!standard 9.1(21) 16-06-13 AI12-0197-2/02 !class Amendment 16-06-07 !status work item 16-06-12 !status received 16-06-12 !priority Very Low !difficulty Hard !subject Passive tasks !summary Aspect Passive is added to tasks (and task types) !problem Tasks are often a nice and readable model to express operations where state is kept as the place in execution, such as generators, couroutines, etc. However, using plain tasks involve efficiency costs due to task switching and raises scheduling issues. It should be possible to express behaviour in a task-like fashion, while being executed by the caller of provided services. !proposal Add a "passive" aspect to tasks and task types, specifying that the task has no thread of its own, but that its code is to be executed by client tasks when necessary. !wording !discussion There is no thread of control associated to a passive task. The model is that when a client task calls an entry of a server task, the code of the server task is executed "by proxy" by the caller task (similar to the proxy model of protected actions). This involves stack switching, but no task switching. All scheduling properties remain those of the client task. The client task will execute the server code up to the point where it returns from the called entry. There is no restriction to what can be executed while "catching-up". The rendezvous is considered to start as soon as the client calls the entry (therefore including while catching-up). A consequence of this is that abort is deferred for the client, and that changes to the waiting queue for the entry (like reordering due to changes of priority, f.e.) do not affect the behaviour. On the other hand, if the server task is aborted, execution of the server code is aborted and the client receives Tasking_Error, as expected. Similarly, when a passive task is to be activated, the activator will execute the activation code up to the point of the begin of the task; this ensures that the activator receives Tasking_Error if the activation fails, as for a normal task. This also means that if several tasks are to be activated together, they will be activated sequentially (in some unspecified order) rather than in parallel; depending on context, this can be seen either as a benefit or a drawback. When a master completes, it will "catch up" all its dependent passive tasks to ensure proper termination. If a master executes a select statement with a terminate alternative, it will similarly "catch up" its dependent tasks until termination conditions are met, or it can be decided that they are not met. This model provides a kind of lazy evaluation and saves the task switching cost. As it is a purely sequential model, ordering of actions is well defined (at least between client and server). An implementation permission should be provided to ignore the "passive" aspect. The main difference if the aspect is ignored is for the scheduling aspects of the server task (including possible ordering of actions). !ASIS !ACATS test !appendix From: Jean-Pierre Rosen Sent: Sunday, June 12, 2016 5:53 AM Here is a first shot at what I had in mind about passive tasks. [This was version /01 of the AI - Editor.] Wait while I get my asbestos suit... **************************************************************** From: Jean-Pierre Rosen Sent: Sunday, June 12, 2016 11:22 AM Here is a new version of the proposal for passive tasks. I added a discussion about activation and termination of passive tasks - refinements are certainly needed in this area. [This was version /02 of the AI - I also made a few tiny changes to put this into the format of an Amendment - Editor.] **************************************************************** From: Alan Burns Sent: Sunday, June 12, 2016 9:16 PM Some thoughts on passive tasks. It would seem desirable for the client of a passive task not to be delayed other than by the execution of the code of the passive task (the catching up code and the accept statement for the entry). It follows that a passive task should not call any potentially blocking operations other than accept statements. One could go further and restrict a passive task to a single entry. This would prevent the passive task been blocked on accept E1, when the client task had called E2. If a passive task can block then perhaps the client task could make a conditional entry call that is now defined to fail if the passive task is not executable, rather than not at an appropriate accept statement. **************************************************************** From: Jeff Cousins Sent: Monday, June 13, 2016 2:06 AM "couroutines" - matters of the heart? Couldn't entries in other passive tasks be called? **************************************************************** From: Arnaud Charlet Sent: Monday, June 13, 2016 12:58 AM > It would seem desirable for the client of a passive task not to be delayed > other than by the execution of the code of the passive task (the catching > up code and the accept statement for the entry). It follows that a passive > task should not call any potentially blocking operations other than accept > statements. I do not think it is a good idea to forbid e.g. IO in this context and end up reinventing protected objects. ****************************************************************