Difference between revisions of "Lib/sequencer offers Multitasking"

From Liberty Eiffel Wiki
Jump to navigation Jump to search
(typo)
(revisited for 2.3)
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[Category:Book]]
 
[[Category:Book]]
   
  +
The <tt>lib/sequencer</tt> 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 <tt>yield</tt> feature) but only in known and stable states. That is conform to the Eiffel principles.
<!--
 
{{TranslationWanted}}
 
 
*** Translation over, if some English native people could check that would be nice
 
*** --[[User:Cadrian|Cyril]] 14:57, 4 Jan 2006 (CET)
 
-->
 
 
The <tt>lib/sequencer</tt> library implements one kind of cooperative multi-tasking of the event-driver kind. Unlike "pure" cooperative multi-tasking, a task cannot stop at any time (using a hypothetical <tt>yield</tt> feature) but only in known and stable states. That is conform to the Eiffel principles.
 
   
 
The principle is:
 
The principle is:
   
 
* the class [[library_class:LOOP_STACK|<tt>LOOP_STACK</tt>]] manages the multi-tasking;
 
* the class [[library_class:LOOP_STACK|<tt>LOOP_STACK</tt>]] manages the multi-tasking;
* the class [[library_class:JOB|<tt>JOB</TT>]] represents a task. The task core is the <tt>continue</tt> feature, in which the task controls the whole system;
+
* the class [[library_class:JOB|<tt>JOB</TT>]] represents a task. The task core is the <tt>continue</tt> feature, during which execution the task controls the whole system;
* the class [[library_class:READY_DESCRIPTION|<tt>READY_DESCRIPTION</tt>]] allows to describe in which conditions a task can be executed.
+
* the class [[library_class:EVENTS_SET|<tt>EVENTS_SET</tt>]] allows to describe in which conditions a task can be executed.
   
 
We will successively see each of those concepts.
 
We will successively see each of those concepts.
Line 20: Line 13:
 
== The multi-tasking manager ==
 
== The multi-tasking manager ==
 
The class [[library_class:LOOP_STACK|<tt>LOOP_STACK</tt>]] is in charge of managing the multi-tasking. It is used in two steps:
 
The class [[library_class:LOOP_STACK|<tt>LOOP_STACK</tt>]] is in charge of managing the multi-tasking. It is used in two steps:
* initialisation: creation of the <tt>LOOP_STACK</tt> object, and adding of the tasks to execute
+
* initialization: creation of the <tt>LOOP_STACK</tt> object, and adding of the tasks to execute
 
* execution: execution of the <tt>run</tt> feature
 
* execution: execution of the <tt>run</tt> feature
   
 
Of course, tasks can be added during the execution. The manager can also be stopped, thanks to the <tt>break</tt> feature.
 
Of course, tasks can be added during the execution. The manager can also be stopped, thanks to the <tt>break</tt> feature.
   
Also, the loops stack is composed of many execution loops ([[library_class:LOOP_ITEM|<tt>LOOP_ITEM</tt>]]). This allows, for instance, the implementation of a kind of ''modality'' (see the modal windows in [[lib/vision|Vision]]).
+
Also, the loops stack is composed of many execution loops ([[library_class:LOOP_ITEM|<tt>LOOP_ITEM</tt>]]). This allows, for instance, the implementation of a kind of ''modality'' (e.g. the modal windows in [[lib/vision|Vision]]).
   
 
== Tasks ==
 
== Tasks ==
   
A task has a life cycle represented by the features executed by the manager (indeed a [[library_class:LOOP_ITEM|<tt>LOOP_ITEM</tt>]] hence the export clauses of those fetaures).
+
A task has a life cycle represented by the features executed by the manager (indeed a [[library_class:LOOP_ITEM|<tt>LOOP_ITEM</tt>]] hence the export clauses of those features).
   
# <tt>prepare</tt> allows to prepare the task; in this phase, the task sets the events upon which it wants to be activated. The [[library_class:READY_DESCRIPTION|<tt>READY_DESCRIPTION</tt>]] object is an object upon which one can set conditions (thanks to its <tt>when_*</tt> features).
+
# <tt>prepare</tt> allows to prepare the task; in this phase, the task sets the events upon which it wants to be activated. The [[library_class:EVENTS_SET|<tt>EVENTS_SET</tt>]] object is an object upon which one can set conditions (thanks to its <tt>expect</tt> feature).
# <tt>is_ready</tt> allows to test if the task has really been activated.The [[library_class:READY_DESCRIPTION|<tt>READY_DESCRIPTION</tt>]] object is an object upon which one can test conditions (thanks to its <tt>is_*</tt> features).
+
# <tt>is_ready</tt> allows to test if the task has really been activated.The [[library_class:EVENTS_SET|<tt>EVENTS_SET</tt>]] object is an object upon which one can test conditions (thanks to its <tt>event_occurred</tt> feature).
 
# <tt>continue</tt> contains the execution body of the task, and is executed if the task is really activated.
 
# <tt>continue</tt> contains the execution body of the task, and is executed if the task is really activated.
 
# <tt>done</tt> tells if the task has finished its execution. If so, it will be removed from the execution loop. Otherwise, the cycle begins again.
 
# <tt>done</tt> tells if the task has finished its execution. If so, it will be removed from the execution loop. Otherwise, the cycle begins again.
Line 41: Line 34:
 
== Execution conditions ==
 
== Execution conditions ==
   
The class [[library_class:READY_DESCRIPTION|<tt>READY_DESCRIPTION</tt>]] allows to set and test conditions. The possible conditions are:
+
The class [[library_class:EVENTS_SET|<tt>EVENTS_SET</tt>]] allows to set and test conditions ([[library_class:EVENT_DESCRIPTOR|<tt>EVENT_DESCRIPTOR</tt>]]s).
  +
  +
The possible conditions are:
   
* '''Time''': this allows to create periodic tasks. See the classes [[library_class:PERIODIC_JOB|<tt>PERIODIC_JOB</tt>]] and [[library_class:BACKGROUND_JOB|<tt>BACKGROUND_JOB</tt>]];
+
* '''Time''': this allows to create periodic tasks. See the classes [[library_class:PERIODIC_JOB|<tt>PERIODIC_JOB</tt>]], [[library_class:BACKGROUND_JOB|<tt>BACKGROUND_JOB</tt>]], and [[library_class:TIME_EVENTS|<tt>TIME_EVENTS</tt>]];
 
* '''Input-output''':
 
* '''Input-output''':
** ''Data on an input stream'': this allows to build tasks that wait for input data to be available (features <tt>when_data</tt> and <tt>is_data</tt>),
+
** ''Data on an input stream'': this allows to build tasks that wait for input data to be available (feature [[library_class:INPUT_STREAM|<tt>INPUT_STREAM</tt>]]<tt>.event_can_read</tt>),
** ''Data on an output stream'': this allows to build tasks that wait until they can write on an output stream (features <tt>when_free</tt> and <tt>is_free</tt>)&nbsp;;
+
** ''Data on an output stream'': this allows to build tasks that wait until they can write on an output stream (feature [[library_class:OUTPUT_STREAM|<tt>OUTPUT_STREAM</tt>]]<tt>.event_can_write</tt>);
* '''Network''': this allows to build tasks waiting network connections (features <tt>when_connection</tt> and <tt>is_connection</tt>).
+
* '''Network''': this allows to build tasks waiting network connections (feature [[library_class:SOCKET_SERVER|<tt>SOCKET_SERVER</tt>]]<tt>.event_connection</tt>).
   
 
== Tasks unfolding ==
 
== Tasks unfolding ==
Line 53: Line 48:
 
The manager implements the following cycle:
 
The manager implements the following cycle:
   
* call to the feature [[library_class:READY_DESCRIPTION|<tt>READY_DESCRIPTION</tt>]].<tt>reset</tt>;
+
* call to the feature [[library_class:EVENTS_SET|<tt>EVENTS_SET</tt>]]<tt>.reset</tt>;
* call to the feature <tt>prepare</tt> on each task;
+
* call to the feature [[library_class:JOB|<tt>JOB</tt>]]<tt>.prepare</tt> on each task;
* call to the feature [[library_class:READY_DESCRIPTION|<tt>READY_DESCRIPTION</tt>]].<tt>wait</tt> to wait for at least one condition to happen;
+
* call to the feature [[library_class:EVENTS_SET|<tt>EVENTS_SET</tt>]]<tt>.wait</tt> to wait for at least one condition to happen;
* call to the feature <tt>is_ready</tt> on each task;
+
* call to the feature [[library_class:JOB|<tt>JOB</tt>]]<tt>.is_ready</tt> on each task;
* for all the ready tasks, call to the feature <tt>continue</tt>;
+
* for all the ready tasks, call to the feature [[library_class:JOB|<tt>JOB</tt>]]<tt>.continue</tt>;
* for those tasks, call to the feature <tt>done</tt> and if relevent, removal of the task;
+
* for those tasks, call to the feature [[library_class:JOB|<tt>JOB</tt>]]<tt>.done</tt> and if relevant, remove the task;
 
* and back to the beginning.
 
* and back to the beginning.
   
 
== Priorities ==
 
== Priorities ==
   
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.
+
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 ==
 
== Libraries using the sequencer ==

Revision as of 12:46, 25 April 2007


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.

Also, the loops stack is composed of many execution loops (LOOP_ITEM). This allows, for instance, the implementation of a kind of modality (e.g. the modal windows in Vision).

Tasks

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

  1. 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).
  2. 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).
  3. continue contains the execution body of the task, and is executed if the task is really activated.
  4. done tells if the task has finished its execution. If so, it will be removed from the execution loop. Otherwise, the cycle begins again.
  5. restart allows to reinsert a task in the execution loop.

The restart feature is seldom useful. See Vision for some use cases.

Execution conditions

The class EVENTS_SET allows to set and test conditions (EVENT_DESCRIPTORs).

The possible conditions are:

  • Time: this allows to create periodic tasks. See the classes PERIODIC_JOB, BACKGROUND_JOB, and TIME_EVENTS;
  • Input-output:
    • Data on an input stream: this allows to build tasks that wait for input data to be available (feature INPUT_STREAM.event_can_read),
    • Data on an output stream: this allows to build tasks that wait until they can write on an output stream (feature OUTPUT_STREAM.event_can_write);
  • Network: this allows to build tasks waiting network connections (feature SOCKET_SERVER.event_connection).

Tasks unfolding

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.

Priorities

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 connexions. This is implemented thanks to the sequencer.
  • lib/vision: the event manager loop is implemented with a sequencer.