Inheritance diagram for Task:

Click schedules a router's CPU or CPUs with one or more task queues. These queues are simply lists of tasks, which represent functions that would like unconditional access to the CPU. Tasks are generally associated with elements. When scheduled, most tasks call some element's run_task() method.
Click tasks are represented by Task objects. An element that would like special access to a router's CPU should include and initialize a Task instance variable.
Tasks are called very frequently, up to tens of thousands of times per second. Elements generally use Tasks for frequent tasks, and implement their own algorithms for scheduling and unscheduling the tasks when there's work to be done. For infrequent events, it is far more efficient to use Timer objects.
A Task's callback function, which is called when the task fires, has bool return type. The callback should return true if the task did useful work, and false if it was not able to do useful work (for example, because there were no packets in the configuration to return). Adaptive algorithms may use this information to fine-tune Click's scheduling behavior.
Since Click tasks are cooperatively scheduled, executing a task should not take a long time. Slow tasks can inappropriately delay timers and other periodic events.
This code shows how Task objects tend to be used. For fuller examples, see InfiniteSource and similar elements.
class InfiniteSource { ... bool run_task(Task *t); private: Task _task; }; InfiniteSource::InfiniteSource() : _task(this) { } int InfiniteSource::initialize(ErrorHandler *errh) { ScheduleInfo::initialize_task(this, &_task, errh); return 0; } bool InfiniteSource::run_task(Task *) { Packet *p = ... generate packet ...; output(0).push(p); if (packets left to send) _task.fast_reschedule(); return true; // the task did useful work }
Public Types | |
| enum | { STRIDE1 = 1U<<16, MAX_STRIDE = 1U<<31 } |
| enum | { MAX_TICKETS = 1<<15, DEFAULT_TICKETS = 1<<10 } |
Public Member Functions | |
| Task (TaskCallback f, void *user_data) | |
| Construct a task that calls f with user_data argument. | |
| Task (Element *e) | |
| Construct a task that calls e ->*) run_task(). | |
| ~Task () | |
| Destroy a task. | |
| TaskCallback | callback () const |
| Return the task's callback function. | |
| void * | user_data () const |
| Return the task callback function's user data. | |
| Element * | element () const |
| Return the task's owning element. | |
| bool | initialized () const |
| Return true iff the task has been initialize()d. | |
| int | home_thread_id () const |
| Return the task's home thread ID. | |
| RouterThread * | thread () const |
| Return the thread on which this task is currently scheduled, or would be scheduled. | |
| Router * | router () const |
| Return the router to which this task belongs. | |
| Master * | master () const |
| Return the master where this task will be scheduled. | |
| void | initialize (Element *owner, bool schedule) |
| Initialize the Task, and optionally schedule it. | |
| void | initialize (Router *router, bool schedule) |
| Initialize the Task, and optionally schedule it. | |
| bool | scheduled () const |
| Return true iff the task is currently scheduled to run. | |
| void | unschedule () |
| Unschedule the task. | |
| void | reschedule () |
| Reschedule the task. | |
| void | strong_unschedule () |
| Unschedule the Task and move it to a quiescent thread. | |
| void | strong_reschedule () |
| Reschedule the Task, moving it from the "dead" thread to its home thread if appropriate. | |
| void | fast_reschedule () |
| Reschedule the task. The task's current thread must be currently locked. | |
| void | move_thread (int thread_id) |
| Move the Task to a new home thread. | |
| int | tickets () const |
| Return the task's number of tickets. | |
| void | set_tickets (int n) |
| Set the task's ticket count. | |
| void | adjust_tickets (int delta) |
| Add delta to the Task's ticket count. | |
| void | fire () |
| Fire the task by calling its callback function. | |
| Task::Task | ( | TaskCallback | f, | |
| void * | user_data | |||
| ) | [inline] |
Construct a task that calls f with user_data argument.
| f | callback function | |
| user_data | argument for callback function |
bool work_done = f(task, user_data);
where task is a pointer to this task. f should return true if the task accomplished some meaningful work, and false if it did not. For example, a task that polls a network driver for packets should return true if it emits at least one packet, and false if no packets were available.
| Task::Task | ( | Element * | e | ) | [inline] |
Construct a task that calls e ->*) run_task().
| e | element to call |
| Task::~Task | ( | ) |
Destroy a task.
Unschedules the task if necessary.
| TaskCallback Task::callback | ( | ) | const [inline] |
Return the task's callback function.
Returns null if the task was constructed with the Task(Element *) constructor.
| void* Task::user_data | ( | ) | const [inline] |
Return the task callback function's user data.
| Element* Task::element | ( | ) | const [inline] |
Return the task's owning element.
| bool Task::initialized | ( | ) | const [inline] |
Return true iff the task has been initialize()d.
| int Task::home_thread_id | ( | ) | const [inline] |
Return the task's home thread ID.
This is the thread_id() of the thread on which this Task would run if it were scheduled. This need not equal the ID of the current thread(), since changes in home_thread_id() aren't always implemented immediately (because of locking issues).
| RouterThread * Task::thread | ( | ) | const [inline] |
Return the thread on which this task is currently scheduled, or would be scheduled.
Usually, task->thread()->thread_id() == task->home_thread_id(). They can differ, however, if move_thread() was called but the task hasn't yet been moved to the new thread, or if the task was strongly unscheduled with strong_unschedule(). (In this last case, task->thread()->thread_id() == RouterThread::THREAD_STRONG_UNSCHEDULE.)
| Router* Task::router | ( | ) | const [inline] |
Return the router to which this task belongs.
| Master * Task::master | ( | ) | const |
| void Task::initialize | ( | Element * | owner, | |
| bool | schedule | |||
| ) |
Initialize the Task, and optionally schedule it.
| owner | specifies the element owning the Task | |
| schedule | if true, the Task will be scheduled immediately |
An assertion will fail if a Task is initialized twice.
Most elements call ScheduleInfo::initialize_task() to initialize a Task object. The ScheduleInfo method additionally sets the task's scheduling parameters, such as ticket count and thread preference, based on a router's ScheduleInfo. ScheduleInfo::initialize_task() calls Task::initialize().
| void Task::initialize | ( | Router * | router, | |
| bool | schedule | |||
| ) |
Initialize the Task, and optionally schedule it.
| router | specifies the router owning the Task | |
| schedule | if true, the Task will be scheduled immediately |
| bool Task::scheduled | ( | ) | const [inline] |
Return true iff the task is currently scheduled to run.
| void Task::unschedule | ( | ) |
Unschedule the task.
After unschedule() returns, the task will not run until it is rescheduled with reschedule().
| void Task::reschedule | ( | ) | [inline] |
Reschedule the task.
The task is rescheduled on its home thread. The task will eventually run (unless the home thread is quiescent). Due to locking issues, the task may not be scheduled right away -- scheduled() may not immediately return true.
| void Task::strong_unschedule | ( | ) |
Unschedule the Task and move it to a quiescent thread.
When strong_unschedule() returns, the task will not be scheduled on any thread. Furthermore, the task has been moved to a temporary "dead" thread. Future reschedule() calls will not schedule the task, since the dead thread never runs; future move_thread() calls change the home thread ID, but leave the thread on the dead thread. Only strong_reschedule() can make the task run again.
| void Task::strong_reschedule | ( | ) |
Reschedule the Task, moving it from the "dead" thread to its home thread if appropriate.
This function undoes any previous strong_unschedule(). If the task is on the "dead" thread, then it is moved to its home thread. The task is also rescheduled. Due to locking issues, the task may not be scheduled right away -- scheduled() may not immediately return true.
| void Task::fast_reschedule | ( | ) | [inline] |
Reschedule the task. The task's current thread must be currently locked.
This accomplishes the same function as reschedule(), but does a faster job because it assumes the task's thread lock is held. Generally, this can be guaranteed only from within a task's run_task() callback function.
| void Task::move_thread | ( | int | thread_id | ) |
Move the Task to a new home thread.
The home thread ID is set to thread_id. The task, if it is currently scheduled, is rescheduled on thread thread_id; this generally takes some time to take effect. thread_id can be less than zero, in which case the thread is scheduled on a quiescent thread: it will never be run.
| int Task::tickets | ( | ) | const [inline] |
Return the task's number of tickets.
Tasks with larger numbers of tickets are scheduled more often. Tasks are initialized with tickets() == DEFAULT_TICKETS.
| void Task::set_tickets | ( | int | n | ) | [inline] |
Set the task's ticket count.
| n | the ticket count |
| void Task::adjust_tickets | ( | int | delta | ) | [inline] |
Add delta to the Task's ticket count.
| delta | adjustment to the ticket count |
| void Task::fire | ( | ) | [inline] |
Fire the task by calling its callback function.
This function is generally called by the RouterThread implementation; there should be no need to call it yourself.
1.5.1