fatal("failed to create mctx");
CHECK(isc_appctx_create(mctx, &actx));
- CHECK(isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr));
+ CHECK(isc_taskmgr_createinctx(mctx, actx, 1, &taskmgr));
CHECK(isc_socketmgr_createinctx(mctx, actx, &socketmgr));
CHECK(isc_timermgr_createinctx(mctx, actx, &timermgr));
isc_log_setdebuglevel(lctx, 0);
- result = isc_taskmgr_create(mctx, 1, 0, &taskmgr);
+ result = isc_taskmgr_create(mctx, 1, &taskmgr);
check_result(result, "isc_taskmgr_create");
result = isc_task_create(taskmgr, 0, &global_task);
print_time(outfp);
print_version(outfp);
- result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr);
+ result = isc_taskmgr_create(mctx, ntasks, &taskmgr);
if (result != ISC_R_SUCCESS)
fatal("failed to create task manager: %s",
isc_result_totext(result));
"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,
&named_g_taskmgr);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
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, &taskmgr);
check_result(result, "isc_taskmgr_create");
result = isc_task_create(taskmgr, 0, &global_task);
DO("create memory context", isc_mem_create(0, 0, &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 task manager", isc_taskmgr_create(rndc_mctx, 1, &taskmgr));
DO("create task", isc_task_create(taskmgr, 0, &task));
DO("create logging context", isc_log_create(rndc_mctx, &log, &logconfig));
isc_result_t result;
taskmgr = NULL;
- result = isc_taskmgr_create(mctx, 5, 0, &taskmgr);
+ result = isc_taskmgr_create(mctx, 5, &taskmgr);
check_result(result, "isc_taskmgr_create");
timermgr = NULL;
}
taskmgr = NULL;
- RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr)
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, &taskmgr)
== ISC_R_SUCCESS);
task = NULL;
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task)
}
taskmgr = NULL;
- RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr) ==
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, &taskmgr) ==
ISC_R_SUCCESS);
task = NULL;
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task) ==
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
- RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
+ RUNCHECK(isc_taskmgr_create(mctx, 1, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
isc_interval_set(&linterval, 1, 0);
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
- RUNTIME_CHECK(isc_taskmgr_create(mctx, 3, 0, &taskmgr) ==
- ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, 3, &taskmgr) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &g_task) ==
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
mctx2 = NULL;
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx2) == ISC_R_SUCCESS);
- RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &task_manager) ==
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, &task_manager) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx, &timer_manager) ==
ISC_R_SUCCESS);
dst_result_register();
taskmgr = NULL;
- RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) ==
- ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, &taskmgr) == ISC_R_SUCCESS);
task1 = NULL;
RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task1) == ISC_R_SUCCESS);
* 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, &manager) ==
ISC_R_SUCCESS);
/*
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
- RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, &manager) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS);
printf("%u workers\n", workers);
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx1) == ISC_R_SUCCESS);
- RUNTIME_CHECK(isc_taskmgr_create(mctx1, workers, 0, &manager) ==
+ RUNTIME_CHECK(isc_taskmgr_create(mctx1, workers, &manager) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx1, &timgr) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
- RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) ==
+ RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, &taskmgr) ==
ISC_R_SUCCESS);
RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
- RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
+ RUNCHECK(isc_taskmgr_create(mctx, 1, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
- RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
+ RUNCHECK(isc_taskmgr_create(mctx, 1, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
RUNCHECK(dst_lib_init(mctx, NULL));
taskmgr = NULL;
- RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
+ RUNCHECK(isc_taskmgr_create(mctx, 1, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
fatal("can't choose between IPv4 and IPv6");
taskmgr = NULL;
- RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
+ RUNCHECK(isc_taskmgr_create(mctx, 1, &taskmgr));
task = NULL;
RUNCHECK(isc_task_create(taskmgr, 0, &task));
timermgr = NULL;
result = isc_app_ctxstart(actx);
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr);
+ result = isc_taskmgr_createinctx(mctx, actx, 1, &taskmgr);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = isc_socketmgr_createinctx(mctx, actx, &socketmgr);
disp->ntasks = 1;
disp->task[0] = NULL;
- result = isc_task_create(taskmgr, 50, &disp->task[0]);
+ result = isc_task_create(taskmgr, 0, &disp->task[0]);
if (result != ISC_R_SUCCESS)
goto kill_socket;
isc_result_t result;
ncpus = isc_os_ncpus();
- CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
+ CHECK(isc_taskmgr_create(mctx, ncpus, &taskmgr));
CHECK(isc_timermgr_create(mctx, &timermgr));
CHECK(isc_socketmgr_create(mctx, &socketmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
if (result != ISC_R_SUCCESS)
goto fail;
- result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, taskmgrp);
if (result != ISC_R_SUCCESS)
goto fail;
isc_result_t
isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
- unsigned int workers, unsigned int default_quantum,
- isc_taskmgr_t **managerp);
+ unsigned int workers, 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);
+ isc_taskmgr_t **managerp);
/*%<
* Create a new task manager. isc_taskmgr_createinctx() also associates
* the new manager with the specified application context.
* create 'workers' threads, but if at least one thread creation
* succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS.
*
- *\li If 'default_quantum' is non-zero, then it will be used as the default
- * quantum value when tasks are created. If zero, then an implementation
- * defined default quantum will be used.
- *
* Requires:
*
*\li 'mctx' is a valid memory context.
isc_condition_t work_available;
isc_thread_t thread;
unsigned int threadid;
+ unsigned int tasks_waiting;
isc__taskmgr_t *manager;
};
isc__taskqueue_t *queues;
/* Locked by task manager lock. */
- unsigned int default_quantum;
LIST(isc__task_t) tasks;
isc_taskmgrmode_t mode;
bool pause_requested;
isc__taskmgr_resume(isc_taskmgr_t *manager0);
-#define DEFAULT_DEFAULT_QUANTUM 25
+/*
+ * Unless specified otherwise when creating task we normally run
+ * DEFAULT_QUANTUM events from a task in a single worker loop.
+ * If there are more than CONGESTED_TASK_LIMIT tasks waiting in the same queue
+ * we switch to CONGESTED_QUANTUM tasks per loop.
+ */
+
+#define DEFAULT_QUANTUM 25
+#define CONGESTED_QUANTUM 10
+#define CONGESTED_TASK_LIMIT 5
+
#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
/*%
INIT_LIST(task->events);
INIT_LIST(task->on_shutdown);
task->nevents = 0;
- task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
+ task->quantum = quantum;
task->flags = 0;
task->now = 0;
isc_time_settoepoch(&task->tnow);
if (task != NULL) {
DEQUEUE(manager->queues[c].ready_tasks, task, ready_link);
+ manager->queues[c].tasks_waiting--;
if (ISC_LINK_LINKED(task, ready_priority_link)) {
DEQUEUE(manager->queues[c].ready_priority_tasks, task,
ready_priority_link);
static inline void
push_readyq(isc__taskmgr_t *manager, isc__task_t *task, int c) {
ENQUEUE(manager->queues[c].ready_tasks, task, ready_link);
+ manager->queues[c].tasks_waiting++;
if ((task->flags & TASK_F_PRIVILEGED) != 0) {
ENQUEUE(manager->queues[c].ready_priority_tasks, task,
ready_priority_link);
task = pop_readyq(manager, threadid);
if (task != NULL) {
unsigned int dispatch_count = 0;
+ unsigned int quantum = task->quantum;
+ if (quantum == 0) {
+ if (manager->queues[threadid].tasks_waiting
+ < CONGESTED_TASK_LIMIT)
+ {
+ quantum = DEFAULT_QUANTUM;
+ } else {
+ quantum = CONGESTED_QUANTUM;
+ }
+ }
bool done = false;
bool requeue = false;
bool finished = false;
} else
task->state = task_state_idle;
done = true;
- } else if (dispatch_count >= task->quantum) {
+ } else if (dispatch_count >= quantum) {
/*
* Our quantum has expired, but
* there is more work to be done.
isc_result_t
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
- unsigned int default_quantum, isc_taskmgr_t **managerp)
+ isc_taskmgr_t **managerp)
{
unsigned int i;
isc__taskmgr_t *manager;
manager->workers = workers;
- if (default_quantum == 0) {
- default_quantum = DEFAULT_DEFAULT_QUANTUM;
- }
- manager->default_quantum = default_quantum;
INIT_LIST(manager->tasks);
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
RUNTIME_CHECK(manager->queues != NULL);
manager->queues[i].manager = manager;
manager->queues[i].threadid = i;
+ manager->queues[i].tasks_waiting = 0;
RUNTIME_CHECK(isc_thread_create(run, &manager->queues[i],
&manager->queues[i].thread)
== ISC_R_SUCCESS);
TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers));
TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"));
- TRY0(xmlTextWriterWriteFormatString(writer, "%d",
- mgr->default_quantum));
- TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */
-
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"));
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
(int) mgr->tasks_running));
CHECKMEM(obj);
json_object_object_add(tasks, "worker-threads", obj);
- obj = json_object_new_int(mgr->default_quantum);
- CHECKMEM(obj);
- json_object_object_add(tasks, "default-quantum", obj);
-
obj = json_object_new_int(mgr->tasks_running);
CHECKMEM(obj);
json_object_object_add(tasks, "tasks-running", obj);
isc_result_t
isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
- unsigned int workers, unsigned int default_quantum,
- isc_taskmgr_t **managerp)
+ unsigned int workers, isc_taskmgr_t **managerp)
{
isc_result_t result;
- result = isc_taskmgr_create(mctx, workers, default_quantum,
- managerp);
+ result = isc_taskmgr_create(mctx, workers, managerp);
if (result == ISC_R_SUCCESS)
isc_appctx_settaskmgr(actx, *managerp);
workers = atoi(p);
}
- CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr));
+ CHECK(isc_taskmgr_create(mctx, workers, &taskmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
isc_taskmgr_setexcltask(taskmgr, maintask);
result = isc_mem_create(0, 0, &mctx);
assert_int_equal(result, ISC_R_SUCCESS);
- result = isc_taskmgr_create(mctx, 4, 0, &taskmgr);
+ result = isc_taskmgr_create(mctx, 4, &taskmgr);
assert_int_equal(result, ISC_R_SUCCESS);
done = false;
isc_event_t *event = NULL;
ncpus = isc_os_ncpus();
- CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
+ CHECK(isc_taskmgr_create(mctx, ncpus, &taskmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
isc_taskmgr_setexcltask(taskmgr, maintask);
CHECK(isc_task_onshutdown(maintask, shutdown_managers, NULL));
if (result != ISC_R_SUCCESS)
goto fail;
- result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, taskmgrp);
if (result != ISC_R_SUCCESS)
goto fail;
result = isc_app_ctxstart(actx);
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr);
+ result = isc_taskmgr_createinctx(mctx, actx, 1, &taskmgr);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = isc_socketmgr_createinctx(mctx, actx, &socketmgr);
if (result != ISC_R_SUCCESS)
goto fail;
- result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, taskmgrp);
if (result != ISC_R_SUCCESS)
goto fail;