Commit 36ee4303 authored by Evan Hunt's avatar Evan Hunt

optionally associate a netmgr with a task manager when creating

When a task manager is created, we can now specify an `isc_nm`
object to associate with it; thereafter when the task manager is
placed into exclusive mode, the network manager will be paused.
parent f188d002
......@@ -1379,7 +1379,7 @@ setup_libs(void) {
isc_log_setdebuglevel(lctx, 0);
result = isc_taskmgr_create(mctx, 1, 0, &taskmgr);
result = isc_taskmgr_create(mctx, 1, 0, NULL, &taskmgr);
check_result(result, "isc_taskmgr_create");
result = isc_task_create(taskmgr, 0, &global_task);
......
......@@ -3797,7 +3797,7 @@ main(int argc, char *argv[]) {
print_time(outfp);
print_version(outfp);
result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr);
result = isc_taskmgr_create(mctx, ntasks, 0, NULL, &taskmgr);
if (result != ISC_R_SUCCESS)
fatal("failed to create task manager: %s",
isc_result_totext(result));
......
......@@ -897,7 +897,7 @@ create_managers(void) {
"using %u UDP listener%s per interface",
named_g_udpdisp, named_g_udpdisp == 1 ? "" : "s");
result = isc_taskmgr_create(named_g_mctx, named_g_cpus, 0,
result = isc_taskmgr_create(named_g_mctx, named_g_cpus, 0, NULL,
&named_g_taskmgr);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
......
......@@ -906,7 +906,7 @@ setup_system(void) {
result = isc_timermgr_create(gmctx, &timermgr);
check_result(result, "dns_timermgr_create");
result = isc_taskmgr_create(gmctx, 1, 0, &taskmgr);
result = isc_taskmgr_create(gmctx, 1, 0, NULL, &taskmgr);
check_result(result, "isc_taskmgr_create");
result = isc_task_create(taskmgr, 0, &global_task);
......
......@@ -936,11 +936,14 @@ main(int argc, char **argv) {
serial = isc_random32();
isc_mem_create(&rndc_mctx);
DO("create socket manager", isc_socketmgr_create(rndc_mctx, &socketmgr));
DO("create task manager", isc_taskmgr_create(rndc_mctx, 1, 0, &taskmgr));
DO("create socket manager", isc_socketmgr_create(rndc_mctx,
&socketmgr));
DO("create task manager", isc_taskmgr_create(rndc_mctx, 1, 0,
NULL, &taskmgr));
DO("create task", isc_task_create(taskmgr, 0, &task));
DO("create logging context", isc_log_create(rndc_mctx, &log, &logconfig));
DO("create logging context", isc_log_create(rndc_mctx, &log,
&logconfig));
isc_log_setcontext(log);
DO("setting log tag", isc_log_settag(logconfig, progname));
logdest.file.stream = stderr;
......
......@@ -144,7 +144,7 @@ create_managers(void) {
isc_result_t result;
taskmgr = NULL;
result = isc_taskmgr_create(mctx, 5, 0, &taskmgr);
result = isc_taskmgr_create(mctx, 5, 0, NULL, &taskmgr);
check_result(result, "isc_taskmgr_create");
timermgr = NULL;
......
......@@ -112,7 +112,7 @@ main(int argc, char *argv[]) {
}
taskmgr = NULL;
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr)
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, NULL, &taskmgr)
== ISC_R_SUCCESS);
task = NULL;
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task)
......
......@@ -226,7 +226,7 @@ main(int argc, char *argv[]) {
}
taskmgr = NULL;
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, NULL, &taskmgr) ==
ISC_R_SUCCESS);
task = NULL;
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task) ==
......
......@@ -470,7 +470,7 @@ main(int argc, char *argv[]) {
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, NULL, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
......
......@@ -102,7 +102,7 @@ main(int argc, char *argv[]) {
isc_interval_set(&linterval, 1, 0);
isc_mem_create(&mctx);
RUNTIME_CHECK(isc_taskmgr_create(mctx, 3, 0, &taskmgr) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, 3, 0, NULL, &taskmgr) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) ==
ISC_R_SUCCESS);
......
......@@ -181,7 +181,7 @@ main(int argc, char *argv[]) {
isc_mem_create(&mctx);
mctx2 = NULL;
isc_mem_create(&mctx2);
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &task_manager) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, NULL, &task_manager) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx, &timer_manager) ==
ISC_R_SUCCESS);
......
......@@ -226,7 +226,7 @@ main(int argc, char *argv[]) {
dst_result_register();
taskmgr = NULL;
RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, NULL, &taskmgr) ==
ISC_R_SUCCESS);
task1 = NULL;
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task1) == ISC_R_SUCCESS);
......
......@@ -292,7 +292,7 @@ main(int argc, char *argv[]) {
* The task manager is independent (other than memory context)
*/
manager = NULL;
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, NULL, &manager) ==
ISC_R_SUCCESS);
/*
......
......@@ -79,7 +79,7 @@ main(int argc, char *argv[]) {
isc_mem_create(&mctx);
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, NULL, &manager) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS);
......
......@@ -108,7 +108,7 @@ main(int argc, char *argv[]) {
printf("%u workers\n", workers);
isc_mem_create(&mctx1);
RUNTIME_CHECK(isc_taskmgr_create(mctx1, workers, 0, &manager) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx1, workers, 0, NULL, &manager) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx1, &timgr) == ISC_R_SUCCESS);
......
......@@ -280,7 +280,7 @@ main(int argc, char **argv) {
RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS);
isc_mem_create(&mctx);
RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) ==
RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, NULL, &taskmgr) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
......
......@@ -277,7 +277,7 @@ main(int argc, char *argv[]) {
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, NULL, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
......
......@@ -236,7 +236,7 @@ main(int argc, char *argv[]) {
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, NULL, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
......
......@@ -175,7 +175,7 @@ main(int argc, char **argv) {
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, NULL, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
......
......@@ -2047,7 +2047,7 @@ main(int argc, char *argv[]) {
fatal("can't choose between IPv4 and IPv6");
taskmgr = NULL;
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
RUNCHECK(isc_taskmgr_create(mctx, 1, 0, NULL, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
......
......@@ -116,7 +116,7 @@ create_managers(void) {
isc_result_t result;
ncpus = isc_os_ncpus();
CHECK(isc_taskmgr_create(dt_mctx, ncpus, 0, &taskmgr));
CHECK(isc_taskmgr_create(dt_mctx, ncpus, 0, NULL, &taskmgr));
CHECK(isc_timermgr_create(dt_mctx, &timermgr));
CHECK(isc_socketmgr_create(dt_mctx, &socketmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
......
......@@ -78,6 +78,7 @@
#include <isc/eventclass.h>
#include <isc/lang.h>
#include <isc/stdtime.h>
#include <isc/netmgr.h>
#include <isc/types.h>
#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0)
......@@ -544,6 +545,8 @@ isc_task_beginexclusive(isc_task_t *task);
* task. Waits for any other concurrently executing tasks to finish their
* current event, and prevents any new events from executing in any of the
* tasks sharing a task manager with 'task'.
* It also pauses processing of network events in netmgr if it was provided
* when taskmgr was created.
*
* The exclusive access must be relinquished by calling
* isc_task_endexclusive() before returning from the current event handler.
......@@ -633,7 +636,8 @@ isc_taskmgr_createinctx(isc_mem_t *mctx,
isc_taskmgr_t **managerp);
isc_result_t
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
unsigned int default_quantum, isc_taskmgr_t **managerp);
unsigned int default_quantum,
isc_nm_t *nm, isc_taskmgr_t **managerp);
/*%<
* Create a new task manager. isc_taskmgr_createinctx() also associates
* the new manager with the specified application context.
......@@ -650,6 +654,9 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
* quantum value when tasks are created. If zero, then an implementation
* defined default quantum will be used.
*
*\li If 'nm' is set then netmgr is paused when an exclusive task mode
* is requested.
*
* Requires:
*
*\li 'mctx' is a valid memory context.
......
......@@ -155,6 +155,7 @@ struct isc__taskmgr {
atomic_uint_fast32_t curq;
atomic_uint_fast32_t tasks_count;
isc__taskqueue_t *queues;
isc_nm_t *nm;
/* Locked by task manager lock. */
unsigned int default_quantum;
......@@ -405,7 +406,8 @@ task_ready(isc__task_t *task) {
LOCK(&manager->queues[task->threadid].lock);
push_readyq(manager, task, task->threadid);
if (atomic_load(&manager->mode) == isc_taskmgrmode_normal ||
has_privilege) {
has_privilege)
{
SIGNAL(&manager->queues[task->threadid].work_available);
}
UNLOCK(&manager->queues[task->threadid].lock);
......@@ -1323,7 +1325,8 @@ manager_free(isc__taskmgr_t *manager) {
isc_result_t
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
unsigned int default_quantum, isc_taskmgr_t **managerp)
unsigned int default_quantum,
isc_nm_t *nm, isc_taskmgr_t **managerp)
{
unsigned int i;
isc__taskmgr_t *manager;
......@@ -1354,6 +1357,11 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
default_quantum = DEFAULT_DEFAULT_QUANTUM;
}
manager->default_quantum = default_quantum;
if (nm != NULL) {
isc_nm_attach(nm, &manager->nm);
}
INIT_LIST(manager->tasks);
atomic_store(&manager->tasks_count, 0);
manager->queues = isc_mem_get(mctx,
......@@ -1484,6 +1492,13 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
isc_thread_join(manager->queues[i].thread, NULL);
}
/*
* Detach from the network manager if it was set.
*/
if (manager->nm != NULL) {
isc_nm_detach(&manager->nm);
}
manager_free(manager);
*managerp = NULL;
......@@ -1600,6 +1615,9 @@ isc_task_beginexclusive(isc_task_t *task0) {
WAIT(&manager->halt_cond, &manager->halt_lock);
}
UNLOCK(&manager->halt_lock);
if (manager->nm != NULL) {
isc_nm_pause(manager->nm);
}
return (ISC_R_SUCCESS);
}
......@@ -1610,9 +1628,11 @@ isc_task_endexclusive(isc_task_t *task0) {
REQUIRE(VALID_TASK(task));
REQUIRE(task->state == task_state_running);
manager = task->manager;
if (manager->nm != NULL) {
isc_nm_resume(manager->nm);
}
LOCK(&manager->halt_lock);
REQUIRE(atomic_load_relaxed(&manager->exclusive_req) == true);
atomic_store_relaxed(&manager->exclusive_req, false);
......@@ -1888,8 +1908,8 @@ isc_taskmgr_createinctx(isc_mem_t *mctx,
{
isc_result_t result;
result = isc_taskmgr_create(mctx, workers, default_quantum,
managerp);
result = isc_taskmgr_create(mctx, workers, default_quantum, NULL,
managerp);
return (result);
}
......@@ -88,7 +88,7 @@ create_managers(unsigned int workers) {
workers = atoi(p);
}
CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr));
CHECK(isc_taskmgr_create(mctx, workers, 0, NULL, &taskmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
isc_taskmgr_setexcltask(taskmgr, maintask);
......
......@@ -734,7 +734,7 @@ manytasks(void **state) {
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
isc_mem_create(&mctx);
result = isc_taskmgr_create(mctx, 4, 0, &taskmgr);
result = isc_taskmgr_create(mctx, 4, 0, NULL, &taskmgr);
assert_int_equal(result, ISC_R_SUCCESS);
atomic_init(&done, false);
......
......@@ -611,6 +611,7 @@ isc_task_exiting
isc_task_getcurrenttime
isc_task_getcurrenttimex
isc_task_onshutdown
isc_task_pause
isc_task_privilege
isc_task_purge
isc_task_purgeevent
......@@ -622,6 +623,7 @@ isc_task_sendtoanddetach
isc_task_setname
isc_task_setprivilege
isc_task_shutdown
isc_task_unpause
isc_task_unsend
isc_taskmgr_create
isc_taskmgr_createinctx
......
......@@ -177,7 +177,7 @@ create_managers(void) {
isc_event_t *event = NULL;
ncpus = isc_os_ncpus();
CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
CHECK(isc_taskmgr_create(mctx, ncpus, 0, NULL, &taskmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
isc_taskmgr_setexcltask(taskmgr, maintask);
CHECK(isc_task_onshutdown(maintask, shutdown_managers, NULL));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment