Lib/sequencer offers Multitasking
The lib/sequencer library implements one kind of cooperative multi-tasking of the event-driven kind. Unlike "pure" cooperative multi-tasking, a task cannot stop at any time (using a hypothetical yield feature) but only in known and stable states. That is conform to the Eiffel principles.
The principle is:
- the class LOOP_STACK manages the multi-tasking;
- the class JOB represents a task. The task core is the continue feature, during which execution the task controls the whole system;
- the class EVENTS_SET allows to describe in which conditions a task can be executed.
We will successively see each of those concepts.
The multi-tasking manager
The class LOOP_STACK is in charge of managing the multi-tasking. It is used in two steps:
- initialization: creation of the LOOP_STACK object, and adding of the tasks to execute
- execution: execution of the run feature
Of course, tasks can be added during the execution. The manager can also be stopped, thanks to the break feature.
A task has a life cycle represented by the features executed by the manager (indeed a LOOP_ITEM hence the export clauses of those features).
- prepare allows to prepare the task; in this phase, the task sets the events upon which it wants to be activated. The EVENTS_SET object is an object upon which one can set conditions (thanks to its expect feature).
- is_ready allows to test if the task has really been activated.The EVENTS_SET object is an object upon which one can test conditions (thanks to its event_occurred feature).
- continue contains the execution body of the task, and is executed if the task is really activated.
- done tells if the task has finished its execution. If so, it will be removed from the execution loop. Otherwise, the cycle begins again.
- restart allows to reinsert a task in the execution loop.
The restart feature is seldom useful. See Vision for some use cases.
The possible conditions are:
- Time: this allows to create periodic tasks. See the classes PERIODIC_JOB, BACKGROUND_JOB, and TIME_EVENTS;
- Network: this allows to build tasks waiting network connections (feature SOCKET_SERVER.event_connection).
The manager implements the following cycle:
- call to the feature EVENTS_SET.reset;
- call to the feature JOB.prepare on each task;
- call to the feature EVENTS_SET.wait to wait for at least one condition to happen;
- call to the feature JOB.is_ready on each task;
- for all the ready tasks, call to the feature JOB.continue;
- for those tasks, call to the feature JOB.done and if relevant, remove the task;
- and back to the beginning.
Tasks are executed by priority order. Only the ready tasks with a lower priority are executed. The others, even if ready, will have to wait a future time when no other task with a lower priority is ready.
Libraries using the sequencer
- lib/net: servers usually allow to accept many simultaneous connections. This is implemented with the sequencer library.
- lib/vision: the event manager loop is implemented with a sequencer.