Index

Cooperating Sequential Tasks

  1. Introduction
    1. Arduino
    2. Interrupts
  2. Simple Tasks
  3. Multiple Tasks
  4. Communicating Tasks
  5. Communicating Values
  6. Synchronising Tasks
  7. Buffered Communication
  8. Multiple Senders
  9. Conditional Tasks
  10. Transput
  11. Implementation
    1. Common Data
    2. Tasks
    3. task_builder
    4. task
    5. channel
    6. virtual_machine
    7. set
    8. queue
    9. clock
    10. standard
    11. Adjusting Limits
images/24-1.png

Common Data



Most of the library components need access to common data describing the state of the tasks being executed. The variables which maintain this state are defined by Tasks.cpp as members of the tasks_system namespace used by all the components.

byte        next_channel;
channel     channels[max_channels];


Every time new_channel is called the value of next_channel, which is initialised to zero, is used to define the channel's identifier, after which it is incremented by one. Information about the state of each channel is maintained in the channels array indexed by channel identifier. The channel type is defined in channel.h.

byte        next_task;
task_record tasks[max_tasks];


Every time new_task is called the value of next_task, which is initialised to zero, is used to define the task's identifier, after which it is incremented by one. Information about the state of each task is maintained in the tasks array indexed by task identifier. The task type is defined in type.h.

int         next_code;
int         code[code_size];


Every time an action is added to a task, a value used to represent it is added to the code array using next_code, which is initialised to zero, as an index. The value of next_code is then incremented by one. One entry is also added to the code array for each action parameter, e.g. pause(100) requires two entries in the code array.

queue       active_queue;


The active_queue variable is used to maintain a queue of task identifiers in the order they will be selected for execution. When a task is delayed waiting on a condition or for some time interval, or for communication to take place, it will be removed from the queue. When it becomes ready for execution again, it will be placed at the back of the queue. At any particular time the task at the front of the queue is the one being executed. The queue type is defined in queue.h.

set         waiting_set;


When a task starts waiting on a condition, or is paused, it will be removed from the front of the active_queue and added to the waiting_set so that the system can periodically check to see which tasks are ready to continue. Normally tasks are selected for execution in the order defined by the active_queue, however they may finish waiting, and thus be remove from the waiting_set, in any order. When a task is removed from the waiting_set it is placed at the back of the active_queue. The set type is defined in set.h.

byte        current_task;


While a task is being defined, i.e. after a call of new_task and before a call of end_task, or when it is active and being executed, current_task will hold the tasks identifier.

bool        skip;


The skip variable is used to implement the when and repeat actions.