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

Remove unthreaded support

This commit is contained in:
Witold Kręcicki
2018-06-06 11:39:50 +02:00
parent 8e164f784d
commit 5cdb38c2c7
45 changed files with 596 additions and 1872 deletions

View File

@@ -53,12 +53,6 @@
* is expected to have a separate manager; no "worker threads" are shared by
* the application threads.
*/
#ifdef ISC_PLATFORM_USETHREADS
#define USE_WORKER_THREADS
#else
#define USE_SHARED_MANAGER
#endif /* ISC_PLATFORM_USETHREADS */
#ifdef ISC_TASK_TRACE
#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
task, isc_thread_self(), (m))
@@ -132,21 +126,17 @@ struct isc__taskmgr {
isc_taskmgr_t common;
isc_mem_t * mctx;
isc_mutex_t lock;
#ifdef ISC_PLATFORM_USETHREADS
unsigned int workers;
isc_thread_t * threads;
#endif /* ISC_PLATFORM_USETHREADS */
/* Locked by task manager lock. */
unsigned int default_quantum;
LIST(isc__task_t) tasks;
isc__tasklist_t ready_tasks;
isc__tasklist_t ready_priority_tasks;
isc_taskmgrmode_t mode;
#ifdef ISC_PLATFORM_USETHREADS
isc_condition_t work_available;
isc_condition_t exclusive_granted;
isc_condition_t paused;
#endif /* ISC_PLATFORM_USETHREADS */
unsigned int tasks_running;
unsigned int tasks_ready;
bool pause_requested;
@@ -160,19 +150,12 @@ struct isc__taskmgr {
*/
isc_mutex_t excl_lock;
isc__task_t *excl;
#ifdef USE_SHARED_MANAGER
unsigned int refs;
#endif /* ISC_PLATFORM_USETHREADS */
};
#define DEFAULT_TASKMGR_QUANTUM 10
#define DEFAULT_DEFAULT_QUANTUM 5
#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
#ifdef USE_SHARED_MANAGER
static isc__taskmgr_t *taskmgr = NULL;
#endif /* USE_SHARED_MANAGER */
/*%
* The following are intended for internal use (indicated by "isc__"
* prefix) but are not declared as static, allowing direct access from
@@ -314,7 +297,6 @@ task_finished(isc__task_t *task) {
LOCK(&manager->lock);
UNLINK(manager->tasks, task, link);
#ifdef USE_WORKER_THREADS
if (FINISHED(manager)) {
/*
* All tasks have completed and the
@@ -324,7 +306,6 @@ task_finished(isc__task_t *task) {
*/
BROADCAST(&manager->work_available);
}
#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
DESTROYLOCK(&task->lock);
@@ -461,9 +442,7 @@ task_shutdown(isc__task_t *task) {
static inline void
task_ready(isc__task_t *task) {
isc__taskmgr_t *manager = task->manager;
#ifdef USE_WORKER_THREADS
bool has_privilege = isc__task_privilege((isc_task_t *) task);
#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
REQUIRE(task->state == task_state_ready);
@@ -472,10 +451,8 @@ task_ready(isc__task_t *task) {
LOCK(&manager->lock);
push_readyq(manager, task);
#ifdef USE_WORKER_THREADS
if (manager->mode == isc_taskmgrmode_normal || has_privilege)
SIGNAL(&manager->work_available);
#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
}
@@ -1001,12 +978,6 @@ push_readyq(isc__taskmgr_t *manager, isc__task_t *task) {
static void
dispatch(isc__taskmgr_t *manager) {
isc__task_t *task;
#ifndef USE_WORKER_THREADS
unsigned int total_dispatch_count = 0;
isc__tasklist_t new_ready_tasks;
isc__tasklist_t new_priority_tasks;
unsigned int tasks_ready = 0;
#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
@@ -1060,14 +1031,9 @@ dispatch(isc__taskmgr_t *manager) {
* unlocks. The while expression is always protected by the lock.
*/
#ifndef USE_WORKER_THREADS
ISC_LIST_INIT(new_ready_tasks);
ISC_LIST_INIT(new_priority_tasks);
#endif
LOCK(&manager->lock);
while (!FINISHED(manager)) {
#ifdef USE_WORKER_THREADS
/*
* For reasons similar to those given in the comment in
* isc_task_send() above, it is safe for us to dequeue
@@ -1089,11 +1055,6 @@ dispatch(isc__taskmgr_t *manager) {
ISC_MSGSET_TASK,
ISC_MSG_AWAKE, "awake"));
}
#else /* USE_WORKER_THREADS */
if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||
empty_readyq(manager))
break;
#endif /* USE_WORKER_THREADS */
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
ISC_MSG_WORKING, "working"));
@@ -1144,9 +1105,6 @@ dispatch(isc__taskmgr_t *manager) {
LOCK(&task->lock);
}
dispatch_count++;
#ifndef USE_WORKER_THREADS
total_dispatch_count++;
#endif /* USE_WORKER_THREADS */
}
if (task->references == 0 &&
@@ -1231,7 +1189,6 @@ dispatch(isc__taskmgr_t *manager) {
LOCK(&manager->lock);
manager->tasks_running--;
#ifdef USE_WORKER_THREADS
if (manager->exclusive_requested &&
manager->tasks_running == 1) {
SIGNAL(&manager->exclusive_granted);
@@ -1239,7 +1196,6 @@ dispatch(isc__taskmgr_t *manager) {
manager->tasks_running == 0) {
SIGNAL(&manager->paused);
}
#endif /* USE_WORKER_THREADS */
if (requeue) {
/*
* We know we're awake, so we don't have
@@ -1260,19 +1216,10 @@ dispatch(isc__taskmgr_t *manager) {
* were usually nonempty, the 'optimization'
* might even hurt rather than help.
*/
#ifdef USE_WORKER_THREADS
push_readyq(manager, task);
#else
ENQUEUE(new_ready_tasks, task, ready_link);
if ((task->flags & TASK_F_PRIVILEGED) != 0)
ENQUEUE(new_priority_tasks, task,
ready_priority_link);
tasks_ready++;
#endif
}
}
#ifdef USE_WORKER_THREADS
/*
* If we are in privileged execution mode and there are no
* tasks remaining on the current ready queue, then
@@ -1284,22 +1231,11 @@ dispatch(isc__taskmgr_t *manager) {
if (!empty_readyq(manager))
BROADCAST(&manager->work_available);
}
#endif
}
#ifndef USE_WORKER_THREADS
ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link);
ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks,
ready_priority_link);
manager->tasks_ready += tasks_ready;
if (empty_readyq(manager))
manager->mode = isc_taskmgrmode_normal;
#endif
UNLOCK(&manager->lock);
}
#ifdef USE_WORKER_THREADS
static isc_threadresult_t
#ifdef _WIN32
WINAPI
@@ -1321,18 +1257,15 @@ run(void *uap) {
return ((isc_threadresult_t)0);
}
#endif /* USE_WORKER_THREADS */
static void
manager_free(isc__taskmgr_t *manager) {
isc_mem_t *mctx;
#ifdef USE_WORKER_THREADS
(void)isc_condition_destroy(&manager->exclusive_granted);
(void)isc_condition_destroy(&manager->work_available);
(void)isc_condition_destroy(&manager->paused);
isc_mem_free(manager->mctx, manager->threads);
#endif /* USE_WORKER_THREADS */
DESTROYLOCK(&manager->lock);
DESTROYLOCK(&manager->excl_lock);
manager->common.impmagic = 0;
@@ -1340,10 +1273,6 @@ manager_free(isc__taskmgr_t *manager) {
mctx = manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
#ifdef USE_SHARED_MANAGER
taskmgr = NULL;
#endif /* USE_SHARED_MANAGER */
}
isc_result_t
@@ -1361,21 +1290,6 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
REQUIRE(workers > 0);
REQUIRE(managerp != NULL && *managerp == NULL);
#ifndef USE_WORKER_THREADS
UNUSED(i);
UNUSED(started);
#endif
#ifdef USE_SHARED_MANAGER
if (taskmgr != NULL) {
if (taskmgr->refs == 0)
return (ISC_R_SHUTTINGDOWN);
taskmgr->refs++;
*managerp = (isc_taskmgr_t *)taskmgr;
return (ISC_R_SUCCESS);
}
#endif /* USE_SHARED_MANAGER */
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
@@ -1393,7 +1307,6 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
goto cleanup_mgr;
}
#ifdef USE_WORKER_THREADS
manager->workers = 0;
manager->threads = isc_mem_allocate(mctx,
workers * sizeof(isc_thread_t));
@@ -1425,7 +1338,6 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
result = ISC_R_UNEXPECTED;
goto cleanup_exclusivegranted;
}
#endif /* USE_WORKER_THREADS */
if (default_quantum == 0)
default_quantum = DEFAULT_DEFAULT_QUANTUM;
manager->default_quantum = default_quantum;
@@ -1441,7 +1353,6 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
isc_mem_attach(mctx, &manager->mctx);
#ifdef USE_WORKER_THREADS
LOCK(&manager->lock);
/*
* Start workers.
@@ -1465,17 +1376,11 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
return (ISC_R_NOTHREADS);
}
isc_thread_setconcurrency(workers);
#endif /* USE_WORKER_THREADS */
#ifdef USE_SHARED_MANAGER
manager->refs = 1;
taskmgr = manager;
#endif /* USE_SHARED_MANAGER */
*managerp = (isc_taskmgr_t *)manager;
return (ISC_R_SUCCESS);
#ifdef USE_WORKER_THREADS
cleanup_exclusivegranted:
(void)isc_condition_destroy(&manager->exclusive_granted);
cleanup_workavailable:
@@ -1484,7 +1389,6 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
isc_mem_free(mctx, manager->threads);
cleanup_lock:
DESTROYLOCK(&manager->lock);
#endif
cleanup_mgr:
isc_mem_put(mctx, manager, sizeof(*manager));
return (result);
@@ -1504,18 +1408,6 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
manager = (isc__taskmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
#ifndef USE_WORKER_THREADS
UNUSED(i);
#endif /* USE_WORKER_THREADS */
#ifdef USE_SHARED_MANAGER
manager->refs--;
if (manager->refs > 0) {
*managerp = NULL;
return;
}
#endif
XTHREADTRACE("isc_taskmgr_destroy");
/*
* Only one non-worker thread may ever call this routine.
@@ -1567,7 +1459,6 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
push_readyq(manager, task);
UNLOCK(&task->lock);
}
#ifdef USE_WORKER_THREADS
/*
* Wake up any sleeping workers. This ensures we get work done if
* there's work left to do, and if there are already no tasks left
@@ -1581,28 +1472,6 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
*/
for (i = 0; i < manager->workers; i++)
(void)isc_thread_join(manager->threads[i], NULL);
#else /* USE_WORKER_THREADS */
/*
* Dispatch the shutdown events.
*/
UNLOCK(&manager->lock);
while (isc__taskmgr_ready((isc_taskmgr_t *)manager))
(void)isc__taskmgr_dispatch((isc_taskmgr_t *)manager);
if (!ISC_LIST_EMPTY(manager->tasks)) {
isc__task_t *t;
isc_mem_printallactive(stderr);
for (t = ISC_LIST_HEAD(manager->tasks);
t != NULL;
t = ISC_LIST_NEXT(t, link))
{
fprintf(stderr, "task: %p (%s)\n", t, t->name);
}
}
INSIST(ISC_LIST_EMPTY(manager->tasks));
#ifdef USE_SHARED_MANAGER
taskmgr = NULL;
#endif
#endif /* USE_WORKER_THREADS */
manager_free(manager);
@@ -1628,43 +1497,6 @@ isc__taskmgr_mode(isc_taskmgr_t *manager0) {
return (mode);
}
#ifndef USE_WORKER_THREADS
bool
isc__taskmgr_ready(isc_taskmgr_t *manager0) {
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
bool is_ready;
#ifdef USE_SHARED_MANAGER
if (manager == NULL)
manager = taskmgr;
#endif
if (manager == NULL)
return (false);
LOCK(&manager->lock);
is_ready = !empty_readyq(manager);
UNLOCK(&manager->lock);
return (is_ready);
}
isc_result_t
isc__taskmgr_dispatch(isc_taskmgr_t *manager0) {
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
#ifdef USE_SHARED_MANAGER
if (manager == NULL)
manager = taskmgr;
#endif
if (manager == NULL)
return (ISC_R_NOTFOUND);
dispatch(manager);
return (ISC_R_SUCCESS);
}
#else
void
isc__taskmgr_pause(isc_taskmgr_t *manager0) {
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
@@ -1687,7 +1519,6 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0) {
}
UNLOCK(&manager->lock);
}
#endif /* USE_WORKER_THREADS */
void
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) {
@@ -1723,7 +1554,6 @@ isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) {
isc_result_t
isc__task_beginexclusive(isc_task_t *task0) {
#ifdef USE_WORKER_THREADS
isc__task_t *task = (isc__task_t *)task0;
isc__taskmgr_t *manager = task->manager;
@@ -1743,15 +1573,11 @@ isc__task_beginexclusive(isc_task_t *task0) {
WAIT(&manager->exclusive_granted, &manager->lock);
}
UNLOCK(&manager->lock);
#else
UNUSED(task0);
#endif
return (ISC_R_SUCCESS);
}
void
isc__task_endexclusive(isc_task_t *task0) {
#ifdef USE_WORKER_THREADS
isc__task_t *task = (isc__task_t *)task0;
isc__taskmgr_t *manager = task->manager;
@@ -1761,9 +1587,6 @@ isc__task_endexclusive(isc_task_t *task0) {
manager->exclusive_requested = false;
BROADCAST(&manager->work_available);
UNLOCK(&manager->lock);
#else
UNUSED(task0);
#endif
}
void
@@ -1833,7 +1656,6 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
* on which type is enabled.
*/
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model"));
#ifdef ISC_PLATFORM_USETHREADS
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded"));
TRY0(xmlTextWriterEndElement(writer)); /* type */
@@ -1841,15 +1663,6 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads"));
TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers));
TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */
#else /* ISC_PLATFORM_USETHREADS */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded"));
TRY0(xmlTextWriterEndElement(writer)); /* type */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs));
TRY0(xmlTextWriterEndElement(writer)); /* references */
#endif /* ISC_PLATFORM_USETHREADS */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"));
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
@@ -1942,7 +1755,6 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) {
* Write out the thread-model, and some details about each depending
* on which type is enabled.
*/
#ifdef ISC_PLATFORM_USETHREADS
obj = json_object_new_string("threaded");
CHECKMEM(obj);
json_object_object_add(tasks, "thread-model", obj);
@@ -1950,15 +1762,6 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) {
obj = json_object_new_int(mgr->workers);
CHECKMEM(obj);
json_object_object_add(tasks, "worker-threads", obj);
#else /* ISC_PLATFORM_USETHREADS */
obj = json_object_new_string("non-threaded");
CHECKMEM(obj);
json_object_object_add(tasks, "thread-model", obj);
obj = json_object_new_int(mgr->refs);
CHECKMEM(obj);
json_object_object_add(tasks, "references", obj);
#endif /* ISC_PLATFORM_USETHREADS */
obj = json_object_new_int(mgr->default_quantum);
CHECKMEM(obj);