experimental use of atomic functions
This commit is contained in:
parent
d2725688e0
commit
02d87fee5b
@ -963,6 +963,14 @@ struct hio_cmgr_t
|
|||||||
#endif
|
#endif
|
||||||
#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)
|
#if defined(HIO_HAVE_BUILTIN_EXPECT)
|
||||||
# define HIO_LIKELY(x) (__builtin_expect(!!(x),1))
|
# define HIO_LIKELY(x) (__builtin_expect(!!(x),1))
|
||||||
# define HIO_UNLIKELY(x) (__builtin_expect(!!(x),0))
|
# define HIO_UNLIKELY(x) (__builtin_expect(!!(x),0))
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
#define CGI_OVER_WRITE_TO_PEER (1 << 3)
|
#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)
|
#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
|
struct cgi_t
|
||||||
{
|
{
|
||||||
HIO_SVC_HTTS_TASK_HEADER;
|
HIO_SVC_HTTS_TASK_HEADER;
|
||||||
@ -75,9 +77,45 @@ struct cgi_peer_xtn_t
|
|||||||
};
|
};
|
||||||
typedef struct cgi_peer_xtn_t 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_client (cgi_t* cgi, int rcdown);
|
||||||
static void unbind_task_from_peer (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)
|
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);
|
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 */
|
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);
|
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, hio_htre_getcontentlen(req) == 0);
|
||||||
HIO_ASSERT (hio, cli->sck == csck);
|
HIO_ASSERT (hio, cli->sck == csck);
|
||||||
|
|
||||||
if (htts->stat.ntask_cgis >= htts->option.task_cgi_max)
|
if (inc_ntask_cgis(htts) <= -1) return -1;
|
||||||
{
|
|
||||||
hio_seterrbfmt (hio, HIO_ENOCAPA, "too many cgi tasks");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cgi = (cgi_t*)hio_svc_htts_task_make(htts, HIO_SIZEOF(*cgi), cgi_on_kill, req, csck);
|
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);
|
HIO_SVC_HTTS_TASK_RCUP((hio_svc_htts_task_t*)cgi);
|
||||||
htts->stat.ntask_cgis++;
|
|
||||||
|
|
||||||
cgi->on_kill = on_kill;
|
cgi->on_kill = on_kill;
|
||||||
cgi->options = options;
|
cgi->options = options;
|
||||||
|
@ -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 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 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)
|
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);
|
qpath_len = hio_htre_getqpathlen(req);
|
||||||
qmth_len = hio_htre_getqmethodlen(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);
|
task = hio_callocmem(hio, task_size + qmth_len + 1 + qpath_len + 1);
|
||||||
if (HIO_UNLIKELY(!task))
|
if (HIO_UNLIKELY(!task))
|
||||||
{
|
{
|
||||||
HIO_DEBUG1 (hio, "HTTS(%p) - failed to allocate task\n", htts);
|
HIO_DEBUG1 (hio, "HTTS(%p) - failed to allocate task\n", htts);
|
||||||
|
dec_ntasks (htts);
|
||||||
return HIO_NULL;
|
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_write == client_on_write);
|
||||||
HIO_ASSERT (hio, csck->on_disconnect == client_on_disconnect);
|
HIO_ASSERT (hio, csck->on_disconnect == client_on_disconnect);
|
||||||
|
|
||||||
htts->stat.ntasks++;
|
|
||||||
HIO_DEBUG2 (hio, "HTTS(%p) - allocated task %p\n", htts, task);
|
HIO_DEBUG2 (hio, "HTTS(%p) - allocated task %p\n", htts, task);
|
||||||
return 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);
|
if (task->task_on_kill) task->task_on_kill (task);
|
||||||
hio_freemem (hio, task);
|
hio_freemem (hio, task);
|
||||||
|
|
||||||
htts->stat.ntasks--;
|
dec_ntasks (htts);
|
||||||
HIO_DEBUG2 (hio, "HTTS(%p) - destroyed task %p\n", htts, task);
|
HIO_DEBUG2 (hio, "HTTS(%p) - destroyed task %p\n", htts, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ static int dev_thr_kill_master (hio_dev_t* dev, int force)
|
|||||||
hio_freemem (hio, ti);
|
hio_freemem (hio, ti);
|
||||||
#else
|
#else
|
||||||
/* schedule a resource destroyer */
|
/* 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user