mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +00:00
Make all tasks to be bound to a thread
Previously, tasks could be created either unbound or bound to a specific thread (worker loop). The unbound tasks would be assigned to a random thread every time isc_task_send() was called. Because there's no logic that would assign the task to the least busy worker, this just creates unpredictability. Instead of random assignment, bind all the previously unbound tasks to worker 0, which is guaranteed to exist.
This commit is contained in:
parent
9da46f3947
commit
1fe391fd40
@ -1392,7 +1392,7 @@ setup_libs(void) {
|
|||||||
|
|
||||||
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &global_task);
|
result = isc_task_create(taskmgr, 0, &global_task, 0);
|
||||||
check_result(result, "isc_task_create");
|
check_result(result, "isc_task_create");
|
||||||
isc_task_setname(global_task, "dig", NULL);
|
isc_task_setname(global_task, "dig", NULL);
|
||||||
|
|
||||||
|
@ -4001,7 +4001,7 @@ main(int argc, char *argv[]) {
|
|||||||
isc_managers_create(mctx, ntasks, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(mctx, ntasks, 0, &netmgr, &taskmgr, NULL);
|
||||||
|
|
||||||
main_task = NULL;
|
main_task = NULL;
|
||||||
result = isc_task_create(taskmgr, 0, &main_task);
|
result = isc_task_create(taskmgr, 0, &main_task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
fatal("failed to create task: %s", isc_result_totext(result));
|
fatal("failed to create task: %s", isc_result_totext(result));
|
||||||
}
|
}
|
||||||
@ -4009,7 +4009,7 @@ main(int argc, char *argv[]) {
|
|||||||
tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
|
tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
|
||||||
for (i = 0; i < (int)ntasks; i++) {
|
for (i = 0; i < (int)ntasks; i++) {
|
||||||
tasks[i] = NULL;
|
tasks[i] = NULL;
|
||||||
result = isc_task_create(taskmgr, 0, &tasks[i]);
|
result = isc_task_create(taskmgr, 0, &tasks[i], i);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
fatal("failed to create task: %s",
|
fatal("failed to create task: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
|
@ -10067,7 +10067,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
|
|||||||
* startup and shutdown of the server, as well as all exclusive
|
* startup and shutdown of the server, as well as all exclusive
|
||||||
* tasks.
|
* tasks.
|
||||||
*/
|
*/
|
||||||
CHECKFATAL(isc_task_create_bound(named_g_taskmgr, 0, &server->task, 0),
|
CHECKFATAL(isc_task_create(named_g_taskmgr, 0, &server->task, 0),
|
||||||
"creating server task");
|
"creating server task");
|
||||||
isc_task_setname(server->task, "server", server);
|
isc_task_setname(server->task, "server", server);
|
||||||
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
|
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
|
||||||
|
@ -911,7 +911,7 @@ setup_system(void) {
|
|||||||
result = dns_dispatchmgr_create(gmctx, netmgr, &dispatchmgr);
|
result = dns_dispatchmgr_create(gmctx, netmgr, &dispatchmgr);
|
||||||
check_result(result, "dns_dispatchmgr_create");
|
check_result(result, "dns_dispatchmgr_create");
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &global_task);
|
result = isc_task_create(taskmgr, 0, &global_task, 0);
|
||||||
check_result(result, "isc_task_create");
|
check_result(result, "isc_task_create");
|
||||||
|
|
||||||
result = dst_lib_init(gmctx, NULL);
|
result = dst_lib_init(gmctx, NULL);
|
||||||
|
@ -1028,7 +1028,7 @@ main(int argc, char **argv) {
|
|||||||
|
|
||||||
isc_mem_create(&rndc_mctx);
|
isc_mem_create(&rndc_mctx);
|
||||||
isc_managers_create(rndc_mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(rndc_mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
||||||
DO("create task", isc_task_create(taskmgr, 0, &rndc_task));
|
DO("create task", isc_task_create(taskmgr, 0, &rndc_task, 0));
|
||||||
isc_log_create(rndc_mctx, &log, &logconfig);
|
isc_log_create(rndc_mctx, &log, &logconfig);
|
||||||
isc_log_setcontext(log);
|
isc_log_setcontext(log);
|
||||||
isc_log_settag(logconfig, progname);
|
isc_log_settag(logconfig, progname);
|
||||||
|
@ -263,7 +263,7 @@ main(int argc, char *argv[]) {
|
|||||||
RUNCHECK(dst_lib_init(mctx, NULL));
|
RUNCHECK(dst_lib_init(mctx, NULL));
|
||||||
|
|
||||||
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
||||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
|
||||||
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
||||||
|
|
||||||
RUNCHECK(dns_dispatch_createudp(
|
RUNCHECK(dns_dispatch_createudp(
|
||||||
|
@ -223,7 +223,7 @@ main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
||||||
|
|
||||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
|
||||||
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
||||||
|
|
||||||
isc_sockaddr_any(&bind_any);
|
isc_sockaddr_any(&bind_any);
|
||||||
|
@ -167,7 +167,7 @@ main(int argc, char **argv) {
|
|||||||
|
|
||||||
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
||||||
|
|
||||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
|
||||||
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
||||||
isc_sockaddr_any(&bind_any);
|
isc_sockaddr_any(&bind_any);
|
||||||
RUNCHECK(dns_dispatch_createudp(dispatchmgr, &bind_any, &dispatchv4));
|
RUNCHECK(dns_dispatch_createudp(dispatchmgr, &bind_any, &dispatchv4));
|
||||||
|
@ -2157,7 +2157,7 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
|
||||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
|
||||||
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
|
||||||
|
|
||||||
set_source_ports(dispatchmgr);
|
set_source_ports(dispatchmgr);
|
||||||
|
@ -2126,7 +2126,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
|
|||||||
/*
|
/*
|
||||||
* Allocate an internal task.
|
* Allocate an internal task.
|
||||||
*/
|
*/
|
||||||
result = isc_task_create(adb->taskmgr, 0, &adb->task);
|
result = isc_task_create(adb->taskmgr, 0, &adb->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto free_lock;
|
goto free_lock;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
|
|||||||
}
|
}
|
||||||
if (taskmgr != NULL) {
|
if (taskmgr != NULL) {
|
||||||
dbtask = NULL;
|
dbtask = NULL;
|
||||||
result = isc_task_create(taskmgr, 1, &dbtask);
|
result = isc_task_create(taskmgr, 1, &dbtask, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_db;
|
goto cleanup_db;
|
||||||
}
|
}
|
||||||
@ -470,7 +470,7 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (taskmgr != NULL && timermgr != NULL) {
|
if (taskmgr != NULL && timermgr != NULL) {
|
||||||
result = isc_task_create(taskmgr, 1, &cleaner->task);
|
result = isc_task_create(taskmgr, 1, &cleaner->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"isc_task_create() failed: %s",
|
"isc_task_create() failed: %s",
|
||||||
|
@ -732,7 +732,7 @@ dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
|
|||||||
new_zones->timermgr = timermgr;
|
new_zones->timermgr = timermgr;
|
||||||
new_zones->taskmgr = taskmgr;
|
new_zones->taskmgr = taskmgr;
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &new_zones->updater);
|
result = isc_task_create(taskmgr, 0, &new_zones->updater, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_ht;
|
goto cleanup_ht;
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
|
|||||||
isc_mutex_init(&client->readylock);
|
isc_mutex_init(&client->readylock);
|
||||||
isc_condition_init(&client->ready);
|
isc_condition_init(&client->ready);
|
||||||
|
|
||||||
result = isc_task_create(client->taskmgr, 0, &client->task);
|
result = isc_task_create(client->taskmgr, 0, &client->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_lock;
|
goto cleanup_lock;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ dns_ntatable_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
|
|||||||
ntatable = isc_mem_get(view->mctx, sizeof(*ntatable));
|
ntatable = isc_mem_get(view->mctx, sizeof(*ntatable));
|
||||||
|
|
||||||
ntatable->task = NULL;
|
ntatable->task = NULL;
|
||||||
result = isc_task_create(taskmgr, 0, &ntatable->task);
|
result = isc_task_create(taskmgr, 0, &ntatable->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_ntatable;
|
goto cleanup_ntatable;
|
||||||
}
|
}
|
||||||
|
@ -10230,7 +10230,7 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
|
|||||||
* Since we have a pool of tasks we bind them to task
|
* Since we have a pool of tasks we bind them to task
|
||||||
* queues to spread the load evenly
|
* queues to spread the load evenly
|
||||||
*/
|
*/
|
||||||
result = isc_task_create_bound(taskmgr, 0, &res->tasks[i], i);
|
result = isc_task_create(taskmgr, 0, &res->tasks[i], i);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_tasks;
|
goto cleanup_tasks;
|
||||||
}
|
}
|
||||||
@ -10260,7 +10260,7 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
|
|||||||
isc_mutex_init(&res->lock);
|
isc_mutex_init(&res->lock);
|
||||||
isc_mutex_init(&res->primelock);
|
isc_mutex_init(&res->primelock);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_primelock;
|
goto cleanup_primelock;
|
||||||
}
|
}
|
||||||
|
@ -1476,7 +1476,7 @@ dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
|
|||||||
goto cleanup_rbt;
|
goto cleanup_rbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &rpzs->updater);
|
result = isc_task_create(taskmgr, 0, &rpzs->updater, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_task;
|
goto cleanup_task;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ create_managers(void) {
|
|||||||
ncpus = isc_os_ncpus();
|
ncpus = isc_os_ncpus();
|
||||||
|
|
||||||
isc_managers_create(dt_mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
|
isc_managers_create(dt_mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
|
||||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
CHECK(isc_task_create(taskmgr, 0, &maintask, 0));
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -603,7 +603,7 @@ nta_test(void **state) {
|
|||||||
result = dns_test_makeview("view", &myview);
|
result = dns_test_makeview("view", &myview);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &myview->task);
|
result = isc_task_create(taskmgr, 0, &myview->task, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
result = dns_view_initsecroots(myview, dt_mctx);
|
result = dns_view_initsecroots(myview, dt_mctx);
|
||||||
|
@ -629,7 +629,7 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
|
|||||||
REQUIRE(!view->frozen);
|
REQUIRE(!view->frozen);
|
||||||
REQUIRE(view->resolver == NULL);
|
REQUIRE(view->resolver == NULL);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &view->task);
|
result = isc_task_create(taskmgr, 0, &view->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
@ -18742,7 +18742,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||||||
isc_rwlock_init(&zmgr->urlock, 0, 0);
|
isc_rwlock_init(&zmgr->urlock, 0, 0);
|
||||||
|
|
||||||
/* Create a single task for queueing of SOA queries. */
|
/* Create a single task for queueing of SOA queries. */
|
||||||
result = isc_task_create(taskmgr, 1, &zmgr->task);
|
result = isc_task_create(taskmgr, 1, &zmgr->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto free_urlock;
|
goto free_urlock;
|
||||||
}
|
}
|
||||||
@ -18782,8 +18782,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||||||
zmgr->mctx, zmgr->workers * sizeof(zmgr->zonetasks[0]));
|
zmgr->mctx, zmgr->workers * sizeof(zmgr->zonetasks[0]));
|
||||||
memset(zmgr->zonetasks, 0, zmgr->workers * sizeof(zmgr->zonetasks[0]));
|
memset(zmgr->zonetasks, 0, zmgr->workers * sizeof(zmgr->zonetasks[0]));
|
||||||
for (size_t i = 0; i < zmgr->workers; i++) {
|
for (size_t i = 0; i < zmgr->workers; i++) {
|
||||||
result = isc_task_create_bound(zmgr->taskmgr, 2,
|
result = isc_task_create(zmgr->taskmgr, 2, &zmgr->zonetasks[i],
|
||||||
&zmgr->zonetasks[i], i);
|
i);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto free_zonetasks;
|
goto free_zonetasks;
|
||||||
}
|
}
|
||||||
@ -18794,8 +18794,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||||||
zmgr->mctx, zmgr->workers * sizeof(zmgr->loadtasks[0]));
|
zmgr->mctx, zmgr->workers * sizeof(zmgr->loadtasks[0]));
|
||||||
memset(zmgr->loadtasks, 0, zmgr->workers * sizeof(zmgr->loadtasks[0]));
|
memset(zmgr->loadtasks, 0, zmgr->workers * sizeof(zmgr->loadtasks[0]));
|
||||||
for (size_t i = 0; i < zmgr->workers; i++) {
|
for (size_t i = 0; i < zmgr->workers; i++) {
|
||||||
result = isc_task_create_bound(zmgr->taskmgr, UINT_MAX,
|
result = isc_task_create(zmgr->taskmgr, UINT_MAX,
|
||||||
&zmgr->loadtasks[i], i);
|
&zmgr->loadtasks[i], i);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto free_loadtasks;
|
goto free_loadtasks;
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,7 @@
|
|||||||
* \section purge Purging and Unsending
|
* \section purge Purging and Unsending
|
||||||
*
|
*
|
||||||
* Events which have been queued for a task but not delivered may be removed
|
* Events which have been queued for a task but not delivered may be removed
|
||||||
* from the task's event queue by purging or unsending.
|
* from the task's event queue by purging the event.
|
||||||
*
|
|
||||||
* With both types, the caller specifies a matching pattern that selects
|
|
||||||
* events based upon their sender, type, and tag.
|
|
||||||
*
|
*
|
||||||
* Purging calls isc_event_free() on the matching events.
|
* Purging calls isc_event_free() on the matching events.
|
||||||
*
|
*
|
||||||
@ -92,16 +89,14 @@ ISC_LANG_BEGINDECLS
|
|||||||
*** Types
|
*** Types
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#define isc_task_create(m, q, t) \
|
#define isc_task_create(m, q, t, i) \
|
||||||
isc__task_create_bound(m, q, t, -1 ISC__TASKFILELINE)
|
isc__task_create(m, q, t, i ISC__TASKFILELINE)
|
||||||
#define isc_task_create_bound(m, q, t, i) \
|
|
||||||
isc__task_create_bound(m, q, t, i ISC__TASKFILELINE)
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
isc__task_create(isc_taskmgr_t *manager, unsigned int quantum,
|
||||||
isc_task_t **taskp, int tid ISC__TASKFLARG);
|
isc_task_t **taskp, int tid ISC__TASKFLARG);
|
||||||
/*%<
|
/*%<
|
||||||
* Create a task, optionally bound to a particular tid.
|
* Create a task, bound to a particular thread id.
|
||||||
*
|
*
|
||||||
* Notes:
|
* Notes:
|
||||||
*
|
*
|
||||||
@ -127,7 +122,6 @@ isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
|||||||
* Returns:
|
* Returns:
|
||||||
*
|
*
|
||||||
*\li #ISC_R_SUCCESS
|
*\li #ISC_R_SUCCESS
|
||||||
*\li #ISC_R_NOMEMORY
|
|
||||||
*\li #ISC_R_UNEXPECTED
|
*\li #ISC_R_UNEXPECTED
|
||||||
*\li #ISC_R_SHUTTINGDOWN
|
*\li #ISC_R_SHUTTINGDOWN
|
||||||
*/
|
*/
|
||||||
@ -196,7 +190,7 @@ isc_task_detach(isc_task_t **taskp);
|
|||||||
void
|
void
|
||||||
isc_task_send(isc_task_t *task, isc_event_t **eventp);
|
isc_task_send(isc_task_t *task, isc_event_t **eventp);
|
||||||
/*%<
|
/*%<
|
||||||
* Send '*event' to 'task', if task is idle try starting it on cpu 'c'
|
* Send '*event' to 'task'.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
@ -212,7 +206,7 @@ void
|
|||||||
isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
|
isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
|
||||||
/*%<
|
/*%<
|
||||||
* Send '*event' to '*taskp' and then detach '*taskp' from its
|
* Send '*event' to '*taskp' and then detach '*taskp' from its
|
||||||
* task. If task is idle try starting it on cpu 'c'
|
* task.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
@ -239,15 +233,12 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
|
|||||||
/*%<
|
/*%<
|
||||||
* Purge 'event' from a task's event queue.
|
* Purge 'event' from a task's event queue.
|
||||||
*
|
*
|
||||||
* XXXRTH: WARNING: This method may be removed before beta.
|
|
||||||
*
|
|
||||||
* Notes:
|
* Notes:
|
||||||
*
|
*
|
||||||
*\li If 'event' is on the task's event queue, it will be purged,
|
*\li If 'event' is on the task's event queue, it will be purged. 'event'
|
||||||
* unless it is marked as unpurgeable. 'event' does not have to be
|
* does not have to be on the task's event queue; in fact, it can even be
|
||||||
* on the task's event queue; in fact, it can even be an invalid
|
* an invalid pointer. Purging only occurs if the event is actually on the
|
||||||
* pointer. Purging only occurs if the event is actually on the task's
|
* task's event queue.
|
||||||
* event queue.
|
|
||||||
*
|
*
|
||||||
* \li Purging never changes the state of the task.
|
* \li Purging never changes the state of the task.
|
||||||
*
|
*
|
||||||
@ -262,8 +253,7 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
|
|||||||
* Returns:
|
* Returns:
|
||||||
*
|
*
|
||||||
*\li #true The event was purged.
|
*\li #true The event was purged.
|
||||||
*\li #false The event was not in the event queue,
|
*\li #false The event was not in the event queue.
|
||||||
* or was marked unpurgeable.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -295,8 +285,8 @@ isc_task_getname(isc_task_t *task);
|
|||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
*\li A non-NULL pointer to a null-terminated string.
|
*\li A non-NULL pointer to a null-terminated string.
|
||||||
* If the task has not been named, the string is
|
* If the task has not been named, the string is
|
||||||
* empty.
|
* empty.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
* locality on CPU.
|
* locality on CPU.
|
||||||
*
|
*
|
||||||
* To make load even some tasks (from task pools) are bound to specific
|
* To make load even some tasks (from task pools) are bound to specific
|
||||||
* queues using isc_task_create_bound. This way load balancing between
|
* queues using isc_task_create. This way load balancing between
|
||||||
* CPUs/queues happens on the higher layer.
|
* CPUs/queues happens on the higher layer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -118,7 +118,6 @@ struct isc_task {
|
|||||||
isc_time_t tnow;
|
isc_time_t tnow;
|
||||||
char name[16];
|
char name[16];
|
||||||
void *tag;
|
void *tag;
|
||||||
bool bound;
|
|
||||||
/* Protected by atomics */
|
/* Protected by atomics */
|
||||||
atomic_bool shuttingdown;
|
atomic_bool shuttingdown;
|
||||||
/* Locked by task manager lock. */
|
/* Locked by task manager lock. */
|
||||||
@ -198,18 +197,22 @@ task_destroy(isc_task_t *task) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
isc__task_create(isc_taskmgr_t *manager, unsigned int quantum,
|
||||||
isc_task_t **taskp, int tid ISC__TASKFLARG) {
|
isc_task_t **taskp, int tid ISC__TASKFLARG) {
|
||||||
isc_task_t *task = NULL;
|
isc_task_t *task = NULL;
|
||||||
bool exiting;
|
bool exiting;
|
||||||
|
|
||||||
REQUIRE(VALID_MANAGER(manager));
|
REQUIRE(VALID_MANAGER(manager));
|
||||||
REQUIRE(taskp != NULL && *taskp == NULL);
|
REQUIRE(taskp != NULL && *taskp == NULL);
|
||||||
|
REQUIRE(tid >= 0 && tid < (int)manager->nworkers);
|
||||||
|
|
||||||
XTRACE("isc_task_create");
|
XTRACE("isc_task_create");
|
||||||
|
|
||||||
task = isc_mem_get(manager->mctx, sizeof(*task));
|
task = isc_mem_get(manager->mctx, sizeof(*task));
|
||||||
*task = (isc_task_t){ 0 };
|
*task = (isc_task_t){
|
||||||
|
.state = task_state_idle,
|
||||||
|
.tid = tid,
|
||||||
|
};
|
||||||
|
|
||||||
#if TASKMGR_TRACE
|
#if TASKMGR_TRACE
|
||||||
strlcpy(task->func, func, sizeof(task->func));
|
strlcpy(task->func, func, sizeof(task->func));
|
||||||
@ -221,34 +224,14 @@ isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
|||||||
|
|
||||||
isc_taskmgr_attach(manager, &task->manager);
|
isc_taskmgr_attach(manager, &task->manager);
|
||||||
|
|
||||||
if (tid == -1) {
|
|
||||||
/*
|
|
||||||
* Task is not pinned to a queue, it's tid will be
|
|
||||||
* randomly chosen when first task will be sent to it.
|
|
||||||
*/
|
|
||||||
task->bound = false;
|
|
||||||
task->tid = -1;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Task is pinned to a queue, it'll always be run
|
|
||||||
* by a specific thread.
|
|
||||||
*/
|
|
||||||
task->bound = true;
|
|
||||||
task->tid = tid % task->manager->nworkers;
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_mutex_init(&task->lock);
|
isc_mutex_init(&task->lock);
|
||||||
task->state = task_state_idle;
|
|
||||||
|
|
||||||
isc_refcount_init(&task->references, 1);
|
isc_refcount_init(&task->references, 1);
|
||||||
INIT_LIST(task->events);
|
INIT_LIST(task->events);
|
||||||
task->nevents = 0;
|
|
||||||
task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
|
task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
|
||||||
atomic_init(&task->shuttingdown, false);
|
atomic_init(&task->shuttingdown, false);
|
||||||
task->now = 0;
|
|
||||||
isc_time_settoepoch(&task->tnow);
|
isc_time_settoepoch(&task->tnow);
|
||||||
memset(task->name, 0, sizeof(task->name));
|
memset(task->name, 0, sizeof(task->name));
|
||||||
task->tag = NULL;
|
|
||||||
INIT_LINK(task, link);
|
INIT_LINK(task, link);
|
||||||
task->magic = TASK_MAGIC;
|
task->magic = TASK_MAGIC;
|
||||||
|
|
||||||
@ -304,9 +287,6 @@ task_ready(isc_task_t *task) {
|
|||||||
|
|
||||||
isc_task_attach(task, &(isc_task_t *){ NULL });
|
isc_task_attach(task, &(isc_task_t *){ NULL });
|
||||||
LOCK(&task->lock);
|
LOCK(&task->lock);
|
||||||
if (task->tid < 0) {
|
|
||||||
task->tid = (int)isc_random_uniform(manager->nworkers);
|
|
||||||
}
|
|
||||||
isc_nm_task_enqueue(manager->netmgr, task, task->tid);
|
isc_nm_task_enqueue(manager->netmgr, task, task->tid);
|
||||||
UNLOCK(&task->lock);
|
UNLOCK(&task->lock);
|
||||||
}
|
}
|
||||||
@ -358,10 +338,6 @@ task_send(isc_task_t *task, isc_event_t **eventp) {
|
|||||||
|
|
||||||
if (task->state == task_state_idle) {
|
if (task->state == task_state_idle) {
|
||||||
was_idle = true;
|
was_idle = true;
|
||||||
if (!task->bound) {
|
|
||||||
task->tid = (int)isc_random_uniform(
|
|
||||||
task->manager->nworkers);
|
|
||||||
}
|
|
||||||
INSIST(EMPTY(task->events));
|
INSIST(EMPTY(task->events));
|
||||||
task->state = task_state_ready;
|
task->state = task_state_ready;
|
||||||
}
|
}
|
||||||
@ -438,11 +414,10 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event) {
|
|||||||
REQUIRE(VALID_TASK(task));
|
REQUIRE(VALID_TASK(task));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If 'event' is on the task's event queue, it will be purged,
|
* If 'event' is on the task's event queue, it will be purged, 'event'
|
||||||
* unless it is marked as unpurgeable. 'event' does not have to be
|
* does not have to be on the task's event queue; in fact, it can even
|
||||||
* on the task's event queue; in fact, it can even be an invalid
|
* be an invalid pointer. Purging only occurs if the event is actually
|
||||||
* pointer. Purging only occurs if the event is actually on the task's
|
* on the task's event queue.
|
||||||
* event queue.
|
|
||||||
*
|
*
|
||||||
* Purging never changes the state of the task.
|
* Purging never changes the state of the task.
|
||||||
*/
|
*/
|
||||||
|
@ -79,7 +79,7 @@ create_managers(unsigned int workers) {
|
|||||||
isc_managers_create(test_mctx, workers, 0, &netmgr, &taskmgr,
|
isc_managers_create(test_mctx, workers, 0, &netmgr, &taskmgr,
|
||||||
&timermgr);
|
&timermgr);
|
||||||
|
|
||||||
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
|
CHECK(isc_task_create(taskmgr, 0, &maintask, 0));
|
||||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
@ -131,7 +131,7 @@ create_task(void **state) {
|
|||||||
|
|
||||||
UNUSED(state);
|
UNUSED(state);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_task_detach(&task);
|
isc_task_detach(&task);
|
||||||
@ -153,7 +153,7 @@ all_events(void **state) {
|
|||||||
atomic_init(&a, 0);
|
atomic_init(&a, 0);
|
||||||
atomic_init(&b, 0);
|
atomic_init(&b, 0);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
/* First event */
|
/* First event */
|
||||||
@ -240,13 +240,13 @@ basic(void **state) {
|
|||||||
|
|
||||||
UNUSED(state);
|
UNUSED(state);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task1);
|
result = isc_task_create(taskmgr, 0, &task1, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
result = isc_task_create(taskmgr, 0, &task2);
|
result = isc_task_create(taskmgr, 0, &task2, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
result = isc_task_create(taskmgr, 0, &task3);
|
result = isc_task_create(taskmgr, 0, &task3, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
result = isc_task_create(taskmgr, 0, &task4);
|
result = isc_task_create(taskmgr, 0, &task4, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_interval_set(&interval, 1, 0);
|
isc_interval_set(&interval, 1, 0);
|
||||||
@ -365,13 +365,12 @@ task_exclusive(void **state) {
|
|||||||
|
|
||||||
if (i == 6) {
|
if (i == 6) {
|
||||||
/* task chosen from the middle of the range */
|
/* task chosen from the middle of the range */
|
||||||
result = isc_task_create_bound(taskmgr, 0, &tasks[i],
|
result = isc_task_create(taskmgr, 0, &tasks[i], 0);
|
||||||
0);
|
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_taskmgr_setexcltask(taskmgr, tasks[6]);
|
isc_taskmgr_setexcltask(taskmgr, tasks[6]);
|
||||||
} else {
|
} else {
|
||||||
result = isc_task_create(taskmgr, 0, &tasks[i]);
|
result = isc_task_create(taskmgr, 0, &tasks[i], 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +414,7 @@ maxtask_cb(isc_task_t *task, isc_event_t *event) {
|
|||||||
/*
|
/*
|
||||||
* Create a new task and forward the message.
|
* Create a new task and forward the message.
|
||||||
*/
|
*/
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_task_send(task, &event);
|
isc_task_send(task, &event);
|
||||||
@ -513,7 +512,7 @@ try_purgeevent(void) {
|
|||||||
atomic_init(&done, false);
|
atomic_init(&done, false);
|
||||||
eventcnt = 0;
|
eventcnt = 0;
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,7 +114,7 @@ setup_test(isc_timertype_t timertype, isc_interval_t *interval,
|
|||||||
|
|
||||||
LOCK(&mx);
|
LOCK(&mx);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_mutex_lock(&lasttime_mx);
|
isc_mutex_lock(&lasttime_mx);
|
||||||
@ -493,10 +493,10 @@ purge(void **state) {
|
|||||||
seconds = 1;
|
seconds = 1;
|
||||||
nanoseconds = 0;
|
nanoseconds = 0;
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task1);
|
result = isc_task_create(taskmgr, 0, &task1, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
result = isc_task_create(taskmgr, 0, &task2);
|
result = isc_task_create(taskmgr, 0, &task2, 0);
|
||||||
assert_int_equal(result, ISC_R_SUCCESS);
|
assert_int_equal(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_interval_set(&interval, seconds, 0);
|
isc_interval_set(&interval, seconds, 0);
|
||||||
|
@ -2436,8 +2436,8 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
|
|||||||
|
|
||||||
dns_aclenv_attach(aclenv, &manager->aclenv);
|
dns_aclenv_attach(aclenv, &manager->aclenv);
|
||||||
|
|
||||||
result = isc_task_create_bound(manager->taskmgr, 20, &manager->task,
|
result = isc_task_create(manager->taskmgr, 20, &manager->task,
|
||||||
manager->tid);
|
manager->tid);
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
isc_task_setname(manager->task, "clientmgr", NULL);
|
isc_task_setname(manager->task, "clientmgr", NULL);
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||||||
|
|
||||||
isc_mutex_init(&mgr->lock);
|
isc_mutex_init(&mgr->lock);
|
||||||
|
|
||||||
result = isc_task_create_bound(taskmgr, 0, &mgr->task, 0);
|
result = isc_task_create(taskmgr, 0, &mgr->task, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_lock;
|
goto cleanup_lock;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ create_managers(void) {
|
|||||||
int ncpus = isc_os_ncpus();
|
int ncpus = isc_os_ncpus();
|
||||||
|
|
||||||
isc_managers_create(mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
|
isc_managers_create(mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
|
||||||
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
|
CHECK(isc_task_create(taskmgr, 0, &maintask, 0));
|
||||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||||
|
|
||||||
CHECK(ns_server_create(mctx, matchview, &sctx));
|
CHECK(ns_server_create(mctx, matchview, &sctx));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user