experimental use of atomic functions

This commit is contained in:
hyung-hwan 2023-11-17 18:42:46 +09:00
parent d2725688e0
commit 02d87fee5b
4 changed files with 91 additions and 12 deletions

View File

@ -963,6 +963,14 @@ struct hio_cmgr_t
#endif
#endif
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
#define HCL_ATOMIC_LOAD(dst) __atomic_load_n(dst, __ATOMIC_RELAXED)
#define HCL_ATOMIC_CMP_XCHG(dst,expected,desired) \
__atomic_compare_exchange_n(dst, expected, desired, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
#else
#error NOT SUPPORTED
#endif
#if defined(HIO_HAVE_BUILTIN_EXPECT)
# define HIO_LIKELY(x) (__builtin_expect(!!(x),1))
# define HIO_UNLIKELY(x) (__builtin_expect(!!(x),0))

View File

@ -48,6 +48,8 @@
#define CGI_OVER_WRITE_TO_PEER (1 << 3)
#define CGI_OVER_ALL (CGI_OVER_READ_FROM_CLIENT | CGI_OVER_READ_FROM_PEER | CGI_OVER_WRITE_TO_CLIENT | CGI_OVER_WRITE_TO_PEER)
/* ----------------------------------------------------------------------- */
struct cgi_t
{
HIO_SVC_HTTS_TASK_HEADER;
@ -75,9 +77,45 @@ struct cgi_peer_xtn_t
};
typedef struct cgi_peer_xtn_t cgi_peer_xtn_t;
/* ----------------------------------------------------------------------- */
static void unbind_task_from_client (cgi_t* cgi, int rcdown);
static void unbind_task_from_peer (cgi_t* cgi, int rcdown);
/* ----------------------------------------------------------------------- */
static int inc_ntask_cgis (hio_svc_htts_t* htts)
{
int ok;
do
{
hio_oow_t ntask_cgis;
ntask_cgis = HCL_ATOMIC_LOAD(&htts->stat.ntask_cgis);
if (ntask_cgis >= htts->option.task_cgi_max)
{
hio_seterrbfmt (htts->hio, HIO_ENOCAPA, "too many cgi tasks");
return -1;
}
ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntask_cgis, &ntask_cgis, ntask_cgis + 1);
}
while (!ok);
return 0;
}
static void dec_ntask_cgis (hio_svc_htts_t* htts)
{
int ok;
do
{
hio_oow_t ntask_cgis;
ntask_cgis = HCL_ATOMIC_LOAD(&htts->stat.ntask_cgis);
ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntask_cgis, &ntask_cgis, ntask_cgis - 1);
}
while (!ok);
}
/* ----------------------------------------------------------------------- */
static void cgi_halt_participating_devices (cgi_t* cgi)
{
HIO_DEBUG5 (cgi->htts->hio, "HTTS(%p) - cgi(t=%p,c=%p(%d),p=%p) Halting participating devices\n", cgi->htts, cgi, cgi->task_csck, (cgi->task_csck? cgi->task_csck->hnd: -1), cgi->peer);
@ -192,7 +230,8 @@ static void cgi_on_kill (hio_svc_htts_task_t* task)
}
if (cgi->task_next) HIO_SVC_HTTS_TASKL_UNLINK_TASK (cgi); /* detach from the htts service only if it's attached */
cgi->htts->stat.ntask_cgis--;
dec_ntask_cgis (cgi->htts);
HIO_DEBUG5 (hio, "HTTS(%p) - cgi(t=%p,c=%p[%d],p=%p) - killed the task\n", cgi->htts, cgi, cgi->task_client, (cgi->task_csck? cgi->task_csck->hnd: -1), cgi->peer);
}
@ -939,16 +978,14 @@ int hio_svc_htts_docgi (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t* r
HIO_ASSERT (hio, hio_htre_getcontentlen(req) == 0);
HIO_ASSERT (hio, cli->sck == csck);
if (htts->stat.ntask_cgis >= htts->option.task_cgi_max)
{
hio_seterrbfmt (hio, HIO_ENOCAPA, "too many cgi tasks");
return -1;
}
if (inc_ntask_cgis(htts) <= -1) return -1;
cgi = (cgi_t*)hio_svc_htts_task_make(htts, HIO_SIZEOF(*cgi), cgi_on_kill, req, csck);
if (HIO_UNLIKELY(!cgi)) goto oops;
if (HIO_UNLIKELY(!cgi))
{
dec_ntask_cgis (htts);
goto oops;
}
HIO_SVC_HTTS_TASK_RCUP((hio_svc_htts_task_t*)cgi);
htts->stat.ntask_cgis++;
cgi->on_kill = on_kill;
cgi->options = options;

View File

@ -38,6 +38,38 @@ static int client_on_read (hio_dev_sck_t* sck, const void* buf, hio_iolen_t len,
static int client_on_write (hio_dev_sck_t* sck, hio_iolen_t wrlen, void* wrctx, const hio_skad_t* dstaddr);
static void client_on_disconnect (hio_dev_sck_t* sck);
/* ------------------------------------------------------------------------ */
static int inc_ntasks (hio_svc_htts_t* htts)
{
int ok;
do
{
hio_oow_t ntasks;
ntasks = HCL_ATOMIC_LOAD(&htts->stat.ntasks);
if (ntasks >= htts->option.task_cgi_max)
{
hio_seterrbfmt (htts->hio, HIO_ENOCAPA, "too many tasks");
return -1;
}
ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntasks, &ntasks, ntasks + 1);
}
while (!ok);
return 0;
}
static void dec_ntasks (hio_svc_htts_t* htts)
{
int ok;
do
{
hio_oow_t ntasks;
ntasks = HCL_ATOMIC_LOAD(&htts->stat.ntasks);
ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntasks, &ntasks, ntasks - 1);
}
while (!ok);
}
/* ------------------------------------------------------------------------ */
static int client_htrd_peek_request (hio_htrd_t* htrd, hio_htre_t* req)
{
@ -805,10 +837,13 @@ hio_svc_htts_task_t* hio_svc_htts_task_make (hio_svc_htts_t* htts, hio_oow_t tas
qpath_len = hio_htre_getqpathlen(req);
qmth_len = hio_htre_getqmethodlen(req);
if (inc_ntasks(htts) <= -1) return HIO_NULL;
task = hio_callocmem(hio, task_size + qmth_len + 1 + qpath_len + 1);
if (HIO_UNLIKELY(!task))
{
HIO_DEBUG1 (hio, "HTTS(%p) - failed to allocate task\n", htts);
dec_ntasks (htts);
return HIO_NULL;
}
@ -837,7 +872,6 @@ hio_svc_htts_task_t* hio_svc_htts_task_make (hio_svc_htts_t* htts, hio_oow_t tas
HIO_ASSERT (hio, csck->on_write == client_on_write);
HIO_ASSERT (hio, csck->on_disconnect == client_on_disconnect);
htts->stat.ntasks++;
HIO_DEBUG2 (hio, "HTTS(%p) - allocated task %p\n", htts, task);
return task;
}
@ -852,7 +886,7 @@ void hio_svc_htts_task_kill (hio_svc_htts_task_t* task)
if (task->task_on_kill) task->task_on_kill (task);
hio_freemem (hio, task);
htts->stat.ntasks--;
dec_ntasks (htts);
HIO_DEBUG2 (hio, "HTTS(%p) - destroyed task %p\n", htts, task);
}

View File

@ -323,7 +323,7 @@ static int dev_thr_kill_master (hio_dev_t* dev, int force)
hio_freemem (hio, ti);
#else
/* schedule a resource destroyer */
hio_addcfmb (hio, ti, ready_to_free_thr_info, HIO_NULL);
hio_addcfmb (hio, (hio_cfmb_t*)ti, ready_to_free_thr_info, HIO_NULL);
#endif
}