2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Use atomic stack for async job queue

Previously, the async job queue would use a locked-list (ISC_LIST).
With introduction of atomic stack (that has to be drained at once), we
could use it to remove some contention between the threads and simplify
the async queue.

Fortunately, the reverse order still works for us - instead of append
and tail/prev operation on the list, we are now using prepend and
head/next operation on the atomic stack.
This commit is contained in:
Ondřej Surý
2023-02-20 16:16:07 +01:00
committed by Tony Finch
parent 36e56923ce
commit 6eb1340d1b
4 changed files with 18 additions and 34 deletions

View File

@@ -180,31 +180,17 @@ shutdown_cb(uv_async_t *handle) {
static void
queue_cb(uv_async_t *handle) {
isc_loop_t *loop = uv_handle_get_data(handle);
isc_job_t *job = NULL;
ISC_LIST(isc_job_t) list;
REQUIRE(VALID_LOOP(loop));
ISC_LIST_INIT(list);
ISC_STACK(isc_job_t) drain = ISC_ASTACK_TO_STACK(loop->queue_jobs);
isc_job_t *job = ISC_STACK_POP(drain, link);
LOCK(&loop->queue_lock);
ISC_LIST_MOVE(list, loop->queue_jobs);
UNLOCK(&loop->queue_lock);
/*
* The ISC_LIST_TAIL is counterintuitive here, but uv_idle
* drains its queue backwards, so if there's more than one event to
* be processed then they need to be in reverse order.
*/
job = ISC_LIST_TAIL(list);
while (job != NULL) {
isc_job_t *next = ISC_LIST_PREV(job, link);
ISC_LIST_UNLINK(list, job, link);
isc__job_init(loop, job);
isc__job_run(job);
job = next;
job = ISC_STACK_POP(drain, link);
}
}
@@ -213,6 +199,9 @@ loop_init(isc_loop_t *loop, isc_loopmgr_t *loopmgr, uint32_t tid) {
*loop = (isc_loop_t){
.tid = tid,
.loopmgr = loopmgr,
.queue_jobs = ISC_ASTACK_INITIALIZER,
.setup_jobs = ISC_LIST_INITIALIZER,
.teardown_jobs = ISC_LIST_INITIALIZER,
};
int r = uv_loop_init(&loop->loop);
@@ -239,12 +228,6 @@ loop_init(isc_loop_t *loop, isc_loopmgr_t *loopmgr, uint32_t tid) {
isc_mem_create(&loop->mctx);
isc_mem_setname(loop->mctx, name);
isc_mutex_init(&loop->queue_lock);
ISC_LIST_INIT(loop->queue_jobs);
ISC_LIST_INIT(loop->setup_jobs);
ISC_LIST_INIT(loop->teardown_jobs);
isc_refcount_init(&loop->references, 1);
loop->magic = LOOP_MAGIC;
@@ -278,8 +261,7 @@ loop_close(isc_loop_t *loop) {
int r = uv_loop_close(&loop->loop);
UV_RUNTIME_CHECK(uv_loop_close, r);
isc_mutex_destroy(&loop->queue_lock);
INSIST(ISC_LIST_EMPTY(loop->queue_jobs));
INSIST(ISC_ASTACK_EMPTY(loop->queue_jobs));
loop->magic = 0;