Lines Matching refs:task

25  * XXXRTH  Need to document the states a task can be in, and the rules
38 #include <isc/task.h>
51 * when built without threads we share a single global task manager and use
52 * an integrated event loop for socket, timer, and other generic task events.
54 * we don't use either of them: an application can have multiple task managers
70 #define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
71 task, isc_thread_self(), (m))
72 #define XTTRACE(t, m) fprintf(stderr, "task %p thread %lu: %s\n", \
108 /* Locked by task lock. */
118 /* Locked by task manager lock. */
144 /* Locked by task manager lock. */
197 isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
202 isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
206 isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
229 isc__task_beginexclusive(isc_task_t *task);
248 push_readyq(isc__taskmgr_t *manager, isc__task_t *task);
297 task_finished(isc__task_t *task) {
298 isc__taskmgr_t *manager = task->manager;
300 REQUIRE(EMPTY(task->events));
301 REQUIRE(EMPTY(task->on_shutdown));
302 REQUIRE(task->references == 0);
303 REQUIRE(task->state == task_state_done);
308 UNLINK(manager->tasks, task, link);
313 * task manager is exiting. Wake up
322 DESTROYLOCK(&task->lock);
323 task->common.impmagic = 0;
324 task->common.magic = 0;
325 isc_mem_put(manager->mctx, task, sizeof(*task));
333 isc__task_t *task;
340 task = isc_mem_get(manager->mctx, sizeof(*task));
341 if (task == NULL)
344 result = isc_mutex_init(&task->lock);
346 isc_mem_put(manager->mctx, task, sizeof(*task));
350 LOCK(&task->lock); /* helps coverity analysis noise ratio */
351 task->manager = manager;
352 task->state = task_state_idle;
353 task->references = 1;
354 INIT_LIST(task->events);
355 INIT_LIST(task->on_shutdown);
356 task->quantum = quantum;
357 task->flags = 0;
358 task->now = 0;
359 memset(task->name, 0, sizeof(task->name));
360 task->tag = NULL;
361 INIT_LINK(task, link);
362 INIT_LINK(task, ready_link);
363 INIT_LINK(task, ready_priority_link);
364 UNLOCK(&task->lock);
370 if (task->quantum == 0)
371 task->quantum = manager->default_quantum;
372 APPEND(manager->tasks, task, link);
378 DESTROYLOCK(&task->lock);
379 isc_mem_put(manager->mctx, task, sizeof(*task));
383 task->common.methods = (isc_taskmethods_t *)&taskmethods;
384 task->common.magic = ISCAPI_TASK_MAGIC;
385 task->common.impmagic = TASK_MAGIC;
386 *taskp = (isc_task_t *)task;
412 task_shutdown(isc__task_t *task) {
417 * Caller must be holding the task's lock.
422 if (! TASK_SHUTTINGDOWN(task)) {
425 task->flags |= TASK_F_SHUTTINGDOWN;
426 if (task->state == task_state_idle) {
427 INSIST(EMPTY(task->events));
428 task->state = task_state_ready;
431 INSIST(task->state == task_state_ready ||
432 task->state == task_state_running);
437 for (event = TAIL(task->on_shutdown);
441 DEQUEUE(task->on_shutdown, event, ev_link);
442 ENQUEUE(task->events, event, ev_link);
450 * Moves a task onto the appropriate run queue.
455 task_ready(isc__task_t *task) {
456 isc__taskmgr_t *manager = task->manager;
458 isc_boolean_t has_privilege = isc__task_privilege((isc_task_t *) task);
462 REQUIRE(task->state == task_state_ready);
467 push_readyq(manager, task);
476 task_detach(isc__task_t *task) {
479 * Caller must be holding the task lock.
482 REQUIRE(task->references > 0);
486 task->references--;
487 if (task->references == 0 && task->state == task_state_idle) {
488 INSIST(EMPTY(task->events));
490 * There are no references to this task, and no
492 * either initiate shutdown or clean up the task,
494 * make the task ready and allow run() or the event
497 task->state = task_state_ready;
506 isc__task_t *task;
510 * Detach *taskp from its task.
514 task = (isc__task_t *)*taskp;
515 REQUIRE(VALID_TASK(task));
519 LOCK(&task->lock);
520 was_idle = task_detach(task);
521 UNLOCK(&task->lock);
524 task_ready(task);
530 task_send(isc__task_t *task, isc_event_t **eventp) {
535 * Caller must be holding the task lock.
542 REQUIRE(task->state != task_state_done);
546 if (task->state == task_state_idle) {
548 INSIST(EMPTY(task->events));
549 task->state = task_state_ready;
551 INSIST(task->state == task_state_ready ||
552 task->state == task_state_running);
553 ENQUEUE(task->events, event, ev_link);
561 isc__task_t *task = (isc__task_t *)task0;
565 * Send '*event' to 'task'.
568 REQUIRE(VALID_TASK(task));
577 LOCK(&task->lock);
578 was_idle = task_send(task, eventp);
579 UNLOCK(&task->lock);
583 * We need to add this task to the ready queue.
585 * We've waited until now to do it because making a task
587 * this while holding the task lock, we could deadlock.
590 * be trying to add this task to the ready queue. The
592 * task. It thus doesn't matter if events are added,
594 * between the time we released the task lock, and the time
595 * we add the task to the ready queue.
597 task_ready(task);
604 isc__task_t *task;
608 * task.
612 task = (isc__task_t *)*taskp;
613 REQUIRE(VALID_TASK(task));
617 LOCK(&task->lock);
618 idle1 = task_send(task, eventp);
619 idle2 = task_detach(task);
620 UNLOCK(&task->lock);
624 * the task lock, and thus the task cannot switch from ready back to
630 task_ready(task);
638 dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first,
645 REQUIRE(VALID_TASK(task));
658 LOCK(&task->lock);
660 for (event = HEAD(task->events); event != NULL; event = next_event) {
666 DEQUEUE(task->events, event, ev_link);
672 UNLOCK(&task->lock);
681 isc__task_t *task = (isc__task_t *)task0;
687 * Purge events from a task's event queue.
694 count = dequeue_events(task, sender, first, last, tag, &events,
703 * Note that purging never changes the state of the task.
710 isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
714 * Purge events from a task's event queue.
719 return (isc__task_purgerange(task, sender, type, type, tag));
724 isc__task_t *task = (isc__task_t *)task0;
728 * Purge 'event' from a task's event queue.
733 REQUIRE(VALID_TASK(task));
736 * If 'event' is on the task's event queue, it will be purged,
738 * on the task's event queue; in fact, it can even be an invalid
739 * pointer. Purging only occurs if the event is actually on the task's
742 * Purging never changes the state of the task.
745 LOCK(&task->lock);
746 for (curr_event = HEAD(task->events);
751 DEQUEUE(task->events, curr_event, ev_link);
755 UNLOCK(&task->lock);
766 isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
771 * Remove events from a task's event queue.
776 return (dequeue_events((isc__task_t *)task, sender, first,
781 isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
785 * Remove events from a task's event queue.
790 return (dequeue_events((isc__task_t *)task, sender, type,
798 isc__task_t *task = (isc__task_t *)task0;
805 * 'task' is shutdown.
808 REQUIRE(VALID_TASK(task));
811 event = isc_event_allocate(task->manager->mctx,
820 LOCK(&task->lock);
821 if (TASK_SHUTTINGDOWN(task)) {
825 ENQUEUE(task->on_shutdown, event, ev_link);
826 UNLOCK(&task->lock);
829 isc_mem_put(task->manager->mctx, event, sizeof(*event));
836 isc__task_t *task = (isc__task_t *)task0;
840 * Shutdown 'task'.
843 REQUIRE(VALID_TASK(task));
845 LOCK(&task->lock);
846 was_idle = task_shutdown(task);
847 UNLOCK(&task->lock);
850 task_ready(task);
868 isc__task_t *task = (isc__task_t *)task0;
871 * Name 'task'.
874 REQUIRE(VALID_TASK(task));
876 LOCK(&task->lock);
877 memset(task->name, 0, sizeof(task->name));
878 strncpy(task->name, name, sizeof(task->name) - 1);
879 task->tag = tag;
880 UNLOCK(&task->lock);
885 isc__task_t *task = (isc__task_t *)task0;
887 REQUIRE(VALID_TASK(task));
889 return (task->name);
894 isc__task_t *task = (isc__task_t *)task0;
896 REQUIRE(VALID_TASK(task));
898 return (task->tag);
903 isc__task_t *task = (isc__task_t *)task0;
905 REQUIRE(VALID_TASK(task));
908 LOCK(&task->lock);
909 *t = task->now;
910 UNLOCK(&task->lock);
922 * Caller must hold the task manager lock.
937 * Dequeue and return a pointer to the first task on the current ready
939 * If the task is privileged, dequeue it from the other ready list
942 * Caller must hold the task manager lock.
946 isc__task_t *task;
949 task = HEAD(manager->ready_tasks);
951 task = HEAD(manager->ready_priority_tasks);
953 if (task != NULL) {
954 DEQUEUE(manager->ready_tasks, task, ready_link);
955 if (ISC_LINK_LINKED(task, ready_priority_link))
956 DEQUEUE(manager->ready_priority_tasks, task,
960 return (task);
964 * Push 'task' onto the ready_tasks queue. If 'task' has the privilege
967 * Caller must hold the task manager lock.
970 push_readyq(isc__taskmgr_t *manager, isc__task_t *task) {
971 ENQUEUE(manager->ready_tasks, task, ready_link);
972 if ((task->flags & TASK_F_PRIVILEGED) != 0)
973 ENQUEUE(manager->ready_priority_tasks, task,
979 isc__task_t *task;
1049 * the task while only holding the manager lock, and then
1050 * change the task to running state while only holding the
1051 * task lock.
1075 task = pop_readyq(manager);
1076 if (task != NULL) {
1083 INSIST(VALID_TASK(task));
1087 * have a task to do. We must reacquire the manager
1088 * lock before exiting the 'if (task != NULL)' block.
1093 LOCK(&task->lock);
1094 INSIST(task->state == task_state_ready);
1095 task->state = task_state_running;
1098 isc_stdtime_get(&task->now);
1100 if (!EMPTY(task->events)) {
1101 event = HEAD(task->events);
1102 DEQUEUE(task->events, event, ev_link);
1112 UNLOCK(&task->lock);
1114 (isc_task_t *)task,
1116 LOCK(&task->lock);
1124 if (task->references == 0 &&
1125 EMPTY(task->events) &&
1126 !TASK_SHUTTINGDOWN(task)) {
1131 * pending events for this task,
1141 * the "if EMPTY(task->events)" block
1145 * we want the task to finish.
1148 * will still want the task's
1151 was_idle = task_shutdown(task);
1155 if (EMPTY(task->events)) {
1157 * Nothing else to do for this task
1164 if (task->references == 0 &&
1165 TASK_SHUTTINGDOWN(task)) {
1167 * The task is done.
1175 task->state = task_state_done;
1177 task->state = task_state_idle;
1179 } else if (dispatch_count >= task->quantum) {
1194 task->state = task_state_ready;
1199 UNLOCK(&task->lock);
1202 task_finished(task);
1222 * empty is to 'goto' the 'if (task != NULL)'
1223 * block, avoiding the ENQUEUE of the task
1225 * (since it is the only executable task).
1236 push_readyq(manager, task);
1238 ENQUEUE(new_ready_tasks, task, ready_link);
1239 if ((task->flags & TASK_F_PRIVILEGED) != 0)
1240 ENQUEUE(new_priority_tasks, task,
1329 * Create a new task manager.
1458 isc__task_t *task;
1485 * task manager, it should ask some non-worker thread to call
1496 * task manager lock and a task lock at the same time.
1513 * Post shutdown event(s) to every task (if they haven't already been
1516 for (task = HEAD(manager->tasks);
1517 task != NULL;
1518 task = NEXT(task, link)) {
1519 LOCK(&task->lock);
1520 if (task_shutdown(task))
1521 push_readyq(manager, task);
1522 UNLOCK(&task->lock);
1643 isc__task_t *task = (isc__task_t *)task0;
1644 isc__taskmgr_t *manager = task->manager;
1645 REQUIRE(task->state == task_state_running);
1665 isc__task_t *task = (isc__task_t *)task0;
1666 isc__taskmgr_t *manager = task->manager;
1668 REQUIRE(task->state == task_state_running);
1681 isc__task_t *task = (isc__task_t *)task0;
1682 isc__taskmgr_t *manager = task->manager;
1685 LOCK(&task->lock);
1686 oldpriv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0);
1688 task->flags |= TASK_F_PRIVILEGED;
1690 task->flags &= ~TASK_F_PRIVILEGED;
1691 UNLOCK(&task->lock);
1697 if (priv && ISC_LINK_LINKED(task, ready_link))
1698 ENQUEUE(manager->ready_priority_tasks, task,
1700 else if (!priv && ISC_LINK_LINKED(task, ready_priority_link))
1701 DEQUEUE(manager->ready_priority_tasks, task,
1708 isc__task_t *task = (isc__task_t *)task0;
1711 LOCK(&task->lock);
1712 priv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0);
1713 UNLOCK(&task->lock);
1726 isc__task_t *task = (isc__task_t *)t;
1728 REQUIRE(VALID_TASK(task));
1729 return (TASK_SHUTTINGDOWN(task));
1737 isc__task_t *task;
1775 task = ISC_LIST_HEAD(mgr->tasks);
1776 while (task != NULL) {
1777 LOCK(&task->lock);
1778 xmlTextWriterStartElement(writer, ISC_XMLCHAR "task");
1780 if (task->name[0] != 0) {
1783 task->name);
1788 xmlTextWriterWriteFormatString(writer, "%d", task->references);
1792 xmlTextWriterWriteFormatString(writer, "%p", task);
1797 statenames[task->state]);
1801 xmlTextWriterWriteFormatString(writer, "%d", task->quantum);
1806 UNLOCK(&task->lock);
1807 task = ISC_LIST_NEXT(task, link);