home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / lrm / chap09.doc < prev    next >
Encoding:
Text File  |  1988-05-03  |  60.6 KB  |  2,642 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. The following document is a draft  of  the  corresponding  chapter  of  the
  7. version  of  the  Ada  Reference  Manual  produced  in response to the Ansi
  8. Canvass.  It is given a limited circulation  to  Ada  implementers  and  to
  9. other groups contributing comments (according to the conventions defined in
  10. RRM.comments).  This draft should not be referred to in any publication.
  11.  
  12.  
  13.  
  14.                       ANSI-RM-09-v23 - Draft Chapter
  15.  
  16.                                  9  Tasks
  17.                                 version 23
  18.  
  19.                                  83-02-11
  20.  
  21.              This revision has addressed comments up to #5795
  22.  
  23. (except  those  marked  "consider"  on  the restriction of select within an
  24. inner block)
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.                                  9. Tasks
  78.  
  79.  
  80.  
  81. The execution of a program that does not contain a task is defined in terms
  82. of a sequential execution of its actions, according to the rules  described
  83. in  other  chapters  of this manual.  These actions can be considered to be
  84. executed by a single logical processor.
  85.  
  86. Tasks are entities whose executions proceed in parallel  in  the  following
  87. sense.   Each  task can be considered to be executed by a logical processor
  88. of  its  own.   Different  tasks  (different  logical  processors)  proceed
  89. independently, except at points where they synchronize.
  90.  
  91. Some  tasks have entries.  An entry of a task can be called by other tasks.
  92. A task accepts a call  of  one  of  its  entries  by  executing  an  accept
  93. statement for the entry.  Synchronization is achieved by rendezvous between
  94. a  task  issuing an entry call and a task accepting the call.  Some entries
  95. have parameters;  entry calls and accept statements for  such  entries  are
  96. the principal means of communicating values between tasks.
  97.  
  98. The  properties of each task are defined by a corresponding task unit which
  99. consists of a task specification and a task body.  Task units  are  one  of
  100. the  four  forms  of  program  unit of which programs can be composed.  The
  101. other forms are subprograms, packages and generic units.  The properties of
  102. task units,  tasks,  and  entries,  and  the  statements  that  affect  the
  103. interaction   between   tasks  (that  is,  entry  call  statements,  accept
  104. statements, delay statements, select statements, and abort statements)  are
  105. described in this chapter.
  106.  
  107. Note:
  108.  
  109. Parallel   tasks  (parallel  logical  processors)  may  be  implemented  on
  110. multicomputers, multiprocessors, or with interleaved execution on a  single
  111. physical  processor.   On  the  other  hand, whenever an implementation can
  112. detect that the same effect can be guaranteed if parts of the actions of  a
  113. given  task  are  executed  by  different  physical  processors  acting  in
  114. parallel, it may choose to execute them in  this  way;   in  such  a  case,
  115. several physical processors implement a single logical processor.
  116.  
  117. References:   abort  statement  9.10, accept statement 9.5, delay statement
  118. 9.6, entry 9.5, entry call statement  9.5,  generic  unit  12,  package  7,
  119. parameter  in  an  entry  call  9.5, program unit 6, rendezvous 9.5, select
  120. statement 9.7, subprogram 6, task body 9.1, task specification 9.1
  121.  
  122.  
  123.  
  124.  
  125. 9.1  Task Specifications and Task Bodies
  126.  
  127.  
  128.  
  129.                                    9 - 1
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138. A task unit consists of a task specification  and  a  task  body.   A  task
  139. specification  that  starts  with  the reserved words  task type declares a
  140. task type.  The value of an object of a task type designates a task  having
  141. the  entries,  if  any, that are declared in the task specification;  these
  142. entries are also called entries of this object.  The execution of the  task
  143. is defined by the corresponding task body.
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.                                    9 - 2
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205. A  task specification without the reserved word type defines a single task.
  206. A task declaration with this form of specification  is  equivalent  to  the
  207. declaration   of  an  anonymous  task  type  immediately  followed  by  the
  208. declaration of an object of the task type, and  the  task  unit  identifier
  209. names the object.  In the remainder of this chapter, explanations are given
  210. in  terms  of  task  type declarations;  the corresponding explanations for
  211. single task declarations follow from the stated equivalence.
  212.  
  213.     task_declaration ::= task_specification;
  214.  
  215.     task_specification ::=
  216.        task [type] identifier [is
  217.           {entry_declaration}
  218.           {representation_clause}
  219.        end [task_simple_name]]
  220.  
  221.     task_body ::=
  222.         task body task_simple_name is
  223.            [declarative_part]
  224.         begin
  225.             sequence_of_statements
  226.        [exception
  227.             exception_handler
  228.            {exception_handler}]
  229.         end [task_simple_name];
  230.  
  231. The simple name at the start of a task  body  must  repeat  the  task  unit
  232. identifier.   Similarly  if  a  simple  name appears at the end of the task
  233. specification or body, it must repeat the task unit identifier.   Within  a
  234. task  body,  the  name  of  the corresponding task unit can also be used to
  235. refer to the task object that designates the task currently  executing  the
  236. body;   furthermore,  the  use  of  this name as a type mark is not allowed
  237. within the task unit itself.
  238.  
  239. For the  elaboration  of  a  task  specification,  entry  declarations  and
  240. representation  clauses,  if  any, are elaborated in the order given.  Such
  241. representation clauses only apply to  the  entries  declared  in  the  task
  242. specification (see 13.5).
  243.  
  244. The  elaboration  of a task body has no other effect than to establish that
  245. the body can from then on be used for the execution of tasks designated  by
  246. objects of the corresponding task type.
  247.  
  248. The  execution of a task body is invoked by the activation of a task object
  249. of the corresponding type (see 9.3).  The optional  exception  handlers  at
  250. the end of a task body handle exceptions raised during the execution of the
  251. sequence of statements of the task body (see 11.4).
  252.  
  253. Examples of specifications of task types:
  254.  
  255.     task type RESOURCE is
  256.        entry SEIZE;
  257.        entry RELEASE;
  258.     end RESOURCE;
  259.  
  260.  
  261.                                    9 - 3
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.     task type KEYBOARD_DRIVER is
  271.        entry READ (C : out CHARACTER);
  272.        entry WRITE(C : in  CHARACTER);
  273.     end KEYBOARD_DRIVER;
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.                                    9 - 4
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336. Examples of specifications of single tasks:
  337.  
  338.     task PRODUCER_CONSUMER is
  339.        entry READ (V : out ITEM);
  340.        entry WRITE(E : in  ITEM);
  341.     end;
  342.  
  343.     task CONTROLLER is
  344.        entry REQUEST(LEVEL)(D : ITEM);  --  a family of entries
  345.     end CONTROLLER;
  346.  
  347.     task USER;  --  has no entries
  348.  
  349. Example of task specification and corresponding body:
  350.  
  351.     task PROTECTED_ARRAY is
  352.        --  INDEX and ITEM are global types
  353.        entry READ (N : in INDEX; V : out ITEM);
  354.        entry WRITE(N : in INDEX; E : in  ITEM);
  355.     end;
  356.  
  357.     task body PROTECTED_ARRAY is
  358.        TABLE : array(INDEX) of ITEM := (INDEX => NULL_ITEM);
  359.     begin
  360.        loop
  361.           select
  362.              accept READ (N : in INDEX; V : out ITEM) do
  363.                 V := TABLE(N);
  364.              end READ;
  365.           or
  366.              accept WRITE(N : in INDEX; E : in  ITEM) do
  367.                 TABLE(N) := E;
  368.              end WRITE;
  369.           end select;
  370.        end loop;
  371.     end PROTECTED_ARRAY;
  372.  
  373. Note:
  374.  
  375. A task specification specifies the interface of tasks of the task type with
  376. other  tasks  of  the  same  or  of different types, and also with the main
  377. program.
  378.  
  379. References:  declaration 3.1, declarative part 3.9, elaboration 3.9,  entry
  380. 9.5,  entry  declaration  9.5, exception handler 11.2, identifier 2.3, main
  381. program 10.1, object 3.2, object declaration 3.2.1,  representation  clause
  382. 13.1,  reserved word 2.9, sequence of statements 5.1, simple name 4.1, type
  383. 3.3, type declaration 3.3.1
  384.  
  385.  
  386.  
  387.  
  388.  
  389. 9.2  Task Types and Task Objects
  390.  
  391.  
  392.  
  393.                                    9 - 5
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402. A task type is a limited type (see 7.4.4).  Hence  neither  assignment  nor
  403. the  predefined  comparison  for  equality  and  inequality are defined for
  404. objects of task types;  moreover, the mode out is not allowed for a  formal
  405. parameter whose type is a task type.
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.                                    9 - 6
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469. A  task object is an object whose type is a task type.  The value of a task
  470. object designates a task that has the entries  of  the  corresponding  task
  471. type,  and whose execution is specified by the corresponding task body.  If
  472. a task object is the object, or a subcomponent of the object,  declared  by
  473. an  object declaration, then the value of the task object is defined by the
  474. elaboration of the object declaration.  If a task object is the object,  or
  475. a  subcomponent  of  the object, created by the evaluation of an allocator,
  476. then the value of the task object is  defined  by  the  evaluation  of  the
  477. allocator.   For  all  parameter modes, if an actual parameter designates a
  478. task, the associated formal parameter designates the same task;   the  same
  479. holds  for  a  subcomponent  of  an  actual parameter and the corresponding
  480. subcomponent of the associated formal parameter;  finally, the  same  holds
  481. for generic parameters.
  482.  
  483. Examples:
  484.  
  485.     CONTROL  : RESOURCE;
  486.     TELETYPE : KEYBOARD_DRIVER;
  487.     POOL     : array(1 .. 10) of KEYBOARD_DRIVER;
  488.     --  see also examples of declarations of single tasks in 9.1
  489.  
  490. Example of access type designating task objects:
  491.  
  492.     type KEYBOARD is access KEYBOARD_DRIVER;
  493.  
  494.     TERMINAL : KEYBOARD := new KEYBOARD_DRIVER;
  495.  
  496. Notes:
  497.  
  498. Since  a  task type is a limited type, it can appear as the definition of a
  499. limited private type in a private part, and as a generic  actual  parameter
  500. associated  with  a  formal parameter whose type is a limited type.  On the
  501. other hand, the type of a generic formal parameter of mode in must not be a
  502. limited type and hence cannot be a task type.
  503.  
  504. Task objects behave as constants (a task object always designates the  same
  505. task)  since  their  values are implicitly defined either at declaration or
  506. allocation, or by a parameter  association,  and  since  no  assignment  is
  507. available.   However  the  reserved  word  constant  is  not allowed in the
  508. declaration  of  a  task  object  since  this  would  require  an  explicit
  509. initialization.   A  task object that is a formal parameter of mode in is a
  510. constant (as is any formal parameter of this mode).
  511.  
  512. If an application needs to store and exchange task identities, it can do so
  513. by defining an access type designating the corresponding task  objects  and
  514. by  using  access  values  for identification purposes (see above example).
  515. Assignment is available for such an access type as for any access type.
  516.  
  517. Subtype declarations are allowed for task types as  for  other  types,  but
  518. there are no constraints applicable to task types.
  519.  
  520. References:   access  type  3.8,  actual  parameter  6.4.1,  allocator 4.8,
  521. assignment 5.2, component declaration 3.7,  composite  type  3.3,  constant
  522. 3.2.1,  constant  declaration  3.2.1,  constraint  3.3,  designate 3.8 9.1,
  523.  
  524.  
  525.                                    9 - 7
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534. elaboration 3.9, entry 9.5, equality operator 4.5.2, formal parameter  6.2,
  535. formal   parameter   mode  6.2,  generic  actual  parameter  12.3,  generic
  536. association 12.3, generic formal parameter 12.1, generic  formal  parameter
  537. mode  12.1.1,  generic  unit  12, inequality operator 4.5.2, initialization
  538. 3.2.1, limited type 7.4.4, object 3.2, object declaration 3.2.1,  parameter
  539. association  6.4,  private  part  7.2, private type 7.4, reserved word 2.9,
  540. subcomponent 3.3, subprogram 6, subtype declaration 3.3.2, task  body  9.1,
  541. type 3.3
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.                                    9 - 8
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600. 9.3  Task Execution - Task Activation
  601.  
  602.  
  603. A  task body defines the execution of any task that is designated by a task
  604. object of the corresponding task type.  The initial part of this  execution
  605. is  called  the  activation  of  the  task  object,  and  also  that of the
  606. designated task;  it consists of the elaboration of the  declarative  part,
  607. if  any, of the task body.  The execution of different tasks, in particular
  608. their activation, proceeds in parallel.
  609.  
  610. If an object declaration that declares a  task  object  occurs  immediately
  611. within  a  declarative  part, then the activation of the task object starts
  612. after the elaboration of the declarative part (that is, after  passing  the
  613. reserved  word  begin following the declarative part);  similarly if such a
  614. declaration  occurs  immediately  within  a  package   specification,   the
  615. activation  starts  after  the  elaboration  of the declarative part of the
  616. package body.  The same holds for the activation of a task object that is a
  617. subcomponent of an object declared immediately within a declarative part or
  618. package specification.  The first statement following the declarative  part
  619. is  executed only after conclusion of the activation of these task objects.
  620.  
  621. Should an exception be raised by the activation of one of these tasks, that
  622. task becomes a completed task (see 9.4);   other  tasks  are  not  directly
  623. affected.   Should  one  of  these  tasks  thus become completed during its
  624. activation, the exception TASKING_ERROR is raised upon  conclusion  of  the
  625. activation  of  all  of  these  tasks  (whether  successfully or not);  the
  626. exception is raised at  a  place  that  is  immediately  before  the  first
  627. statement  following  the  declarative part (immediately after the reserved
  628. word begin).  Should several of these tasks thus  become  completed  during
  629. their activation, the exception TASKING_ERROR is raised only once.
  630.  
  631. Should  an  exception be raised by the elaboration of a declarative part or
  632. package  specification,  then  any  task  that  is  created  (directly   or
  633. indirectly)  by  this  elaboration  and  that  is not yet activated becomes
  634. terminated and is therefore  never  activated  (see  section  9.4  for  the
  635. definition of a terminated task).
  636.  
  637. For  the  above  rules,  in  any  package  body  without statements, a null
  638. statement is assumed.  For any package without a package body, an  implicit
  639. package  body  containing a single null statement is assumed.  If a package
  640. without a package body is declared immediately within some program unit  or
  641. block  statement,  the  implicit  package  body  occurs  at  the end of the
  642. declarative part of the program unit or  block  statement;   if  there  are
  643. several  such  packages,  the  order  of  the  implicit  package  bodies is
  644. undefined.
  645.  
  646. A task object that is the object, or a subcomponent of the object,  created
  647. by  the  evaluation  of  an allocator is activated by this evaluation.  The
  648. activation starts after any initialization for the object  created  by  the
  649. allocator;   if  several subcomponents are task objects, they are activated
  650. in parallel.  The access value designating such an object  is  returned  by
  651. the allocator only after the conclusion of these activations.
  652.  
  653. Should an exception be raised by the activation of one of these tasks, that
  654. task  becomes  a  completed  task;   other tasks are not directly affected.
  655.  
  656.  
  657.                                    9 - 9
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666. Should one of these tasks thus become completed during its activation,  the
  667. exception  TASKING_ERROR is raised upon conclusion of the activation of all
  668. of these tasks (whether successfully or not);  the exception is  raised  at
  669. the  place where the allocator is evaluated.  Should several of these tasks
  670. thus become completed during their activation, the exception  TASKING_ERROR
  671. is raised only once.
  672.  
  673. Should  an  exception be raised by the initialization of the object created
  674. by an allocator (hence before  the  start  of  any  activation),  any  task
  675. designated  by  a  subcomponent  of  this  object becomes terminated and is
  676. therefore never activated.
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.                                   9 - 10
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733. Example:
  734.  
  735.     procedure P is
  736.        A, B : RESOURCE;  --  elaborate the task objects A, B
  737.        C    : RESOURCE;  --  elaborate the task object C
  738.     begin
  739.        --  the tasks A, B, C are activated in parallel before the first statement
  740.        ...
  741.     end;
  742.  
  743. Notes:
  744.  
  745. An entry of a task can be called before the task has  been  activated.   If
  746. several  tasks  are  activated  in  parallel, the execution of any of these
  747. tasks need not await the end of the activation  of the other tasks.  A task
  748. may become completed during its activation either because of  an  exception
  749. or because it is aborted (see 9.10).
  750.  
  751. References:   allocator  4.8,  completed  task  9.4,  declarative part 3.9,
  752. elaboration 3.9, entry 9.5,  exception  11,  handling  an  exception  11.4,
  753. package body 7.1, parallel execution 9, statement 5, subcomponent 3.3, task
  754. body   9.1,   task  object  9.2,  task  termination  9.4,  task  type  9.1,
  755. tasking_error exception 11.1
  756.  
  757.  
  758.  
  759.  
  760. 9.4  Task Dependence - Termination of Tasks
  761.  
  762.  
  763. Each task depends on at least one master.  A master is a construct that  is
  764. either  a  task,  a currently executing block statement or subprogram, or a
  765. library package (a package declared within another program unit  is  not  a
  766. master).   The  dependence  on  a  master  is  a  direct  dependence in the
  767. following two cases:
  768.  
  769. (a)  The task designated by  a  task  object  that  is  the  object,  or  a
  770.      subcomponent  of the object, created by the evaluation of an allocator
  771.      depends on the master that elaborates the  corresponding  access  type
  772.      definition.
  773.  
  774. (b)  The task designated by any other task object  depends  on  the  master
  775.      whose execution creates the task object.
  776.  
  777. Furthermore,  if a task depends on a given master that is a block statement
  778. executed by another master, then  the  task  depends  also  on  this  other
  779. master,  in  an  indirect  manner;  the same holds if the given master is a
  780. subprogram called by another master, and if the given master is a task that
  781. depends (directly or indirectly) on another master.  Dependences exist  for
  782. objects  of  a  private  type  whose full declaration is in terms of a task
  783. type.
  784.  
  785. A task is said to have completed its execution when  it  has  finished  the
  786. execution  of  the  sequence  of statements that appears after the reserved
  787.  
  788.  
  789.                                   9 - 11
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798. word  begin in the corresponding body.  Similarly a block or  a  subprogram
  799. is  said to have completed its execution when it has finished the execution
  800. of the corresponding sequence of statements.  For a  block  statement,  the
  801. execution  is also said to be completed when it reaches an exit, return, or
  802. goto statement transferring control out of the block.  For a procedure, the
  803. execution is  also  said  to  be  completed  when  a  corresponding  return
  804. statement  is  reached.   For  a function, the execution is also said to be
  805. completed after the  evaluation  of  the  result  expression  of  a  return
  806. statement.  Finally the execution of a task, block statement, or subprogram
  807. is  completed if an exception is raised by the execution of its sequence of
  808. statements and there is no corresponding handler, or, if there is one, when
  809. it has finished the execution of the corresponding handler.
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.                                   9 - 12
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865. If a task has no dependent task, its termination takes place  when  it  has
  866. completed  its  execution.   After  its  termination,  a task is said to be
  867. terminated.  If a task has dependent tasks,  its  termination  takes  place
  868. when  the  execution  of  the task is completed and all dependent tasks are
  869. terminated.  A block  statement  or  subprogram  body  whose  execution  is
  870. completed is not left until all of its dependent tasks are terminated.
  871.  
  872. Termination  of  a  task otherwise takes place if and only if its execution
  873. has reached an open  terminate  alternative  in  a  select  statement  (see
  874. 9.7.1), and the following conditions are satisfied:
  875.  
  876.   -  The task depends on some master whose execution  is  completed  (hence
  877.      not a library package).
  878.  
  879.   -  Each task that depends on the  master  considered  is  either  already
  880.      terminated  or similarly waiting on an open terminate alternative of a
  881.      select statement.
  882.  
  883. When both conditions are satisfied, the task considered becomes terminated,
  884. together with all tasks that depend on the master considered.
  885.  
  886. Example:
  887.  
  888.     declare
  889.        type GLOBAL is access RESOURCE;          --  see 9.1
  890.        A, B : RESOURCE;
  891.        G    : GLOBAL;
  892.     begin
  893.        --  activation of A and B
  894.        declare
  895.           type LOCAL is access RESOURCE;
  896.           X : GLOBAL := new RESOURCE;  --  activation of X.all
  897.           L : LOCAL  := new RESOURCE;  --  activation of L.all
  898.           C : RESOURCE;
  899.        begin
  900.           --  activation of C
  901.           G := X;  --  both G and X designate the same task object
  902.           ...
  903.        end;  --  await termination of C and L.all (but not X.all)
  904.        ...
  905.     end;  --  await termination of A, B, and G.all
  906.  
  907. Notes:
  908.  
  909. The rules given for termination imply that all tasks that depend  (directly
  910. or  indirectly)  on a given master and that are not already terminated, can
  911. be terminated (collectively) if and only if each of them is waiting  on  an
  912. open  terminate  alternative of a select statement and the execution of the
  913. given master is completed.
  914.  
  915. The usual rules apply to the main program.   Consequently,  termination  of
  916. the  main  program  awaits  termination  of  any dependent task even if the
  917. corresponding task type is declared in a library  package.   On  the  other
  918. hand,  termination  of the main program does not await termination of tasks
  919.  
  920.  
  921.                                   9 - 13
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930. that depend on library packages;  the language does not define whether such
  931. tasks are required to terminate.
  932.  
  933. For an access type derived from  another  access  type,  the  corresponding
  934. access  type  definition  is that of the parent type;  the dependence is on
  935. the master that elaborates the ultimate parent access type definition.
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.                                   9 - 14
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997. A renaming declaration defines a new name for an existing entity and  hence
  998. creates no further dependence.
  999.  
  1000. References:    access   type  3.8,  allocator  4.8,  block  statement  5.6,
  1001. declaration 3.1, designate 3.8 9.1, exception 11, exception  handler  11.2,
  1002. exit  statement  5.7,  function 6.5, goto statement 5.9, library unit 10.1,
  1003. main program 10.1, object 3.2, open alternative 9.7.1, package  7,  program
  1004. unit  6,  renaming  declaration  8.5,  return statement 5.8, selective wait
  1005. 9.7.1,  sequence  of  statements  5.1,  statement  5,   subcomponent   3.3,
  1006. subprogram  body  6.3, subprogram call 6.4, task body 9.1, task object 9.2,
  1007. terminate alternative 9.7.1
  1008.  
  1009.  
  1010.  
  1011.  
  1012. 9.5  Entries, Entry Calls, and Accept Statements
  1013.  
  1014.  
  1015. Entry calls and accept statements are the primary means of  synchronization
  1016. of  tasks, and of communicating values between tasks.  An entry declaration
  1017. is similar to a subprogram declaration  and  is  only  allowed  in  a  task
  1018. specification.   The  actions  to  be performed when an entry is called are
  1019. specified by corresponding accept statements.
  1020.  
  1021.     entry_declaration ::=
  1022.        entry identifier [(discrete_range)] [formal_part];
  1023.  
  1024.     entry_call_statement ::= entry_name [actual_parameter_part];
  1025.  
  1026.     accept_statement ::=
  1027.        accept entry_simple_name [(entry_index)] [formal_part] [do
  1028.           sequence_of_statements
  1029.        end [entry_simple_name]];
  1030.  
  1031.     entry_index ::= expression
  1032.  
  1033. An entry declaration that includes a discrete range (see 3.6.1) declares  a
  1034. family  of distinct entries having the same formal part (if any);  that is,
  1035. one such entry for each value of the discrete range.  The term single entry
  1036. is used in the definition of any rule that applies to any entry other  than
  1037. one  of  a family.  The task designated by an object of a task type has (or
  1038. owns) the entries declared in the specification of the task type.
  1039.  
  1040. Within the body of a task, each of its single entries or entry families can
  1041. be named by the corresponding simple name.  The  name  of  an  entry  of  a
  1042. family takes the form of an indexed component, the family simple name being
  1043. followed  by  the index in parentheses;  the type of this index must be the
  1044. same as that of the  discrete  range  in  the  corresponding  entry  family
  1045. declaration.   Outside  the  body of a task an entry name has the form of a
  1046. selected component,  whose  prefix  denotes  the  task  object,  and  whose
  1047. selector is the simple name of one of its single entries or entry families.
  1048.  
  1049. A  single  entry overloads a subprogram, an enumeration literal, or another
  1050. single entry if they have the same identifier.  Overloading is not  defined
  1051.  
  1052.  
  1053.                                   9 - 15
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062. for  entry  families.  A single entry or an entry of an entry family can be
  1063. renamed as a procedure as explained in section 8.5.
  1064.  
  1065. The parameter modes defined for parameters of the formal part of  an  entry
  1066. declaration  are the same as for a subprogram declaration and have the same
  1067. meaning (see 6.2).  The syntax of an entry call  statement  is  similar  to
  1068. that   of   a  procedure  call  statement,  and  the  rules  for  parameter
  1069. associations are the same as for subprogram calls (see 6.4.1 and 6.4.2).
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.                                   9 - 16
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129. An accept statement specifies the actions to be performed at a  call  of  a
  1130. named entry (it can be an entry of a family).  The formal part of an accept
  1131. statement  must  conform to the formal part given in the declaration of the
  1132. single entry or entry family named by the  accept  statement  (see  section
  1133. 6.3.1  for  the conformance rules).  If a simple name appears at the end of
  1134. an accept statement, it must repeat that given at the start.
  1135.  
  1136. An accept statement for an entry of a given task is only allowed within the
  1137. corresponding task body;  excluding within the body  of  any  program  unit
  1138. that  is,  itself,  inner  to  the task body;  and excluding within another
  1139. accept statement for either the same single entry or an entry of  the  same
  1140. family.   (One  consequence  of this rule is that a task can execute accept
  1141. statements only for its own entries.)  A task body can  contain  more  than
  1142. one accept statement for the same entry.
  1143.  
  1144. For the elaboration of an entry declaration, the discrete range, if any, is
  1145. evaluated  and  the  formal  part,  if  any,  is  then  elaborated as for a
  1146. subprogram declaration.
  1147.  
  1148. Execution of an accept statement starts with the evaluation  of  the  entry
  1149. index  (in  the  case of an entry of a family).  Execution of an entry call
  1150. statement starts with the evaluation of the entry name;  this  is  followed
  1151. by any evaluations required for actual parameters in the same manner as for
  1152. a  subprogram call (see 6.4).  Further execution of an accept statement and
  1153. of a corresponding entry call statement are synchronized.
  1154.  
  1155. If a given entry is called by only one task, there are  two  possibilities:
  1156.  
  1157.   -  If  the  calling  task  issues  an  entry  call  statement  before   a
  1158.      corresponding  accept  statement  is  reached  by  the task owning the
  1159.      entry, the execution of the calling task is suspended.
  1160.  
  1161.   -  If a task reaches an accept statement prior to any call of that entry,
  1162.      the execution of the task is suspended until such a call is  received.
  1163.  
  1164. When an entry has been called and a corresponding accept statement has been
  1165. reached,  the  sequence  of  statements, if any, of the accept statement is
  1166. executed by the called task (while the  calling  task  remains  suspended).
  1167. This  interaction is called a rendezvous.  Thereafter, the calling task and
  1168. the task owning the entry continue their execution in parallel.
  1169.  
  1170. If several  tasks  call  the  same  entry  before  a  corresponding  accept
  1171. statement  is reached, the calls are queued;  there is one queue associated
  1172. with each entry.  Each execution of an accept statement  removes  one  call
  1173. from the queue.  The calls are processed in the order of arrival.
  1174.  
  1175. An  attempt  to  call  an  entry of a task that has completed its execution
  1176. raises the exception TASKING_ERROR at the point of the call, in the calling
  1177. task;  similarly, this exception is raised at the point of the call if  the
  1178. called  task  completes  its  execution before accepting the call (see also
  1179. 9.10 for the case when the called task becomes  abnormal).   The  exception
  1180. CONSTRAINT_ERROR  is  raised  if  the  index of an entry of a family is not
  1181. within the specified discrete range.
  1182.  
  1183.  
  1184.  
  1185.                                   9 - 17
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194. Examples of entry declarations:
  1195.  
  1196.     entry READ(V : out ITEM);
  1197.     entry SEIZE;
  1198.     entry REQUEST(LEVEL)(D : ITEM);  --  a family of entries
  1199.  
  1200. Examples of entry calls:
  1201.  
  1202.     CONTROL.RELEASE;                      --  see 9.2 and 9.1
  1203.     PRODUCER_CONSUMER.WRITE(E);           --  see 9.1
  1204.     POOL(5).READ(NEXT_CHAR);              --  see 9.2 and 9.1
  1205.     CONTROLLER.REQUEST(LOW)(SOME_ITEM);   --  see 9.1
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.                                   9 - 18
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260. Examples of accept statements:
  1261.  
  1262.     accept SEIZE;
  1263.  
  1264.     accept READ(V : out ITEM) do
  1265.        V := LOCAL_ITEM;
  1266.     end READ;
  1267.  
  1268.     accept REQUEST(LOW)(D : ITEM) do
  1269.        ...
  1270.     end REQUEST;
  1271.  
  1272. Notes:
  1273.  
  1274. The formal part given in an accept statement is not elaborated; it is  only
  1275. used to identify the corresponding entry.
  1276.  
  1277. An  accept  statement   can  call  subprograms  that issue entry calls.  An
  1278. accept statement need not  have  a  sequence  of  statements  even  if  the
  1279. corresponding  entry  has  parameters.   Equally, it can have a sequence of
  1280. statements even if the corresponding entry has no parameters.  The sequence
  1281. of statements of an accept statement can include return statements.  A task
  1282. can call its own entries but it will, of course,  deadlock.   The  language
  1283. permits  conditional  and  timed  entry  calls  (see 9.7.2 and 9.7.3).  The
  1284. language rules ensure that a task can only be in one entry queue at a given
  1285. time.
  1286.  
  1287. If the bounds of  the  discrete  range  of  an  entry  family  are  integer
  1288. literals,  the  index (in an entry name or accept statement) must be of the
  1289. predefined type INTEGER (see 3.6.1).
  1290.  
  1291. References:  abnormal task 9.10, actual parameter part 6.4, completed  task
  1292. 9.4,    conditional    entry   call   9.7.2,   conformance   rules   6.3.1,
  1293. constraint_error exception  11.1,  designate  9.1,  discrete  range  3.6.1,
  1294. elaboration  3.1 3.9, enumeration literal 3.5.1, evaluation 4.5, expression
  1295. 4.4, formal part 6.1, identifier 2.3, indexed component 4.1.1, integer type
  1296. 3.5.4, name 4.1, object 3.2, overloading 6.6  8.7,  parallel  execution  9,
  1297. prefix  4.1,  procedure  6,  procedure  call 6.4, renaming declaration 8.5,
  1298. return statement 5.8, scope 8.2, selected component 4.1.3, selector  4.1.3,
  1299. sequence  of  statements  5.1,  simple  expression  4.4,  simple  name 4.1,
  1300. subprogram 6, subprogram body 6.3, subprogram declaration 6.1, task 9, task
  1301. body 9.1, task specification 9.1, tasking_error exception 11.1, timed entry
  1302. call 9.7.3
  1303.  
  1304.  
  1305.  
  1306. 9.6  Delay Statements, Duration, and Time
  1307.  
  1308.  
  1309. The execution of a delay statement evaluates  the  simple  expression,  and
  1310. suspends  further  execution of the task that executes the delay statement,
  1311. for at least the duration specified by the resulting value.
  1312.  
  1313.     delay_statement ::= delay simple_expression;
  1314.  
  1315.  
  1316.  
  1317.                                   9 - 19
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326. The simple expression must be of the predefined fixed point type  DURATION;
  1327. its value is expressed in seconds;  a delay statement with a negative value
  1328. is equivalent to a delay statement with a zero value.
  1329.  
  1330. Any  implementation  of  the  type  DURATION  must  allow representation of
  1331. durations (both positive and negative) up to at least  86400  seconds  (one
  1332. day);   the  smallest  representable  duration,  DURATION'SMALL must not be
  1333. greater than twenty milliseconds (whenever possible, a  value  not  greater
  1334. than  fifty  microseconds should be chosen).  Note that DURATION'SMALL need
  1335. not correspond to the basic clock cycle, the named number SYSTEM.TICK  (see
  1336. 13.7).
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.                                   9 - 20
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393. The  definition  of  the  type  TIME  is provided in the predefined library
  1394. package CALENDAR.  The function CLOCK returns the current value of TIME  at
  1395. the  time  it is called.  The functions YEAR, MONTH, DAY and SECONDS return
  1396. the corresponding values for a given value of the type TIME;  the procedure
  1397. SPLIT returns all four  corresponding  values.   Conversely,  the  function
  1398. TIME_OF  combines  a  year  number,  a  month  number,  a day number, and a
  1399. duration, into a value of  type  TIME.   The  operators  "+"  and  "-"  for
  1400. addition  and  subtraction  of  times  and  durations,  and  the relational
  1401. operators for times, have the conventional meaning.
  1402.  
  1403. The exception TIME_ERROR is raised by the function TIME_OF  if  the  actual
  1404. parameters do not form a proper date.  This exception is also raised by the
  1405. operators  "+"  and  "-" if, for the given operands, these operators cannot
  1406. return a date whose year number  is  in  the  range  of  the  corresponding
  1407. subtype, or if the operator "-" cannot return a result that is in the range
  1408. of the type DURATION.
  1409.  
  1410.     package CALENDAR is
  1411.        type TIME is private;
  1412.  
  1413.        subtype YEAR_NUMBER  is INTEGER  range 1901 .. 2099;
  1414.        subtype MONTH_NUMBER is INTEGER  range 1 .. 12;
  1415.        subtype DAY_NUMBER   is INTEGER  range 1 .. 31;
  1416.        subtype DAY_DURATION is DURATION range 0.0 .. 86_400.0;
  1417.  
  1418.        function CLOCK return TIME;
  1419.  
  1420.        function YEAR   (DATE : TIME) return YEAR_NUMBER;
  1421.        function MONTH  (DATE : TIME) return MONTH_NUMBER;
  1422.        function DAY    (DATE : TIME) return DAY_NUMBER;
  1423.        function SECONDS(DATE : TIME) return DAY_DURATION;
  1424.  
  1425.        procedure SPLIT (DATE    : in  TIME;
  1426.                         YEAR    : out YEAR_NUMBER;
  1427.                         MONTH   : out MONTH_NUMBER;
  1428.                         DAY     : out DAY_NUMBER;
  1429.                         SECONDS : out DAY_DURATION);
  1430.  
  1431.        function TIME_OF(YEAR    : YEAR_NUMBER;
  1432.                         MONTH   : MONTH_NUMBER;
  1433.                         DAY     : DAY_NUMBER;
  1434.                         SECONDS : DAY_DURATION := 0.0) return TIME;
  1435.  
  1436.  
  1437.        function "+"  (LEFT : TIME;     RIGHT : DURATION) return TIME;
  1438.        function "+"  (LEFT : DURATION; RIGHT : TIME)     return TIME;
  1439.        function "-"  (LEFT : TIME;     RIGHT : DURATION) return TIME;
  1440.        function "-"  (LEFT : TIME;     RIGHT : TIME)     return DURATION;
  1441.  
  1442.        function "<"  (LEFT, RIGHT : TIME) return BOOLEAN;
  1443.        function "<=" (LEFT, RIGHT : TIME) return BOOLEAN;
  1444.        function ">"  (LEFT, RIGHT : TIME) return BOOLEAN;
  1445.        function ">=" (LEFT, RIGHT : TIME) return BOOLEAN;
  1446.  
  1447.  
  1448.  
  1449.                                   9 - 21
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457.  
  1458.        TIME_ERROR : exception;  --  can be raised by TIME_OF, "+", and "-"
  1459.  
  1460.     private
  1461.        -- implementation-dependent
  1462.     end;
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494.  
  1495.  
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.                                   9 - 22
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524. Examples:
  1525.  
  1526.     delay 3.0;  --  delay 3.0 seconds
  1527.  
  1528.     declare
  1529.        use CALENDAR;
  1530.        --  INTERVAL is a global constant of type DURATION
  1531.        NEXT_TIME : TIME := CLOCK + INTERVAL;
  1532.     begin
  1533.        loop
  1534.           delay NEXT_TIME - CLOCK;
  1535.           --  some actions
  1536.           NEXT_TIME := NEXT_TIME + INTERVAL;
  1537.        end loop;
  1538.     end;
  1539.  
  1540. Notes:
  1541.  
  1542. The second example causes the loop to be repeated every INTERVAL seconds on
  1543. average.    This   interval  between  two  successive  iterations  is  only
  1544. approximate.  However, there will be no cumulative drift  as  long  as  the
  1545. duration of each iteration is (sufficiently) less than INTERVAL.
  1546.  
  1547.  
  1548. References:   adding  operator  4.5,  duration  C,  fixed point type 3.5.9,
  1549. function call 6.4, library unit 10.1, operator 4.5, package 7, private type
  1550. 7.4, relational operator 4.5, simple expression 4.4, statement 5,  task  9,
  1551. type 3.3
  1552.  
  1553.  
  1554.  
  1555.  
  1556. 9.7  Select Statements
  1557.  
  1558.  
  1559. There  are three forms of select statements.  One form provides a selective
  1560. wait for one or more alternatives.  The other two provide  conditional  and
  1561. timed entry calls.
  1562.  
  1563.     select_statement ::= selective_wait
  1564.        | conditional_entry_call | timed_entry_call
  1565.  
  1566.  
  1567. References:   selective  wait  9.7.1,  conditional  entry call 9.7.2, timed
  1568. entry call 9.7.3
  1569.  
  1570.  
  1571.  
  1572.  
  1573. 9.7.1  Selective Waits
  1574.  
  1575.  
  1576. This form of the select statement allows a combination of waiting for,  and
  1577. selecting  from,  one  or  more  alternatives.  The selection can depend on
  1578. conditions associated with each alternative of the selective wait.
  1579.  
  1580.  
  1581.                                   9 - 23
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.     selective_wait ::=
  1591.         select
  1592.           select_alternative
  1593.        {or
  1594.           select_alternative}
  1595.        [else
  1596.           sequence_of_statements]
  1597.         end select;
  1598.  
  1599.     select_alternative ::=
  1600.        [when condition =>]
  1601.           selective_wait_alternative
  1602.  
  1603.     selective_wait_alternative ::= accept_alternative
  1604.        | delay_alternative | terminate_alternative
  1605.  
  1606.     accept_alternative ::= accept_statement [sequence_of_statements]
  1607.  
  1608.     delay_alternative  ::= delay_statement  [sequence_of_statements]
  1609.  
  1610.     terminate_alternative ::= terminate;
  1611.  
  1612. A selective wait must contain at least one accept alternative.  In addition
  1613. a selective wait can contain either a terminate alternative (only one),  or
  1614. one or more delay alternatives, or an else part;  these three possibilities
  1615. are mutually exclusive.
  1616.  
  1617. A  select alternative is said to be open if it does not start with when and
  1618. a condition, or if the  condition  is  TRUE.   It  is  said  to  be  closed
  1619. otherwise.
  1620.  
  1621. For  the execution of a selective wait, any conditions specified after when
  1622. are evaluated in some order that is not  defined  by  the  language;   open
  1623. alternatives are thus determined.  For an open delay alternative, the delay
  1624. expression  is  also  evaluated.  Similarly, for an open accept alternative
  1625. for an entry of a family, the entry index is also evaluated.  Selection and
  1626. execution of one open alternative, or of the else part, then completes  the
  1627. execution  of  the  selective  wait;   the  rules  for  this  selection are
  1628. described below.
  1629.  
  1630. Open accept alternatives are  first  considered.   Selection  of  one  such
  1631. alternative  takes  place  immediately  if  a  corresponding  rendezvous is
  1632. possible, that is, if there is a corresponding entry call issued by another
  1633. task and waiting to be accepted.   If  several  alternatives  can  thus  be
  1634. selected,  one  of them is selected arbitrarily (that is, the language does
  1635. not  define  which  one).   When  such  an  alternative  is  selected,  the
  1636. corresponding  accept  statement  and  possible  subsequent  statements are
  1637. executed.  If no rendezvous is immediately possible and there  is  no  else
  1638. part,  the  task  waits  until  an  open  selective wait alternative can be
  1639. selected.
  1640.  
  1641. Selection of the other forms of alternative or of an else part is performed
  1642. as follows:
  1643.  
  1644.  
  1645.  
  1646.  
  1647.                                   9 - 24
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.   -  An open delay alternative will be selected if  no  accept  alternative
  1657.      can  be  selected before the specified delay has elapsed (immediately,
  1658.      for a negative or zero delay in the absence of  queued  entry  calls);
  1659.      any  subsequent  statements  of the alternative are then executed.  If
  1660.      several delay alternatives can thus be selected (that is, if they have
  1661.      the same delay), one of them is selected arbitrarily.
  1662.  
  1663.   -  The else part is selected and its statements are executed if no accept
  1664.      alternative  can  be  immediately  selected,  in  particular,  if  all
  1665.      alternatives are closed.
  1666.  
  1667.   -  An open terminate alternative is selected if the conditions stated  in
  1668.      section  9.4 are satisfied.  It is a consequence of other rules that a
  1669.      terminate alternative cannot be selected while there is a queued entry
  1670.      call for any entry of the task.
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.                                   9 - 25
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722. The exception PROGRAM_ERROR is raised if all alternatives  are  closed  and
  1723. there is no else part.
  1724.  
  1725. Examples of a select statement:
  1726.  
  1727.     select
  1728.        accept DRIVER_AWAKE_SIGNAL;
  1729.     or
  1730.        delay 30.0*SECONDS;
  1731.        STOP_THE_TRAIN;
  1732.     end select;
  1733.  
  1734. Example of a task body with a select statement:
  1735.  
  1736.     task body RESOURCE is
  1737.        BUSY : BOOLEAN := FALSE;
  1738.     begin
  1739.        loop
  1740.           select
  1741.              when not BUSY =>
  1742.                 accept SEIZE do
  1743.                    BUSY := TRUE;
  1744.                 end;
  1745.           or
  1746.              accept RELEASE do
  1747.                 BUSY := FALSE;
  1748.              end;
  1749.           or
  1750.              terminate;
  1751.           end select;
  1752.        end loop;
  1753.     end RESOURCE;
  1754.  
  1755. Notes:
  1756.  
  1757. A  selective  wait  is  allowed to have several open delay alternatives.  A
  1758. selective wait is allowed to have several open accept alternatives for  the
  1759. same entry.
  1760.  
  1761. References:   accept  statement  9.5, condition 5.3, declaration 3.1, delay
  1762. expression 9.6, delay statement 9.6, duration 9.6, entry  9.5,  entry  call
  1763. 9.5,  entry index 9.5, program_error exception 11.1, queued entry call 9.5,
  1764. rendezvous 9.5, select statement 9.7, sequence of statements 5.1, task 9
  1765.  
  1766.  
  1767.  
  1768.  
  1769. 9.7.2  Conditional Entry Calls
  1770.  
  1771.  
  1772. A conditional entry call issues an entry call that is then  canceled  if  a
  1773. rendezvous is not immediately possible.
  1774.  
  1775.     conditional_entry_call ::=
  1776.        select
  1777.  
  1778.  
  1779.                                   9 - 26
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.            entry_call_statement
  1789.           [sequence_of_statements]
  1790.        else
  1791.            sequence_of_statements
  1792.        end select;
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.  
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.                                   9 - 27
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854. For  the  execution  of  a  conditional entry call, the entry name is first
  1855. evaluated.  This  is  followed  by  any  evaluations  required  for  actual
  1856. parameters as in the case of a subprogram call (see 6.4).
  1857.  
  1858. The  entry  call  is  canceled  if the execution of the called task has not
  1859. reached a point where it is ready to accept the call (that  is,  either  an
  1860. accept statement for the corresponding entry, or a select statement with an
  1861. open  accept alternative for the entry), or if there are prior queued entry
  1862. calls for this entry.  If the called task has reached a  select  statement,
  1863. the  entry  call is canceled if an accept alternative for this entry is not
  1864. selected.
  1865.  
  1866. If the entry call  is  canceled,  the  statements  of  the  else  part  are
  1867. executed.   Otherwise,  the  rendezvous  takes  place;   and  the  optional
  1868. sequence of statements after the entry call is then executed.
  1869.  
  1870. The  execution  of  a  conditional  entry   call   raises   the   exception
  1871. TASKING_ERROR  if  the called task has already completed its execution (see
  1872. also 9.10 for the case when the called task becomes abnormal).
  1873.  
  1874. Example:
  1875.  
  1876.     procedure SPIN(R : RESOURCE) is
  1877.     begin
  1878.        loop
  1879.           select
  1880.              R.SEIZE;
  1881.              return;
  1882.           else
  1883.              null;  --  busy waiting
  1884.           end select;
  1885.        end loop;
  1886.     end;
  1887.  
  1888. References:  abnormal task 9.10, accept  statement  9.5,  actual  parameter
  1889. part  6.4,  completed task 9.4, entry call statement 9.5, entry family 9.5,
  1890. entry index 9.5, evaluation 4.5, expression 4.4,  open  alternative  9.7.1,
  1891. queued  entry  call  9.5, rendezvous 9.5, select statement 9.7, sequence of
  1892. statements 5.1, task 9, tasking_error exception 11.1
  1893.  
  1894.  
  1895.  
  1896.  
  1897. 9.7.3  Timed Entry Calls
  1898.  
  1899.  
  1900. A timed entry call issues an entry call that is canceled if a rendezvous is
  1901. not started within a given delay.
  1902.  
  1903.     timed_entry_call ::=
  1904.        select
  1905.            entry_call_statement
  1906.           [sequence_of_statements]
  1907.        or
  1908.            delay_alternative
  1909.  
  1910.  
  1911.                                   9 - 28
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.        end select;
  1921.  
  1922.  
  1923.  
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.                                   9 - 29
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986. For the execution of a timed entry call, the entry name is first evaluated.
  1987. This is followed by any evaluations required for actual  parameters  as  in
  1988. the  case of a subprogram call (see 6.4).  The expression stating the delay
  1989. is then evaluated, and the entry call is finally issued.
  1990.  
  1991. If  a  rendezvous  can  be  started  within  the  specified  duration   (or
  1992. immediately,  as  for  a  conditional  entry  call,  for a negative or zero
  1993. delay), it is performed and the optional sequence of statements  after  the
  1994. entry  call  is  then executed.  Otherwise, the entry call is canceled when
  1995. the specified duration has expired, and the optional sequence of statements
  1996. of the delay alternative is executed.
  1997.  
  1998. The execution of a timed entry call raises the exception  TASKING_ERROR  if
  1999. the called task completes its execution before accepting the call (see also
  2000. 9.10 for the case when the called task becomes abnormal).
  2001.  
  2002. Example:
  2003.  
  2004.     select
  2005.        CONTROLLER.REQUEST(MEDIUM)(SOME_ITEM);
  2006.     or
  2007.        delay 45.0;
  2008.        --  controller too busy, try something else
  2009.     end select;
  2010.  
  2011. References:   abnormal  task  9.10,  accept statement 9.5, actual parameter
  2012. part  6.4,  completed  task  9.4,  conditional  entry  call  9.7.2,   delay
  2013. expression  9.6,  delay  statement  9.6, duration 9.6, entry call statement
  2014. 9.5, entry family 9.5, entry index 9.5,  evaluation  4.5,  expression  4.4,
  2015. rendezvous 9.5, sequence of statements 5.1, task 9, tasking_error exception
  2016. 11.1
  2017.  
  2018.  
  2019.  
  2020.  
  2021. 9.8  Priorities
  2022.  
  2023.  
  2024. Each  task  may  (but  need  not)  have a priority, which is a value of the
  2025. subtype PRIORITY (of the type INTEGER) declared in the  predefined  library
  2026. package  SYSTEM  (see  13.7).   A  lower  value indicates a lower degree of
  2027. urgency;  the range of priorities is implementation-defined.  A priority is
  2028. associated with a task if a pragma
  2029.  
  2030.     pragma PRIORITY (static_expression);
  2031.  
  2032. appears in the corresponding task specification;  the priority is given  by
  2033. the  value  of  the  expression.   A  priority  is associated with the main
  2034. program if such a pragma appears in its  outermost  declarative  part.   At
  2035. most  one such pragma can appear within a given task specification or for a
  2036. subprogram that is a library unit, and these are the  only  allowed  places
  2037. for  this  pragma.   A  pragma  PRIORITY  has  no  effect if it occurs in a
  2038. subprogram other than the main program.
  2039.  
  2040.  
  2041.  
  2042.  
  2043.                                   9 - 30
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052. The specification of a priority  is  an  indication  given  to  assist  the
  2053. implementation  in the allocation of processing resources to parallel tasks
  2054. when there are more tasks eligible for  execution  than  can  be  supported
  2055. simultaneously  by  the  available  processing  resources.   The  effect of
  2056. priorities on scheduling is defined by the following rule:
  2057.  
  2058.      If two tasks with different priorities are both eligible for execution
  2059.      and could sensibly be executed using the same physical processors  and
  2060.      the  same  other processing resources, then it cannot be the case that
  2061.      the task with the lower priority is executing while the task with  the
  2062.      higher priority is not.
  2063.  
  2064.  
  2065.  
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.                                   9 - 31
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118. For  tasks of the same priority, the scheduling order is not defined by the
  2119. language.  For tasks without explicit priority, the  scheduling  rules  are
  2120. not  defined,  except  when such tasks are engaged in a rendezvous.  If the
  2121. priorities  of  both  tasks  engaged  in  a  rendezvous  are  defined,  the
  2122. rendezvous  is executed with the higher of the two priorities.  If only one
  2123. of the two priorities is defined, the rendezvous is executed with at  least
  2124. that  priority.   If  neither is defined, the priority of the rendezvous is
  2125. undefined.
  2126.  
  2127. Notes:
  2128.  
  2129. The priority of a  task  is  static  and  therefore  fixed.   However,  the
  2130. priority  during  a  rendezvous  is  not  necessarily  static since it also
  2131. depends on the priority of the task calling the entry.   Priorities  should
  2132. be  used  only to indicate relative degrees of urgency;  they should not be
  2133. used for task synchronization.
  2134.  
  2135. References:  declarative part 3.9, entry call statement 9.5,  integer  type
  2136. 3.5.4,  main program 10.1, package system 13.7, pragma 2.8, rendezvous 9.5,
  2137. static expression 4.9, subtype 3.3, task 9, task specification 9.1
  2138.  
  2139.  
  2140.  
  2141.  
  2142. 9.9  Task and Entry Attributes
  2143.  
  2144.  
  2145. For a task object or value T the following attributes are defined:
  2146.  
  2147. T'CALLABLE    Yields the  value  FALSE  when  the  execution  of  the  task
  2148.               designated  by  T  is either completed or terminated, or when
  2149.               the task is abnormal.  Yields the value TRUE otherwise.   The
  2150.               value of this attribute is of the predefined type BOOLEAN.
  2151.  
  2152. T'TERMINATED  Yields the  value  TRUE  if  the  task  designated  by  T  is
  2153.               terminated.   Yields the value FALSE otherwise.  The value of
  2154.               this attribute is of the predefined type BOOLEAN.
  2155.  
  2156. In addition, the representation attributes STORAGE_SIZE, SIZE, and  ADDRESS
  2157. are defined for a task object T or a task type T (see 13.7.2).
  2158.  
  2159. The  attribute COUNT is defined for an entry E of a task unit T.  The entry
  2160. can be either a single entry or an entry of a family (in  either  case  the
  2161. name  of  the  single  entry  or  entry family can be either a simple or an
  2162. expanded name).  This attribute is only allowed within the body of  T,  but
  2163. excluding  within any program unit that is, itself, inner to the body of T.
  2164.  
  2165. E'COUNT       Yields the number of entry  calls  presently  queued  on  the
  2166.               entry E (if the attribute is evaluated by the execution of an
  2167.               accept  statement for the entry E, the count does not include
  2168.               the calling task).  The value of this  attribute  is  of  the
  2169.               type universal_integer.
  2170.  
  2171. Note:
  2172.  
  2173.  
  2174.  
  2175.                                   9 - 32
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184. Algorithms  interrogating  the attribute E'COUNT should take precautions to
  2185. allow for the increase of the value of this attribute  for  incoming  entry
  2186. calls, and its decrease, for example with timed entry calls.
  2187.  
  2188. References:   abnormal  task  9.10,  accept statement 9.5, attribute 4.1.4,
  2189. boolean type 3.5.3, completed task 9.4, designate  9.1,  entry  9.5,  false
  2190. boolean  value  3.5.3, queue of entry calls 9.5, storage unit 13.7, task 9,
  2191. task object 9.2, task type 9.1,  terminated  task  9.4,  timed  entry  call
  2192. 9.7.3, true boolean value 3.5.3, universal_integer type 3.5.4
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.                                   9 - 33
  2242.  
  2243.  
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250. 9.10  Abort Statements
  2251.  
  2252.  
  2253. An  abort  statement  causes  one  or  more  tasks to become abnormal, thus
  2254. preventing any further rendezvous with such tasks.
  2255.  
  2256.     abort_statement ::= abort task_name {, task_name};
  2257.  
  2258. The determination of the type of each task name uses the fact that the type
  2259. of the name is a task type.
  2260.  
  2261. For the execution of an abort statement, the given task names are evaluated
  2262. in some order that is not defined by the language.  Each  named  task  then
  2263. becomes abnormal unless it is already terminated;  similarly, any task that
  2264. depends  on  a named task becomes abnormal unless it is already terminated.
  2265.  
  2266. Any abnormal task whose execution is suspended at an  accept  statement,  a
  2267. select  statement,  or  a  delay statement becomes completed;  any abnormal
  2268. task whose execution is suspended at an entry call, and that is not yet  in
  2269. a corresponding rendezvous, becomes completed and is removed from the entry
  2270. queue;   any  abnormal task that has not yet started its activation becomes
  2271. completed (and hence also terminated).  This completes the execution of the
  2272. abort statement.
  2273.  
  2274. The completion of any other abnormal task need not happen before completion
  2275. of the abort statement.  It must happen no later  than  when  the  abnormal
  2276. task  reaches a synchronization point that is one of the following: the end
  2277. of its activation;  a point where it causes the activation of another task;
  2278. an entry call; the start or the end  of  an  accept  statement;   a  select
  2279. statement;   a  delay  statement;   an  exception  handler;   or  an  abort
  2280. statement.  If a task that calls an  entry  becomes  abnormal  while  in  a
  2281. rendezvous,  its  termination  does not take place before the completion of
  2282. the rendezvous (see 11.5).
  2283.  
  2284. The call of an entry of an abnormal task raises the exception TASKING_ERROR
  2285. at the place of the call.  Similarly, the exception TASKING_ERROR is raised
  2286. for any task that has called an entry of an abnormal  task,  if  the  entry
  2287. call  is still queued or if the rendezvous is not yet finished (whether the
  2288. entry call is an entry call statement, or  a  conditional  or  timed  entry
  2289. call);   the  exception  is  raised  no  later  than  the completion of the
  2290. abnormal task.  The value of the attribute CALLABLE is FALSE for  any  task
  2291. that is abnormal (or completed).
  2292.  
  2293. If  the  abnormal completion of a task takes place while the task updates a
  2294. variable, then the value of this variable is undefined.  Example:
  2295.  
  2296.     abort USER, TERMINAL.all, POOL(3);
  2297.  
  2298. Notes:
  2299.  
  2300. An abort statement should be  used  only  in  extremely  severe  situations
  2301. requiring  unconditional termination.  A task is allowed to abort any task,
  2302. including itself.
  2303.  
  2304.  
  2305.  
  2306.  
  2307.                                   9 - 34
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316. References:  abnormal in rendezvous 11.5, accept statement 9.5,  activation
  2317. 9.3,  attribute  4.1.4,  callable  (predefined  attribute) 9.9, conditional
  2318. entry call 9.7.2, delay statement  9.6,  dependent  task  9.4,  entry  call
  2319. statement  9.5,  evaluation  of  a  name 4.1, exception handler 11.2, false
  2320. boolean value 3.5.3, name 4.1, queue of entry calls  9.5,  rendezvous  9.5,
  2321. select  statement  9.7,  statement 5, task 9, tasking_error exception 11.1,
  2322. terminated task 9.4, timed entry call 9.7.3
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.                                   9 - 35
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.  
  2380.  
  2381.  
  2382. 9.11  Shared Variables
  2383.  
  2384.  
  2385. The normal means of communicating values between tasks is  by  entry  calls
  2386. and accept statements.
  2387.  
  2388. If  two  tasks  read  or  update  a  shared  variable  (that is, a variable
  2389. accessible by both), then neither of them may  assume  anything  about  the
  2390. order  in  which  the  other  performs its operations, except at the points
  2391. where they synchronize.  Two tasks are synchronized at the start and at the
  2392. end of their rendezvous.  At the start and at the end of its activation,  a
  2393. task  is  synchronized  with  the task that causes this activation.  A task
  2394. that has completed its execution is synchronized with any other task.
  2395.  
  2396. For the actions performed by a program  that  uses  shared  variables,  the
  2397. following assumptions can always be made:
  2398.  
  2399.   -  If between two synchronization points of a task,  this  task  reads  a
  2400.      shared  variable  whose  type  is  a  scalar  or access type, then the
  2401.      variable is not updated by any other task at any  time  between  these
  2402.      two points.
  2403.  
  2404.   -  If between two synchronization points of a task, this task  updates  a
  2405.      shared  variable  whose  type  is  a  scalar  or access type, then the
  2406.      variable is neither read nor updated by any other  task  at  any  time
  2407.      between these two points.
  2408.  
  2409. The  execution  of  the program is erroneous if any of these assumptions is
  2410. violated.
  2411.  
  2412. If a given task reads the value of a shared variable, the above assumptions
  2413. allow an implementation to maintain local copies of the value (for example,
  2414. in registers or in some other form of temporary storage);  and for as  long
  2415. as  the  given task neither reaches a synchronization point nor updates the
  2416. value of the shared variable, the above assumptions  imply  that,  for  the
  2417. given  task,  reading  a  local  copy  is  equivalent to reading the shared
  2418. variable itself.
  2419.  
  2420. Similarly, if a given task updates the value  of  a  shared  variable,  the
  2421. above  assumptions  allow an implementation to maintain a local copy of the
  2422. value, and to defer the effective store of the local copy into  the  shared
  2423. variable until a synchronization point, provided that every further read or
  2424. update  of the variable by the given task is treated as a read or update of
  2425. the local copy.  On the other hand, an implementation  is  not  allowed  to
  2426. introduce  a  store,  unless  this  store  would  also  be  executed in the
  2427. canonical order (see 11.6).
  2428.  
  2429. The pragma SHARED can be used to specify that every read  or  update  of  a
  2430. variable  is a synchronization point for that variable;  that is, the above
  2431. assumptions always hold for the given variable  (but  not  necessarily  for
  2432. other variables).  The form of this pragma is as follows:
  2433.  
  2434.     pragma SHARED(variable_simple_name);
  2435.  
  2436.  
  2437.  
  2438.  
  2439.                                   9 - 36
  2440.  
  2441.  
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448. This  pragma  is  allowed  only  for  a  variable  declared  by  an  object
  2449. declaration and whose type is  a  scalar  or  access  type;   the  variable
  2450. declaration  and  the  pragma  must  both occur (in this order) immediately
  2451. within the same declarative part or package specification;  the pragma must
  2452. appear before any occurrence of the name of the variable, other than in  an
  2453. address clause.
  2454.  
  2455. An  implementation must restrict the objects for which the pragma SHARED is
  2456. allowed to objects for which each of direct reading and direct updating  is
  2457. implemented as an indivisible operation.
  2458.  
  2459. References:    accept   statement  9.5,  activation  9.3,  assignment  5.2,
  2460. canonical order 11.6, declarative  part  3.9,  entry  call  statement  9.5,
  2461. erroneous  1.6,  global  8.1, package specification 7.1, pragma 2.8, read a
  2462. value 6.2, rendezvous 9.5, simple name 3.1 4.1, task 9, type 3.3, update  a
  2463. value 6.2, variable 3.2.1
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.  
  2476.  
  2477.  
  2478.  
  2479.  
  2480.  
  2481.  
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.                                   9 - 37
  2506.  
  2507.  
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514. 9.12  Example of Tasking
  2515.  
  2516.  
  2517. The following example defines a buffering task to smooth variations between
  2518. the  speed  of  output  of  a producing task and the speed of input of some
  2519. consuming  task.   For  instance,  the  producing  task  may  contain   the
  2520. statements
  2521.  
  2522.     loop
  2523.        --  produce the next character CHAR
  2524.        BUFFER.WRITE(CHAR);
  2525.        exit when CHAR = ASCII.EOT;
  2526.     end loop;
  2527.  
  2528. and the consuming task may contain the statements
  2529.  
  2530.     loop
  2531.        BUFFER.READ(CHAR);
  2532.        --  consume the character CHAR
  2533.        exit when CHAR = ASCII.EOT;
  2534.     end loop;
  2535.  
  2536. The  buffering  task contains an internal pool of characters processed in a
  2537. round-robin fashion.  The pool has two indices, an  IN_INDEX  denoting  the
  2538. space  for the next input character and an OUT_INDEX denoting the space for
  2539. the next output character.
  2540.  
  2541.     task BUFFER is
  2542.        entry READ (C : out CHARACTER);
  2543.        entry WRITE(C : in  CHARACTER);
  2544.     end;
  2545.  
  2546.     task body BUFFER is
  2547.        POOL_SIZE : constant INTEGER := 100;
  2548.        POOL      : array(1 .. POOL_SIZE) of CHARACTER;
  2549.        COUNT     : INTEGER range 0 .. POOL_SIZE := 0;
  2550.        IN_INDEX, OUT_INDEX : INTEGER range 1 .. POOL_SIZE := 1;
  2551.     begin
  2552.        loop
  2553.           select
  2554.              when COUNT < POOL_SIZE =>
  2555.                 accept WRITE(C : in CHARACTER) do
  2556.                    POOL(IN_INDEX) := C;
  2557.                 end;
  2558.                 IN_INDEX := IN_INDEX mod POOL_SIZE + 1;
  2559.                 COUNT    := COUNT + 1;
  2560.           or when COUNT > 0 =>
  2561.                 accept READ(C : out CHARACTER) do
  2562.                    C := POOL(OUT_INDEX);
  2563.                 end;
  2564.                 OUT_INDEX := OUT_INDEX mod POOL_SIZE + 1;
  2565.                 COUNT     := COUNT - 1;
  2566.           or
  2567.              terminate;
  2568.           end select;
  2569.  
  2570.  
  2571.                                   9 - 38
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.        end loop;
  2581.     end BUFFER;
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.  
  2626.  
  2627.  
  2628.  
  2629.  
  2630.  
  2631.  
  2632.  
  2633.  
  2634.  
  2635.  
  2636.  
  2637.                                   9 - 39
  2638.  
  2639.  
  2640.  
  2641.  
  2642.