Task Class Reference

Inheritance diagram for Task:

RouterThread List of all members.

Detailed Description

Represents a frequently-scheduled computational 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.
Elementelement () 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.
RouterThreadthread () const
 Return the thread on which this task is currently scheduled, or would be scheduled.
Routerrouter () 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.


Constructor & Destructor Documentation

Task::Task ( TaskCallback  f,
void *  user_data 
) [inline]

Construct a task that calls f with user_data argument.

Parameters:
f callback function
user_data argument for callback function
Constructs a task that, when fired, calls f like so:

 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().

Parameters:
e element to call
Constructs a task that, when fired, calls the element e's run_task() method, passing this Task as an argument.

See also:
Task(TaskCallback, void *)

Task::~Task (  ) 

Destroy a task.

Unschedules the task if necessary.


Member Function Documentation

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

Return the master where this task will be scheduled.

Reimplemented in RouterThread.

void Task::initialize ( Element owner,
bool  schedule 
)

Initialize the Task, and optionally schedule it.

Parameters:
owner specifies the element owning the Task
schedule if true, the Task will be scheduled immediately
This function must be called on every Task before it is used. The corresponding router's ThreadSched, if any, is used to determine the task's initial thread assignment. The task initially has the default number of tickets, and is scheduled iff schedule is true.

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.

Parameters:
router specifies the router owning the Task
schedule if true, the Task will be scheduled immediately
This function is shorthand for Task::initialize(router ->root_element(), scheduled). However, it is better to explicitly associate tasks with real elements.

bool Task::scheduled (  )  const [inline]

Return true iff the task is currently scheduled to run.

Note:
The scheduled() function is only approximate. It may return false for a scheduled task, or true for an unscheduled task, due to locking issues that prevent some unschedule() and reschedule() operations from completing immediately.

void Task::unschedule (  ) 

Unschedule the task.

After unschedule() returns, the task will not run until it is rescheduled with reschedule().

Note:
scheduled() may return true for a short time even after unschedule().
See also:
reschedule, strong_unschedule, fast_unschedule

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.

See also:
unschedule, strong_reschedule

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.

See also:
strong_reschedule, unschedule

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.

See also:
reschedule, strong_unschedule

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.

See also:
set_tickets, adjust_tickets

void Task::set_tickets ( int  n  )  [inline]

Set the task's ticket count.

Parameters:
n the ticket count
The ticket count n is pinned to the range [1, MAX_TICKETS].

See also:
tickets, adjust_tickets

void Task::adjust_tickets ( int  delta  )  [inline]

Add delta to the Task's ticket count.

Parameters:
delta adjustment to the ticket count
The ticket count cannot be adjusted below 1 or above MAX_TICKETS.

See also:
set_tickets

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.


The documentation for this class was generated from the following files:
Generated on Tue Mar 2 12:25:48 2010 for Click by  doxygen 1.5.1