home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / ada / ada_lrm2.arc / CHAP09.DOC < prev    next >
Text File  |  1988-11-08  |  57KB  |  1,374 lines

  1.                                  9. Tasks
  2.  
  3.  
  4. The execution of a program that does not contain a task is defined in terms
  5. of a sequential execution of its actions, according to the rules  described
  6. in  other  chapters  of this manual.  These actions can be considered to be
  7. executed by a single logical processor.
  8.  
  9.  
  10. Tasks are entities whose executions proceed in parallel  in  the  following
  11. sense.   Each  task can be considered to be executed by a logical processor
  12. of  its  own.   Different  tasks  (different  logical  processors)  proceed
  13. independently, except at points where they synchronize.
  14.  
  15.  
  16. Some  tasks have entries.  An entry of a task can be called by other tasks.
  17. A task accepts a call  of  one  of  its  entries  by  executing  an  accept
  18. statement for the entry.  Synchronization is achieved by rendezvous between
  19. a  task  issuing an entry call and a task accepting the call.  Some entries
  20. have parameters;  entry calls and accept statements for  such  entries  are
  21. the principal means of communicating values between tasks.
  22.  
  23.  
  24. The  properties of each task are defined by a corresponding task unit which
  25. consists of a task specification and a task body.  Task units  are  one  of
  26. the  four  forms  of  program  unit of which programs can be composed.  The
  27. other forms are subprograms, packages and generic units.  The properties of
  28. task units,  tasks,  and  entries,  and  the  statements  that  affect  the
  29. interaction   between   tasks  (that  is,  entry  call  statements,  accept
  30. statements, delay statements, select statements, and abort statements)  are
  31. described in this chapter.
  32.  
  33. Note:
  34.  
  35.  
  36. Parallel   tasks  (parallel  logical  processors)  may  be  implemented  on
  37. multicomputers, multiprocessors, or with interleaved execution on a  single
  38. physical  processor.   On  the  other  hand, whenever an implementation can
  39. detect that the same effect can be guaranteed if parts of the actions of  a
  40. given  task  are  executed  by  different  physical  processors  acting  in
  41. parallel, it may choose to execute them in  this  way;   in  such  a  case,
  42. several physical processors implement a single logical processor.
  43.  
  44.  
  45. References:   abort  statement  9.10, accept statement 9.5, delay statement
  46. 9.6, entry 9.5, entry call statement  9.5,  generic  unit  12,  package  7,
  47. parameter  in  an  entry  call  9.5, program unit 6, rendezvous 9.5, select
  48. statement 9.7, subprogram 6, task body 9.1, task specification 9.1
  49.  
  50. 9.1  Task Specifications and Task Bodies
  51.  
  52.  
  53. A task unit consists of a task specification  and  a  task  body.   A  task
  54. specification  that  starts  with  the reserved words  task type declares a
  55. task type.  The value of an object of a task type designates a task  having
  56. the  entries,  if  any, that are declared in the task specification;  these
  57. entries are also called entries of this object.  The execution of the  task
  58. is defined by the corresponding task body.
  59.  
  60.  
  61. A  task specification without the reserved word type defines a single task.
  62. A task declaration with this form of specification  is  equivalent  to  the
  63. declaration   of  an  anonymous  task  type  immediately  followed  by  the
  64. declaration of an object of the task type, and  the  task  unit  identifier
  65. names the object.  In the remainder of this chapter, explanations are given
  66. in  terms  of  task  type declarations;  the corresponding explanations for
  67. single task declarations follow from the stated equivalence.
  68.  
  69.  
  70.     task_declaration ::= task_specification;
  71.  
  72.     task_specification ::=
  73.        task [type] identifier [is
  74.           {entry_declaration}
  75.           {representation_clause}
  76.        end [task_simple_name]]
  77.  
  78.     task_body ::=
  79.         task body task_simple_name is
  80.            [declarative_part]
  81.         begin
  82.             sequence_of_statements
  83.        [exception
  84.             exception_handler
  85.            {exception_handler}]
  86.         end [task_simple_name];
  87.  
  88.  
  89. The simple name at the start of a task  body  must  repeat  the  task  unit
  90. identifier.   Similarly  if  a  simple  name appears at the end of the task
  91. specification or body, it must repeat the task unit identifier.   Within  a
  92. task  body,  the  name  of  the corresponding task unit can also be used to
  93. refer to the task object that designates the task currently  executing  the
  94. body;   furthermore,  the  use  of  this name as a type mark is not allowed
  95. within the task unit itself.
  96.  
  97.  
  98. For the  elaboration  of  a  task  specification,  entry  declarations  and
  99. representation  clauses,  if  any, are elaborated in the order given.  Such
  100. representation clauses only apply to  the  entries  declared  in  the  task
  101. specification (see 13.5).
  102.  
  103.  
  104. The  elaboration  of a task body has no other effect than to establish that
  105. the body can from then on be used for the execution of tasks designated  by
  106. objects of the corresponding task type.
  107.  
  108.  
  109. The  execution of a task body is invoked by the activation of a task object
  110. of the corresponding type (see 9.3).  The optional  exception  handlers  at
  111. the end of a task body handle exceptions raised during the execution of the
  112. sequence of statements of the task body (see 11.4).
  113.  
  114.  
  115. Examples of specifications of task types:
  116.  
  117.     task type RESOURCE is
  118.        entry SEIZE;
  119.        entry RELEASE;
  120.     end RESOURCE;
  121.  
  122.     task type KEYBOARD_DRIVER is
  123.        entry READ (C : out CHARACTER);
  124.        entry WRITE(C : in  CHARACTER);
  125.     end KEYBOARD_DRIVER;
  126.  
  127.  
  128. Examples of specifications of single tasks:
  129.  
  130.     task PRODUCER_CONSUMER is
  131.        entry READ (V : out ITEM);
  132.        entry WRITE(E : in  ITEM);
  133.     end;
  134.  
  135.     task CONTROLLER is
  136.        entry REQUEST(LEVEL)(D : ITEM);  --  a family of entries
  137.     end CONTROLLER;
  138.  
  139.     task USER;  --  has no entries
  140.  
  141.  
  142. Example of task specification and corresponding body:
  143.  
  144.     task PROTECTED_ARRAY is
  145.        --  INDEX and ITEM are global types
  146.        entry READ (N : in INDEX; V : out ITEM);
  147.        entry WRITE(N : in INDEX; E : in  ITEM);
  148.     end;
  149.  
  150.     task body PROTECTED_ARRAY is
  151.        TABLE : array(INDEX) of ITEM := (INDEX => NULL_ITEM);
  152.     begin
  153.        loop
  154.           select
  155.              accept READ (N : in INDEX; V : out ITEM) do
  156.                 V := TABLE(N);
  157.              end READ;
  158.           or
  159.              accept WRITE(N : in INDEX; E : in  ITEM) do
  160.                 TABLE(N) := E;
  161.              end WRITE;
  162.           end select;
  163.        end loop;
  164.     end PROTECTED_ARRAY;
  165.  
  166. Note:
  167.  
  168.  
  169. A task specification specifies the interface of tasks of the task type with
  170. other  tasks  of  the  same  or  of different types, and also with the main
  171. program.
  172.  
  173.  
  174. References:  declaration 3.1, declarative part 3.9, elaboration 3.9,  entry
  175. 9.5,  entry  declaration  9.5, exception handler 11.2, identifier 2.3, main
  176. program 10.1, object 3.2, object declaration 3.2.1,  representation  clause
  177. 13.1,  reserved word 2.9, sequence of statements 5.1, simple name 4.1, type
  178. 3.3, type declaration 3.3.1
  179.  
  180. 9.2  Task Types and Task Objects
  181.  
  182.  
  183. A task type is a limited type (see 7.4.4).  Hence  neither  assignment  nor
  184. the  predefined  comparison  for  equality  and  inequality are defined for
  185. objects of task types;  moreover, the mode out is not allowed for a  formal
  186. parameter whose type is a task type.
  187.  
  188.  
  189. A  task object is an object whose type is a task type.  The value of a task
  190. object designates a task that has the entries  of  the  corresponding  task
  191. type,  and whose execution is specified by the corresponding task body.  If
  192. a task object is the object, or a subcomponent of the object,  declared  by
  193. an  object declaration, then the value of the task object is defined by the
  194. elaboration of the object declaration.  If a task object is the object,  or
  195. a  subcomponent  of  the object, created by the evaluation of an allocator,
  196. then the value of the task object is  defined  by  the  evaluation  of  the
  197. allocator.   For  all  parameter modes, if an actual parameter designates a
  198. task, the associated formal parameter designates the same task;   the  same
  199. holds  for  a  subcomponent  of  an  actual parameter and the corresponding
  200. subcomponent of the associated formal parameter;  finally, the  same  holds
  201. for generic parameters.
  202.  
  203.  
  204. Examples:
  205.  
  206.     CONTROL  : RESOURCE;
  207.     TELETYPE : KEYBOARD_DRIVER;
  208.     POOL     : array(1 .. 10) of KEYBOARD_DRIVER;
  209.     --  see also examples of declarations of single tasks in 9.1
  210.  
  211.  
  212. Example of access type designating task objects:
  213.  
  214.     type KEYBOARD is access KEYBOARD_DRIVER;
  215.  
  216.     TERMINAL : KEYBOARD := new KEYBOARD_DRIVER;
  217.  
  218. Notes:
  219.  
  220.  
  221. Since  a  task type is a limited type, it can appear as the definition of a
  222. limited private type in a private part, and as a generic  actual  parameter
  223. associated  with  a  formal parameter whose type is a limited type.  On the
  224. other hand, the type of a generic formal parameter of mode in must not be a
  225. limited type and hence cannot be a task type.
  226.  
  227.  
  228. Task objects behave as constants (a task object always designates the  same
  229. task)  since  their  values are implicitly defined either at declaration or
  230. allocation, or by a parameter  association,  and  since  no  assignment  is
  231. available.   However  the  reserved  word  constant  is  not allowed in the
  232. declaration  of  a  task  object  since  this  would  require  an  explicit
  233. initialization.   A  task object that is a formal parameter of mode in is a
  234. constant (as is any formal parameter of this mode).
  235.  
  236.  
  237. If an application needs to store and exchange task identities, it can do so
  238. by defining an access type designating the corresponding task  objects  and
  239. by  using  access  values  for identification purposes (see above example).
  240. Assignment is available for such an access type as for any access type.
  241.  
  242.  
  243. Subtype declarations are allowed for task types as  for  other  types,  but
  244. there are no constraints applicable to task types.
  245.  
  246.  
  247. References:   access  type  3.8,  actual  parameter  6.4.1,  allocator 4.8,
  248. assignment 5.2, component declaration 3.7,  composite  type  3.3,  constant
  249. 3.2.1,  constant  declaration  3.2.1,  constraint  3.3,  designate 3.8 9.1,
  250. elaboration 3.9, entry 9.5, equality operator 4.5.2, formal parameter  6.2,
  251. formal   parameter   mode  6.2,  generic  actual  parameter  12.3,  generic
  252. association 12.3, generic formal parameter 12.1, generic  formal  parameter
  253. mode  12.1.1,  generic  unit  12, inequality operator 4.5.2, initialization
  254. 3.2.1, limited type 7.4.4, object 3.2, object declaration 3.2.1,  parameter
  255. association  6.4,  private  part  7.2, private type 7.4, reserved word 2.9,
  256. subcomponent 3.3, subprogram 6, subtype declaration 3.3.2, task  body  9.1,
  257. type 3.3
  258.  
  259. 9.3  Task Execution - Task Activation
  260.  
  261.  
  262. A  task body defines the execution of any task that is designated by a task
  263. object of the corresponding task type.  The initial part of this  execution
  264. is  called  the  activation  of  the  task  object,  and  also  that of the
  265. designated task;  it consists of the elaboration of the  declarative  part,
  266. if  any, of the task body.  The execution of different tasks, in particular
  267. their activation, proceeds in parallel.
  268.  
  269.  
  270. If an object declaration that declares a  task  object  occurs  immediately
  271. within  a  declarative  part, then the activation of the task object starts
  272. after the elaboration of the declarative part (that is, after  passing  the
  273. reserved  word  begin following the declarative part);  similarly if such a
  274. declaration  occurs  immediately  within  a  package   specification,   the
  275. activation  starts  after  the  elaboration  of the declarative part of the
  276. package body.  The same holds for the activation of a task object that is a
  277. subcomponent of an object declared immediately within a declarative part or
  278. package specification.  The first statement following the declarative  part
  279. is  executed only after conclusion of the activation of these task objects.
  280.  
  281.  
  282. Should an exception be raised by the activation of one of these tasks, that
  283. task becomes a completed task (see 9.4);   other  tasks  are  not  directly
  284. affected.   Should  one  of  these  tasks  thus become completed during its
  285. activation, the exception TASKING_ERROR is raised upon  conclusion  of  the
  286. activation  of  all  of  these  tasks  (whether  successfully or not);  the
  287. exception is raised at  a  place  that  is  immediately  before  the  first
  288. statement  following  the  declarative part (immediately after the reserved
  289. word begin).  Should several of these tasks thus  become  completed  during
  290. their activation, the exception TASKING_ERROR is raised only once.
  291.  
  292.  
  293. Should  an  exception be raised by the elaboration of a declarative part or
  294. package  specification,  then  any  task  that  is  created  (directly   or
  295. indirectly)  by  this  elaboration  and  that  is not yet activated becomes
  296. terminated and is therefore  never  activated  (see  section  9.4  for  the
  297. definition of a terminated task).
  298.  
  299.  
  300. For  the  above  rules,  in  any  package  body  without statements, a null
  301. statement is assumed.  For any package without a package body, an  implicit
  302. package  body  containing a single null statement is assumed.  If a package
  303. without a package body is declared immediately within some program unit  or
  304. block  statement,  the  implicit  package  body  occurs  at  the end of the
  305. declarative part of the program unit or  block  statement;   if  there  are
  306. several  such  packages,  the  order  of  the  implicit  package  bodies is
  307. undefined.
  308.  
  309.  
  310. A task object that is the object, or a subcomponent of the object,  created
  311. by  the  evaluation  of  an allocator is activated by this evaluation.  The
  312. activation starts after any initialization for the object  created  by  the
  313. allocator;   if  several subcomponents are task objects, they are activated
  314. in parallel.  The access value designating such an object  is  returned  by
  315. the allocator only after the conclusion of these activations.
  316.  
  317.  
  318. Should an exception be raised by the activation of one of these tasks, that
  319. task  becomes  a  completed  task;   other tasks are not directly affected.
  320. Should one of these tasks thus become completed during its activation,  the
  321. exception  TASKING_ERROR is raised upon conclusion of the activation of all
  322. of these tasks (whether successfully or not);  the exception is  raised  at
  323. the  place where the allocator is evaluated.  Should several of these tasks
  324. thus become completed during their activation, the exception  TASKING_ERROR
  325. is raised only once.
  326.  
  327.  
  328. Should  an  exception be raised by the initialization of the object created
  329. by an allocator (hence before  the  start  of  any  activation),  any  task
  330. designated  by  a  subcomponent  of  this  object becomes terminated and is
  331. therefore never activated.
  332.  
  333.  
  334. Example:
  335.  
  336.     procedure P is
  337.        A, B : RESOURCE;  --  elaborate the task objects A, B
  338.        C    : RESOURCE;  --  elaborate the task object C
  339.     begin
  340.        --  the tasks A, B, C are activated in parallel before the first statement
  341.        ...
  342.     end;
  343.  
  344. Notes:
  345.  
  346.  
  347. An entry of a task can be called before the task has  been  activated.   If
  348. several  tasks  are  activated  in  parallel, the execution of any of these
  349. tasks need not await the end of the activation  of the other tasks.  A task
  350. may become completed during its activation either because of  an  exception
  351. or because it is aborted (see 9.10).
  352.  
  353.  
  354. References:   allocator  4.8,  completed  task  9.4,  declarative part 3.9,
  355. elaboration 3.9, entry 9.5,  exception  11,  handling  an  exception  11.4,
  356. package body 7.1, parallel execution 9, statement 5, subcomponent 3.3, task
  357. body   9.1,   task  object  9.2,  task  termination  9.4,  task  type  9.1,
  358. tasking_error exception 11.1
  359.  
  360. 9.4  Task Dependence - Termination of Tasks
  361.  
  362.  
  363. Each task depends on at least one master.  A master is a construct that  is
  364. either  a  task,  a currently executing block statement or subprogram, or a
  365. library package (a package declared within another program unit  is  not  a
  366. master).   The  dependence  on  a  master  is  a  direct  dependence in the
  367. following two cases:
  368.  
  369.  
  370. (a)  The task designated by  a  task  object  that  is  the  object,  or  a
  371.      subcomponent  of the object, created by the evaluation of an allocator
  372.      depends on the master that elaborates the  corresponding  access  type
  373.      definition.
  374.  
  375.  
  376. (b)  The task designated by any other task object  depends  on  the  master
  377.      whose execution creates the task object.
  378.  
  379.  
  380. Furthermore,  if a task depends on a given master that is a block statement
  381. executed by another master, then  the  task  depends  also  on  this  other
  382. master,  in  an  indirect  manner;  the same holds if the given master is a
  383. subprogram called by another master, and if the given master is a task that
  384. depends (directly or indirectly) on another master.  Dependences exist  for
  385. objects  of  a  private  type  whose full declaration is in terms of a task
  386. type.
  387.  
  388.  
  389. A task is said to have completed its execution when  it  has  finished  the
  390. execution  of  the  sequence  of statements that appears after the reserved
  391. word  begin in the corresponding body.  Similarly a block or  a  subprogram
  392. is  said to have completed its execution when it has finished the execution
  393. of the corresponding sequence of statements.  For a  block  statement,  the
  394. execution  is also said to be completed when it reaches an exit, return, or
  395. goto statement transferring control out of the block.  For a procedure, the
  396. execution is  also  said  to  be  completed  when  a  corresponding  return
  397. statement  is  reached.   For  a function, the execution is also said to be
  398. completed after the  evaluation  of  the  result  expression  of  a  return
  399. statement.  Finally the execution of a task, block statement, or subprogram
  400. is  completed if an exception is raised by the execution of its sequence of
  401. statements and there is no corresponding handler, or, if there is one, when
  402. it has finished the execution of the corresponding handler.
  403.  
  404.  
  405. If a task has no dependent task, its termination takes place  when  it  has
  406. completed  its  execution.   After  its  termination,  a task is said to be
  407. terminated.  If a task has dependent tasks,  its  termination  takes  place
  408. when  the  execution  of  the task is completed and all dependent tasks are
  409. terminated.  A block  statement  or  subprogram  body  whose  execution  is
  410. completed is not left until all of its dependent tasks are terminated.
  411.  
  412.  
  413. Termination  of  a  task otherwise takes place if and only if its execution
  414. has reached an open  terminate  alternative  in  a  select  statement  (see
  415. 9.7.1), and the following conditions are satisfied:
  416.  
  417.  
  418.   -  The task depends on some master whose execution  is  completed  (hence
  419.      not a library package).
  420.  
  421.  
  422.   -  Each task that depends on the  master  considered  is  either  already
  423.      terminated  or similarly waiting on an open terminate alternative of a
  424.      select statement.
  425.  
  426.  
  427. When both conditions are satisfied, the task considered becomes terminated,
  428. together with all tasks that depend on the master considered.
  429.  
  430.  
  431. Example:
  432.  
  433.     declare
  434.        type GLOBAL is access RESOURCE;          --  see 9.1
  435.        A, B : RESOURCE;
  436.        G    : GLOBAL;
  437.     begin
  438.        --  activation of A and B
  439.        declare
  440.           type LOCAL is access RESOURCE;
  441.           X : GLOBAL := new RESOURCE;  --  activation of X.all
  442.           L : LOCAL  := new RESOURCE;  --  activation of L.all
  443.           C : RESOURCE;
  444.        begin
  445.           --  activation of C
  446.           G := X;  --  both G and X designate the same task object
  447.           ...
  448.        end;  --  await termination of C and L.all (but not X.all)
  449.        ...
  450.     end;  --  await termination of A, B, and G.all
  451.  
  452. Notes:
  453.  
  454.  
  455. The rules given for termination imply that all tasks that depend  (directly
  456. or  indirectly)  on a given master and that are not already terminated, can
  457. be terminated (collectively) if and only if each of them is waiting  on  an
  458. open  terminate  alternative of a select statement and the execution of the
  459. given master is completed.
  460.  
  461.  
  462. The usual rules apply to the main program.   Consequently,  termination  of
  463. the  main  program  awaits  termination  of  any dependent task even if the
  464. corresponding task type is declared in a library  package.   On  the  other
  465. hand,  termination  of the main program does not await termination of tasks
  466. that depend on library packages;  the language does not define whether such
  467. tasks are required to terminate.
  468.  
  469.  
  470. For an access type derived from  another  access  type,  the  corresponding
  471. access  type  definition  is that of the parent type;  the dependence is on
  472. the master that elaborates the ultimate parent access type definition.
  473.  
  474.  
  475. A renaming declaration defines a new name for an existing entity and  hence
  476. creates no further dependence.
  477.  
  478.  
  479. References:    access   type  3.8,  allocator  4.8,  block  statement  5.6,
  480. declaration 3.1, designate 3.8 9.1, exception 11, exception  handler  11.2,
  481. exit  statement  5.7,  function 6.5, goto statement 5.9, library unit 10.1,
  482. main program 10.1, object 3.2, open alternative 9.7.1, package  7,  program
  483. unit  6,  renaming  declaration  8.5,  return statement 5.8, selective wait
  484. 9.7.1,  sequence  of  statements  5.1,  statement  5,   subcomponent   3.3,
  485. subprogram  body  6.3, subprogram call 6.4, task body 9.1, task object 9.2,
  486. terminate alternative 9.7.1
  487.  
  488. 9.5  Entries, Entry Calls, and Accept Statements
  489.  
  490.  
  491. Entry calls and accept statements are the primary means of  synchronization
  492. of  tasks, and of communicating values between tasks.  An entry declaration
  493. is similar to a subprogram declaration  and  is  only  allowed  in  a  task
  494. specification.   The  actions  to  be performed when an entry is called are
  495. specified by corresponding accept statements.
  496.  
  497.  
  498.     entry_declaration ::=
  499.        entry identifier [(discrete_range)] [formal_part];
  500.  
  501.     entry_call_statement ::= entry_name [actual_parameter_part];
  502.  
  503.     accept_statement ::=
  504.        accept entry_simple_name [(entry_index)] [formal_part] [do
  505.           sequence_of_statements
  506.        end [entry_simple_name]];
  507.  
  508.     entry_index ::= expression
  509.  
  510.  
  511. An entry declaration that includes a discrete range (see 3.6.1) declares  a
  512. family  of distinct entries having the same formal part (if any);  that is,
  513. one such entry for each value of the discrete range.  The term single entry
  514. is used in the definition of any rule that applies to any entry other  than
  515. one  of  a family.  The task designated by an object of a task type has (or
  516. owns) the entries declared in the specification of the task type.
  517.  
  518.  
  519. Within the body of a task, each of its single entries or entry families can
  520. be named by the corresponding simple name.  The  name  of  an  entry  of  a
  521. family takes the form of an indexed component, the family simple name being
  522. followed  by  the index in parentheses;  the type of this index must be the
  523. same as that of the  discrete  range  in  the  corresponding  entry  family
  524. declaration.   Outside  the  body of a task an entry name has the form of a
  525. selected component,  whose  prefix  denotes  the  task  object,  and  whose
  526. selector is the simple name of one of its single entries or entry families.
  527.  
  528.  
  529. A  single  entry overloads a subprogram, an enumeration literal, or another
  530. single entry if they have the same identifier.  Overloading is not  defined
  531. for  entry  families.  A single entry or an entry of an entry family can be
  532. renamed as a procedure as explained in section 8.5.
  533.  
  534.  
  535. The parameter modes defined for parameters of the formal part of  an  entry
  536. declaration  are the same as for a subprogram declaration and have the same
  537. meaning (see 6.2).  The syntax of an entry call  statement  is  similar  to
  538. that   of   a  procedure  call  statement,  and  the  rules  for  parameter
  539. associations are the same as for subprogram calls (see 6.4.1 and 6.4.2).
  540.  
  541.  
  542. An accept statement specifies the actions to be performed at a  call  of  a
  543. named entry (it can be an entry of a family).  The formal part of an accept
  544. statement  must  conform to the formal part given in the declaration of the
  545. single entry or entry family named by the  accept  statement  (see  section
  546. 6.3.1  for  the conformance rules).  If a simple name appears at the end of
  547. an accept statement, it must repeat that given at the start.
  548.  
  549.  
  550. An accept statement for an entry of a given task is only allowed within the
  551. corresponding task body;  excluding within the body  of  any  program  unit
  552. that  is,  itself,  inner  to  the task body;  and excluding within another
  553. accept statement for either the same single entry or an entry of  the  same
  554. family.   (One  consequence  of this rule is that a task can execute accept
  555. statements only for its own entries.)  A task body can  contain  more  than
  556. one accept statement for the same entry.
  557.  
  558.  
  559. For the elaboration of an entry declaration, the discrete range, if any, is
  560. evaluated  and  the  formal  part,  if  any,  is  then  elaborated as for a
  561. subprogram declaration.
  562.  
  563.  
  564. Execution of an accept statement starts with the evaluation  of  the  entry
  565. index  (in  the  case of an entry of a family).  Execution of an entry call
  566. statement starts with the evaluation of the entry name;  this  is  followed
  567. by any evaluations required for actual parameters in the same manner as for
  568. a  subprogram call (see 6.4).  Further execution of an accept statement and
  569. of a corresponding entry call statement are synchronized.
  570.  
  571.  
  572. If a given entry is called by only one task, there are  two  possibilities:
  573.  
  574.  
  575.   -  If  the  calling  task  issues  an  entry  call  statement  before   a
  576.      corresponding  accept  statement  is  reached  by  the task owning the
  577.      entry, the execution of the calling task is suspended.
  578.  
  579.  
  580.   -  If a task reaches an accept statement prior to any call of that entry,
  581.      the execution of the task is suspended until such a call is  received.
  582.  
  583.  
  584. When an entry has been called and a corresponding accept statement has been
  585. reached,  the  sequence  of  statements, if any, of the accept statement is
  586. executed by the called task (while the  calling  task  remains  suspended).
  587. This  interaction is called a rendezvous.  Thereafter, the calling task and
  588. the task owning the entry continue their execution in parallel.
  589.  
  590.  
  591. If several  tasks  call  the  same  entry  before  a  corresponding  accept
  592. statement  is reached, the calls are queued;  there is one queue associated
  593. with each entry.  Each execution of an accept statement  removes  one  call
  594. from the queue.  The calls are processed in the order of arrival.
  595.  
  596.  
  597. An  attempt  to  call  an  entry of a task that has completed its execution
  598. raises the exception TASKING_ERROR at the point of the call, in the calling
  599. task;  similarly, this exception is raised at the point of the call if  the
  600. called  task  completes  its  execution before accepting the call (see also
  601. 9.10 for the case when the called task becomes  abnormal).   The  exception
  602. CONSTRAINT_ERROR  is  raised  if  the  index of an entry of a family is not
  603. within the specified discrete range.
  604.  
  605.  
  606. Examples of entry declarations:
  607.  
  608.     entry READ(V : out ITEM);
  609.     entry SEIZE;
  610.     entry REQUEST(LEVEL)(D : ITEM);  --  a family of entries
  611.  
  612.  
  613. Examples of entry calls:
  614.  
  615.     CONTROL.RELEASE;                      --  see 9.2 and 9.1
  616.     PRODUCER_CONSUMER.WRITE(E);           --  see 9.1
  617.     POOL(5).READ(NEXT_CHAR);              --  see 9.2 and 9.1
  618.     CONTROLLER.REQUEST(LOW)(SOME_ITEM);   --  see 9.1
  619.  
  620.  
  621. Examples of accept statements:
  622.  
  623.     accept SEIZE;
  624.  
  625.     accept READ(V : out ITEM) do
  626.        V := LOCAL_ITEM;
  627.     end READ;
  628.  
  629.     accept REQUEST(LOW)(D : ITEM) do
  630.        ...
  631.     end REQUEST;
  632.  
  633. Notes:
  634.  
  635.  
  636. The formal part given in an accept statement is not elaborated; it is  only
  637. used to identify the corresponding entry.
  638.  
  639.  
  640. An  accept  statement   can  call  subprograms  that issue entry calls.  An
  641. accept statement need not  have  a  sequence  of  statements  even  if  the
  642. corresponding  entry  has  parameters.   Equally, it can have a sequence of
  643. statements even if the corresponding entry has no parameters.  The sequence
  644. of statements of an accept statement can include return statements.  A task
  645. can call its own entries but it will, of course,  deadlock.   The  language
  646. permits  conditional  and  timed  entry  calls  (see 9.7.2 and 9.7.3).  The
  647. language rules ensure that a task can only be in one entry queue at a given
  648. time.
  649.  
  650.  
  651. If the bounds of  the  discrete  range  of  an  entry  family  are  integer
  652. literals,  the  index (in an entry name or accept statement) must be of the
  653. predefined type INTEGER (see 3.6.1).
  654.  
  655.  
  656. References:  abnormal task 9.10, actual parameter part 6.4, completed  task
  657. 9.4,    conditional    entry   call   9.7.2,   conformance   rules   6.3.1,
  658. constraint_error exception  11.1,  designate  9.1,  discrete  range  3.6.1,
  659. elaboration  3.1 3.9, enumeration literal 3.5.1, evaluation 4.5, expression
  660. 4.4, formal part 6.1, identifier 2.3, indexed component 4.1.1, integer type
  661. 3.5.4, name 4.1, object 3.2, overloading 6.6  8.7,  parallel  execution  9,
  662. prefix  4.1,  procedure  6,  procedure  call 6.4, renaming declaration 8.5,
  663. return statement 5.8, scope 8.2, selected component 4.1.3, selector  4.1.3,
  664. sequence  of  statements  5.1,  simple  expression  4.4,  simple  name 4.1,
  665. subprogram 6, subprogram body 6.3, subprogram declaration 6.1, task 9, task
  666. body 9.1, task specification 9.1, tasking_error exception 11.1, timed entry
  667. call 9.7.3
  668.  
  669. 9.6  Delay Statements, Duration, and Time
  670.  
  671.  
  672. The execution of a delay statement evaluates  the  simple  expression,  and
  673. suspends  further  execution of the task that executes the delay statement,
  674. for at least the duration specified by the resulting value.
  675.  
  676.  
  677.     delay_statement ::= delay simple_expression;
  678.  
  679.  
  680. The simple expression must be of the predefined fixed point type  DURATION;
  681. its value is expressed in seconds;  a delay statement with a negative value
  682. is equivalent to a delay statement with a zero value.
  683.  
  684.  
  685. Any  implementation  of  the  type  DURATION  must  allow representation of
  686. durations (both positive and negative) up to at least  86400  seconds  (one
  687. day);   the  smallest  representable  duration,  DURATION'SMALL must not be
  688. greater than twenty milliseconds (whenever possible, a  value  not  greater
  689. than  fifty  microseconds should be chosen).  Note that DURATION'SMALL need
  690. not correspond to the basic clock cycle, the named number SYSTEM.TICK  (see
  691. 13.7).
  692.  
  693.  
  694. The  definition  of  the  type  TIME  is provided in the predefined library
  695. package CALENDAR.  The function CLOCK returns the current value of TIME  at
  696. the  time  it is called.  The functions YEAR, MONTH, DAY and SECONDS return
  697. the corresponding values for a given value of the type TIME;  the procedure
  698. SPLIT returns all four  corresponding  values.   Conversely,  the  function
  699. TIME_OF  combines  a  year  number,  a  month  number,  a day number, and a
  700. duration, into a value of  type  TIME.   The  operators  "+"  and  "-"  for
  701. addition  and  subtraction  of  times  and  durations,  and  the relational
  702. operators for times, have the conventional meaning.
  703.  
  704.  
  705. The exception TIME_ERROR is raised by the function TIME_OF  if  the  actual
  706. parameters do not form a proper date.  This exception is also raised by the
  707. operators  "+"  and  "-" if, for the given operands, these operators cannot
  708. return a date whose year number  is  in  the  range  of  the  corresponding
  709. subtype, or if the operator "-" cannot return a result that is in the range
  710. of the type DURATION.
  711.  
  712.  
  713.     package CALENDAR is
  714.        type TIME is private;
  715.  
  716.        subtype YEAR_NUMBER  is INTEGER  range 1901 .. 2099;
  717.        subtype MONTH_NUMBER is INTEGER  range 1 .. 12;
  718.        subtype DAY_NUMBER   is INTEGER  range 1 .. 31;
  719.        subtype DAY_DURATION is DURATION range 0.0 .. 86_400.0;
  720.  
  721.        function CLOCK return TIME;
  722.  
  723.        function YEAR   (DATE : TIME) return YEAR_NUMBER;
  724.        function MONTH  (DATE : TIME) return MONTH_NUMBER;
  725.        function DAY    (DATE : TIME) return DAY_NUMBER;
  726.        function SECONDS(DATE : TIME) return DAY_DURATION;
  727.  
  728.        procedure SPLIT (DATE    : in  TIME;
  729.                         YEAR    : out YEAR_NUMBER;
  730.                         MONTH   : out MONTH_NUMBER;
  731.                         DAY     : out DAY_NUMBER;
  732.                         SECONDS : out DAY_DURATION);
  733.  
  734.        function TIME_OF(YEAR    : YEAR_NUMBER;
  735.                         MONTH   : MONTH_NUMBER;
  736.                         DAY     : DAY_NUMBER;
  737.                         SECONDS : DAY_DURATION := 0.0) return TIME;
  738.  
  739.        function "+"  (LEFT : TIME;     RIGHT : DURATION) return TIME;
  740.        function "+"  (LEFT : DURATION; RIGHT : TIME)     return TIME;
  741.        function "-"  (LEFT : TIME;     RIGHT : DURATION) return TIME;
  742.        function "-"  (LEFT : TIME;     RIGHT : TIME)     return DURATION;
  743.  
  744.        function "<"  (LEFT, RIGHT : TIME) return BOOLEAN;
  745.        function "<=" (LEFT, RIGHT : TIME) return BOOLEAN;
  746.        function ">"  (LEFT, RIGHT : TIME) return BOOLEAN;
  747.        function ">=" (LEFT, RIGHT : TIME) return BOOLEAN;
  748.  
  749.        TIME_ERROR : exception;  --  can be raised by TIME_OF, "+", and "-"
  750.  
  751.     private
  752.        -- implementation-dependent
  753.     end;
  754.  
  755.  
  756. Examples:
  757.  
  758.     delay 3.0;  --  delay 3.0 seconds
  759.  
  760.     declare
  761.        use CALENDAR;
  762.        --  INTERVAL is a global constant of type DURATION
  763.        NEXT_TIME : TIME := CLOCK + INTERVAL;
  764.     begin
  765.        loop
  766.           delay NEXT_TIME - CLOCK;
  767.           --  some actions
  768.           NEXT_TIME := NEXT_TIME + INTERVAL;
  769.        end loop;
  770.     end;
  771.  
  772. Notes:
  773.  
  774.  
  775. The second example causes the loop to be repeated every INTERVAL seconds on
  776. average.    This   interval  between  two  successive  iterations  is  only
  777. approximate.  However, there will be no cumulative drift  as  long  as  the
  778. duration of each iteration is (sufficiently) less than INTERVAL.
  779.  
  780.  
  781. References:   adding  operator  4.5,  duration  C,  fixed point type 3.5.9,
  782. function call 6.4, library unit 10.1, operator 4.5, package 7, private type
  783. 7.4, relational operator 4.5, simple expression 4.4, statement 5,  task  9,
  784. type 3.3
  785.  
  786. 9.7  Select Statements
  787.  
  788.  
  789. There  are three forms of select statements.  One form provides a selective
  790. wait for one or more alternatives.  The other two provide  conditional  and
  791. timed entry calls.
  792.  
  793.  
  794.     select_statement ::= selective_wait
  795.        | conditional_entry_call | timed_entry_call
  796.  
  797.  
  798. References:   selective  wait  9.7.1,  conditional  entry call 9.7.2, timed
  799. entry call 9.7.3
  800.  
  801. 9.7.1  Selective Waits
  802.  
  803.  
  804. This form of the select statement allows a combination of waiting for,  and
  805. selecting  from,  one  or  more  alternatives.  The selection can depend on
  806. conditions associated with each alternative of the selective wait.
  807.  
  808.  
  809.     selective_wait ::=
  810.         select
  811.           select_alternative
  812.        {or
  813.           select_alternative}
  814.        [else
  815.           sequence_of_statements]
  816.         end select;
  817.  
  818.     select_alternative ::=
  819.        [when condition =>]
  820.           selective_wait_alternative
  821.  
  822.     selective_wait_alternative ::= accept_alternative
  823.        | delay_alternative | terminate_alternative
  824.  
  825.     accept_alternative ::= accept_statement [sequence_of_statements]
  826.  
  827.     delay_alternative  ::= delay_statement  [sequence_of_statements]
  828.  
  829.     terminate_alternative ::= terminate;
  830.  
  831.  
  832. A selective wait must contain at least one accept alternative.  In addition
  833. a selective wait can contain either a terminate alternative (only one),  or
  834. one or more delay alternatives, or an else part;  these three possibilities
  835. are mutually exclusive.
  836.  
  837.  
  838. A  select alternative is said to be open if it does not start with when and
  839. a condition, or if the  condition  is  TRUE.   It  is  said  to  be  closed
  840. otherwise.
  841.  
  842.  
  843. For  the execution of a selective wait, any conditions specified after when
  844. are evaluated in some order that is not  defined  by  the  language;   open
  845. alternatives are thus determined.  For an open delay alternative, the delay
  846. expression  is  also  evaluated.  Similarly, for an open accept alternative
  847. for an entry of a family, the entry index is also evaluated.  Selection and
  848. execution of one open alternative, or of the else part, then completes  the
  849. execution  of  the  selective  wait;   the  rules  for  this  selection are
  850. described below.
  851.  
  852.  
  853. Open accept alternatives are  first  considered.   Selection  of  one  such
  854. alternative  takes  place  immediately  if  a  corresponding  rendezvous is
  855. possible, that is, if there is a corresponding entry call issued by another
  856. task and waiting to be accepted.   If  several  alternatives  can  thus  be
  857. selected,  one  of them is selected arbitrarily (that is, the language does
  858. not  define  which  one).   When  such  an  alternative  is  selected,  the
  859. corresponding  accept  statement  and  possible  subsequent  statements are
  860. executed.  If no rendezvous is immediately possible and there  is  no  else
  861. part,  the  task  waits  until  an  open  selective wait alternative can be
  862. selected.
  863.  
  864.  
  865. Selection of the other forms of alternative or of an else part is performed
  866. as follows:
  867.  
  868.  
  869.   -  An open delay alternative will be selected if  no  accept  alternative
  870.      can  be  selected before the specified delay has elapsed (immediately,
  871.      for a negative or zero delay in the absence of  queued  entry  calls);
  872.      any  subsequent  statements  of the alternative are then executed.  If
  873.      several delay alternatives can thus be selected (that is, if they have
  874.      the same delay), one of them is selected arbitrarily.
  875.  
  876.  
  877.   -  The else part is selected and its statements are executed if no accept
  878.      alternative  can  be  immediately  selected,  in  particular,  if  all
  879.      alternatives are closed.
  880.  
  881.  
  882.   -  An open terminate alternative is selected if the conditions stated  in
  883.      section  9.4 are satisfied.  It is a consequence of other rules that a
  884.      terminate alternative cannot be selected while there is a queued entry
  885.      call for any entry of the task.
  886.  
  887.  
  888. The exception PROGRAM_ERROR is raised if all alternatives  are  closed  and
  889. there is no else part.
  890.  
  891.  
  892. Examples of a select statement:
  893.  
  894.     select
  895.        accept DRIVER_AWAKE_SIGNAL;
  896.     or
  897.        delay 30.0*SECONDS;
  898.        STOP_THE_TRAIN;
  899.     end select;
  900.  
  901.  
  902. Example of a task body with a select statement:
  903.  
  904.     task body RESOURCE is
  905.        BUSY : BOOLEAN := FALSE;
  906.     begin
  907.        loop
  908.           select
  909.              when not BUSY =>
  910.                 accept SEIZE do
  911.                    BUSY := TRUE;
  912.                 end;
  913.           or
  914.              accept RELEASE do
  915.                 BUSY := FALSE;
  916.              end;
  917.           or
  918.              terminate;
  919.           end select;
  920.        end loop;
  921.     end RESOURCE;
  922.  
  923. Notes:
  924.  
  925.  
  926. A  selective  wait  is  allowed to have several open delay alternatives.  A
  927. selective wait is allowed to have several open accept alternatives for  the
  928. same entry.
  929.  
  930.  
  931. References:   accept  statement  9.5, condition 5.3, declaration 3.1, delay
  932. expression 9.6, delay statement 9.6, duration 9.6, entry  9.5,  entry  call
  933. 9.5,  entry index 9.5, program_error exception 11.1, queued entry call 9.5,
  934. rendezvous 9.5, select statement 9.7, sequence of statements 5.1, task 9
  935.  
  936. 9.7.2  Conditional Entry Calls
  937.  
  938.  
  939. A conditional entry call issues an entry call that is then  canceled  if  a
  940. rendezvous is not immediately possible.
  941.  
  942.  
  943.     conditional_entry_call ::=
  944.        select
  945.            entry_call_statement
  946.           [sequence_of_statements]
  947.        else
  948.            sequence_of_statements
  949.        end select;
  950.  
  951.  
  952. For  the  execution  of  a  conditional entry call, the entry name is first
  953. evaluated.  This  is  followed  by  any  evaluations  required  for  actual
  954. parameters as in the case of a subprogram call (see 6.4).
  955.  
  956.  
  957. The  entry  call  is  canceled  if the execution of the called task has not
  958. reached a point where it is ready to accept the call (that  is,  either  an
  959. accept statement for the corresponding entry, or a select statement with an
  960. open  accept alternative for the entry), or if there are prior queued entry
  961. calls for this entry.  If the called task has reached a  select  statement,
  962. the  entry  call is canceled if an accept alternative for this entry is not
  963. selected.
  964.  
  965.  
  966. If the entry call  is  canceled,  the  statements  of  the  else  part  are
  967. executed.   Otherwise,  the  rendezvous  takes  place;   and  the  optional
  968. sequence of statements after the entry call is then executed.
  969.  
  970.  
  971. The  execution  of  a  conditional  entry   call   raises   the   exception
  972. TASKING_ERROR  if  the called task has already completed its execution (see
  973. also 9.10 for the case when the called task becomes abnormal).
  974.  
  975.  
  976. Example:
  977.  
  978.     procedure SPIN(R : RESOURCE) is
  979.     begin
  980.        loop
  981.           select
  982.              R.SEIZE;
  983.              return;
  984.           else
  985.              null;  --  busy waiting
  986.           end select;
  987.        end loop;
  988.     end;
  989.  
  990.  
  991. References:  abnormal task 9.10, accept  statement  9.5,  actual  parameter
  992. part  6.4,  completed task 9.4, entry call statement 9.5, entry family 9.5,
  993. entry index 9.5, evaluation 4.5, expression 4.4,  open  alternative  9.7.1,
  994. queued  entry  call  9.5, rendezvous 9.5, select statement 9.7, sequence of
  995. statements 5.1, task 9, tasking_error exception 11.1
  996.  
  997. 9.7.3  Timed Entry Calls
  998.  
  999.  
  1000. A timed entry call issues an entry call that is canceled if a rendezvous is
  1001. not started within a given delay.
  1002.  
  1003.  
  1004.     timed_entry_call ::=
  1005.  
  1006.       select
  1007.            entry_call_statement
  1008.           [sequence_of_statements]
  1009.        or
  1010.            delay_alternative
  1011.        end select;
  1012.  
  1013.  
  1014. For the execution of a timed entry call, the entry name is first evaluated.
  1015. This is followed by any evaluations required for actual  parameters  as  in
  1016. the  case of a subprogram call (see 6.4).  The expression stating the delay
  1017. is then evaluated, and the entry call is finally issued.
  1018.  
  1019.  
  1020. If  a  rendezvous  can  be  started  within  the  specified  duration   (or
  1021. immediately,  as  for  a  conditional  entry  call,  for a negative or zero
  1022. delay), it is performed and the optional sequence of statements  after  the
  1023. entry  call  is  then executed.  Otherwise, the entry call is canceled when
  1024. the specified duration has expired, and the optional sequence of statements
  1025. of the delay alternative is executed.
  1026.  
  1027.  
  1028. The execution of a timed entry call raises the exception  TASKING_ERROR  if
  1029. the called task completes its execution before accepting the call (see also
  1030. 9.10 for the case when the called task becomes abnormal).
  1031.  
  1032.  
  1033. Example:
  1034.  
  1035.     select
  1036.        CONTROLLER.REQUEST(MEDIUM)(SOME_ITEM);
  1037.     or
  1038.        delay 45.0;
  1039.        --  controller too busy, try something else
  1040.     end select;
  1041.  
  1042.  
  1043. References:   abnormal  task  9.10,  accept statement 9.5, actual parameter
  1044. part  6.4,  completed  task  9.4,  conditional  entry  call  9.7.2,   delay
  1045. expression  9.6,  delay  statement  9.6, duration 9.6, entry call statement
  1046. 9.5, entry family 9.5, entry index 9.5,  evaluation  4.5,  expression  4.4,
  1047. rendezvous 9.5, sequence of statements 5.1, task 9, tasking_error exception
  1048. 11.1
  1049.  
  1050. 9.8  Priorities
  1051.  
  1052.  
  1053. Each  task  may  (but  need  not)  have a priority, which is a value of the
  1054. subtype PRIORITY (of the type INTEGER) declared in the  predefined  library
  1055. package  SYSTEM  (see  13.7).   A  lower  value indicates a lower degree of
  1056. urgency;  the range of priorities is implementation-defined.  A priority is
  1057. associated with a task if a pragma
  1058.  
  1059.     pragma PRIORITY (static_expression);
  1060.  
  1061.  
  1062. appears in the corresponding task specification;  the priority is given  by
  1063. the  value  of  the  expression.   A  priority  is associated with the main
  1064. program if such a pragma appears in its  outermost  declarative  part.   At
  1065. most  one such pragma can appear within a given task specification or for a
  1066. subprogram that is a library unit, and these are the  only  allowed  places
  1067. for  this  pragma.   A  pragma  PRIORITY  has  no  effect if it occurs in a
  1068. subprogram other than the main program.
  1069.  
  1070.  
  1071. The specification of a priority  is  an  indication  given  to  assist  the
  1072. implementation  in the allocation of processing resources to parallel tasks
  1073. when there are more tasks eligible for  execution  than  can  be  supported
  1074. simultaneously  by  the  available  processing  resources.   The  effect of
  1075. priorities on scheduling is defined by the following rule:
  1076.  
  1077.  
  1078.      If two tasks with different priorities are both eligible for execution
  1079.      and could sensibly be executed using the same physical processors  and
  1080.      the  same  other processing resources, then it cannot be the case that
  1081.      the task with the lower priority is executing while the task with  the
  1082.      higher priority is not.
  1083.  
  1084.  
  1085. For  tasks of the same priority, the scheduling order is not defined by the
  1086. language.  For tasks without explicit priority, the  scheduling  rules  are
  1087. not  defined,  except  when such tasks are engaged in a rendezvous.  If the
  1088. priorities  of  both  tasks  engaged  in  a  rendezvous  are  defined,  the
  1089. rendezvous  is executed with the higher of the two priorities.  If only one
  1090. of the two priorities is defined, the rendezvous is executed with at  least
  1091. that  priority.   If  neither is defined, the priority of the rendezvous is
  1092. undefined.
  1093.  
  1094. Notes:
  1095.  
  1096.  
  1097. The priority of a  task  is  static  and  therefore  fixed.   However,  the
  1098. priority  during  a  rendezvous  is  not  necessarily  static since it also
  1099. depends on the priority of the task calling the entry.   Priorities  should
  1100. be  used  only to indicate relative degrees of urgency;  they should not be
  1101. used for task synchronization.
  1102.  
  1103.  
  1104. References:  declarative part 3.9, entry call statement 9.5,  integer  type
  1105. 3.5.4,  main program 10.1, package system 13.7, pragma 2.8, rendezvous 9.5,
  1106. static expression 4.9, subtype 3.3, task 9, task specification 9.1
  1107.  
  1108. 9.9  Task and Entry Attributes
  1109.  
  1110.  
  1111. For a task object or value T the following attributes are defined:
  1112.  
  1113.  
  1114. T'CALLABLE    Yields the  value  FALSE  when  the  execution  of  the  task
  1115.               designated  by  T  is either completed or terminated, or when
  1116.               the task is abnormal.  Yields the value TRUE otherwise.   The
  1117.               value of this attribute is of the predefined type BOOLEAN.
  1118.  
  1119.  
  1120. T'TERMINATED  Yields the  value  TRUE  if  the  task  designated  by  T  is
  1121.               terminated.   Yields the value FALSE otherwise.  The value of
  1122.               this attribute is of the predefined type BOOLEAN.
  1123.  
  1124.  
  1125. In addition, the representation attributes STORAGE_SIZE, SIZE, and  ADDRESS
  1126. are defined for a task object T or a task type T (see 13.7.2).
  1127.  
  1128.  
  1129. The  attribute COUNT is defined for an entry E of a task unit T.  The entry
  1130. can be either a single entry or an entry of a family (in  either  case  the
  1131. name  of  the  single  entry  or  entry family can be either a simple or an
  1132. expanded name).  This attribute is only allowed within the body of  T,  but
  1133. excluding  within any program unit that is, itself, inner to the body of T.
  1134.  
  1135.  
  1136. E'COUNT       Yields the number of entry  calls  presently  queued  on  the
  1137.               entry E (if the attribute is evaluated by the execution of an
  1138.               accept  statement for the entry E, the count does not include
  1139.               the calling task).  The value of this  attribute  is  of  the
  1140.               type universal_integer.
  1141.  
  1142. Note:
  1143.  
  1144.  
  1145. Algorithms  interrogating  the attribute E'COUNT should take precautions to
  1146. allow for the increase of the value of this attribute  for  incoming  entry
  1147. calls, and its decrease, for example with timed entry calls.
  1148.  
  1149.  
  1150. References:   abnormal  task  9.10,  accept statement 9.5, attribute 4.1.4,
  1151. boolean type 3.5.3, completed task 9.4, designate  9.1,  entry  9.5,  false
  1152. boolean  value  3.5.3, queue of entry calls 9.5, storage unit 13.7, task 9,
  1153. task object 9.2, task type 9.1,  terminated  task  9.4,  timed  entry  call
  1154. 9.7.3, true boolean value 3.5.3, universal_integer type 3.5.4
  1155.  
  1156. 9.10  Abort Statements
  1157.  
  1158.  
  1159. An  abort  statement  causes  one  or  more  tasks to become abnormal, thus
  1160. preventing any further rendezvous with such tasks.
  1161.  
  1162.  
  1163.     abort_statement ::= abort task_name {, task_name};
  1164.  
  1165.  
  1166. The determination of the type of each task name uses the fact that the type
  1167. of the name is a task type.
  1168.  
  1169.  
  1170. For the execution of an abort statement, the given task names are evaluated
  1171. in some order that is not defined by the language.  Each  named  task  then
  1172. becomes abnormal unless it is already terminated;  similarly, any task that
  1173. depends  on  a named task becomes abnormal unless it is already terminated.
  1174.  
  1175.  
  1176. Any abnormal task whose execution is suspended at an  accept  statement,  a
  1177. select  statement,  or  a  delay statement becomes completed;  any abnormal
  1178. task whose execution is suspended at an entry call, and that is not yet  in
  1179. a corresponding rendezvous, becomes completed and is removed from the entry
  1180. queue;   any  abnormal task that has not yet started its activation becomes
  1181. completed (and hence also terminated).  This completes the execution of the
  1182. abort statement.
  1183.  
  1184.  
  1185. The completion of any other abnormal task need not happen before completion
  1186. of the abort statement.  It must happen no later  than  when  the  abnormal
  1187. task  reaches a synchronization point that is one of the following: the end
  1188. of its activation;  a point where it causes the activation of another task;
  1189. an entry call; the start or the end  of  an  accept  statement;   a  select
  1190. statement;   a  delay  statement;   an  exception  handler;   or  an  abort
  1191. statement.  If a task that calls an  entry  becomes  abnormal  while  in  a
  1192. rendezvous,  its  termination  does not take place before the completion of
  1193. the rendezvous (see 11.5).
  1194.  
  1195.  
  1196. The call of an entry of an abnormal task raises the exception TASKING_ERROR
  1197. at the place of the call.  Similarly, the exception TASKING_ERROR is raised
  1198. for any task that has called an entry of an abnormal  task,  if  the  entry
  1199. call  is still queued or if the rendezvous is not yet finished (whether the
  1200. entry call is an entry call statement, or  a  conditional  or  timed  entry
  1201. call);   the  exception  is  raised  no  later  than  the completion of the
  1202. abnormal task.  The value of the attribute CALLABLE is FALSE for  any  task
  1203. that is abnormal (or completed).
  1204.  
  1205.  
  1206. If  the  abnormal completion of a task takes place while the task updates a
  1207. variable, then the value of this variable is undefined.  
  1208.  
  1209.  
  1210. Example:
  1211.  
  1212.     abort USER, TERMINAL.all, POOL(3);
  1213.  
  1214. Notes:
  1215.  
  1216.  
  1217. An abort statement should be  used  only  in  extremely  severe  situations
  1218. requiring  unconditional termination.  A task is allowed to abort any task,
  1219. including itself.
  1220.  
  1221.  
  1222. References:  abnormal in rendezvous 11.5, accept statement 9.5,  activation
  1223. 9.3,  attribute  4.1.4,  callable  (predefined  attribute) 9.9, conditional
  1224. entry call 9.7.2, delay statement  9.6,  dependent  task  9.4,  entry  call
  1225. statement  9.5,  evaluation  of  a  name 4.1, exception handler 11.2, false
  1226. boolean value 3.5.3, name 4.1, queue of entry calls  9.5,  rendezvous  9.5,
  1227. select  statement  9.7,  statement 5, task 9, tasking_error exception 11.1,
  1228. terminated task 9.4, timed entry call 9.7.3
  1229.  
  1230. 9.11  Shared Variables
  1231.  
  1232.  
  1233. The normal means of communicating values between tasks is  by  entry  calls
  1234. and accept statements.
  1235.  
  1236.  
  1237. If  two  tasks  read  or  update  a  shared  variable  (that is, a variable
  1238. accessible by both), then neither of them may  assume  anything  about  the
  1239. order  in  which  the  other  performs its operations, except at the points
  1240. where they synchronize.  Two tasks are synchronized at the start and at the
  1241. end of their rendezvous.  At the start and at the end of its activation,  a
  1242. task  is  synchronized  with  the task that causes this activation.  A task
  1243. that has completed its execution is synchronized with any other task.
  1244.  
  1245.  
  1246. For the actions performed by a program  that  uses  shared  variables,  the
  1247. following assumptions can always be made:
  1248.  
  1249.  
  1250.   -  If between two synchronization points of a task,  this  task  reads  a
  1251.      shared  variable  whose  type  is  a  scalar  or access type, then the
  1252.      variable is not updated by any other task at any  time  between  these
  1253.      two points.
  1254.  
  1255.  
  1256.   -  If between two synchronization points of a task, this task  updates  a
  1257.      shared  variable  whose  type  is  a  scalar  or access type, then the
  1258.      variable is neither read nor updated by any other  task  at  any  time
  1259.      between these two points.
  1260.  
  1261.  
  1262. The  execution  of  the program is erroneous if any of these assumptions is
  1263. violated.
  1264.  
  1265.  
  1266. If a given task reads the value of a shared variable, the above assumptions
  1267. allow an implementation to maintain local copies of the value (for example,
  1268. in registers or in some other form of temporary storage);  and for as  long
  1269. as  the  given task neither reaches a synchronization point nor updates the
  1270. value of the shared variable, the above assumptions  imply  that,  for  the
  1271. given  task,  reading  a  local  copy  is  equivalent to reading the shared
  1272. variable itself.
  1273.  
  1274.  
  1275. Similarly, if a given task updates the value  of  a  shared  variable,  the
  1276. above  assumptions  allow an implementation to maintain a local copy of the
  1277. value, and to defer the effective store of the local copy into  the  shared
  1278. variable until a synchronization point, provided that every further read or
  1279. update  of the variable by the given task is treated as a read or update of
  1280. the local copy.  On the other hand, an implementation  is  not  allowed  to
  1281. introduce  a  store,  unless  this  store  would  also  be  executed in the
  1282. canonical order (see 11.6).
  1283.  
  1284.  
  1285. The pragma SHARED can be used to specify that every read  or  update  of  a
  1286. variable  is a synchronization point for that variable;  that is, the above
  1287. assumptions always hold for the given variable  (but  not  necessarily  for
  1288. other variables).  The form of this pragma is as follows:
  1289.  
  1290.     pragma SHARED(variable_simple_name);
  1291.  
  1292.  
  1293. This  pragma  is  allowed  only  for  a  variable  declared  by  an  object
  1294. declaration and whose type is  a  scalar  or  access  type;   the  variable
  1295. declaration  and  the  pragma  must  both occur (in this order) immediately
  1296. within the same declarative part or package specification;  the pragma must
  1297. appear before any occurrence of the name of the variable, other than in  an
  1298. address clause.
  1299.  
  1300.  
  1301. An  implementation must restrict the objects for which the pragma SHARED is
  1302. allowed to objects for which each of direct reading and direct updating  is
  1303. implemented as an indivisible operation.
  1304.  
  1305.  
  1306. References:    accept   statement  9.5,  activation  9.3,  assignment  5.2,
  1307. canonical order 11.6, declarative  part  3.9,  entry  call  statement  9.5,
  1308. erroneous  1.6,  global  8.1, package specification 7.1, pragma 2.8, read a
  1309. value 6.2, rendezvous 9.5, simple name 3.1 4.1, task 9, type 3.3, update  a
  1310. value 6.2, variable 3.2.1
  1311.  
  1312. 9.12  Example of Tasking
  1313.  
  1314.  
  1315. The following example defines a buffering task to smooth variations between
  1316. the  speed  of  output  of  a producing task and the speed of input of some
  1317. consuming  task.   For  instance,  the  producing  task  may  contain   the
  1318. statements
  1319.  
  1320.  
  1321.     loop
  1322.        --  produce the next character CHAR
  1323.        BUFFER.WRITE(CHAR);
  1324.        exit when CHAR = ASCII.EOT;
  1325.     end loop;
  1326.  
  1327.  
  1328. and the consuming task may contain the statements
  1329.  
  1330.  
  1331.     loop
  1332.        BUFFER.READ(CHAR);
  1333.        --  consume the character CHAR
  1334.        exit when CHAR = ASCII.EOT;
  1335.     end loop;
  1336.  
  1337.  
  1338. The  buffering  task contains an internal pool of characters processed in a
  1339. round-robin fashion.  The pool has two indices, an  IN_INDEX  denoting  the
  1340. space  for the next input character and an OUT_INDEX denoting the space for
  1341. the next output character.
  1342.  
  1343.  
  1344.     task BUFFER is
  1345.        entry READ (C : out CHARACTER);
  1346.        entry WRITE(C : in  CHARACTER);
  1347.     end;
  1348.  
  1349.     task body BUFFER is
  1350.        POOL_SIZE : constant INTEGER := 100;
  1351.        POOL      : array(1 .. POOL_SIZE) of CHARACTER;
  1352.        COUNT     : INTEGER range 0 .. POOL_SIZE := 0;
  1353.        IN_INDEX, OUT_INDEX : INTEGER range 1 .. POOL_SIZE := 1;
  1354.     begin
  1355.        loop
  1356.           select
  1357.              when COUNT < POOL_SIZE =>
  1358.                 accept WRITE(C : in CHARACTER) do
  1359.                    POOL(IN_INDEX) := C;
  1360.                 end;
  1361.                 IN_INDEX := IN_INDEX mod POOL_SIZE + 1;
  1362.                 COUNT    := COUNT + 1;
  1363.           or when COUNT > 0 =>
  1364.                 accept READ(C : out CHARACTER) do
  1365.                    C := POOL(OUT_INDEX);
  1366.                 end;
  1367.                 OUT_INDEX := OUT_INDEX mod POOL_SIZE + 1;
  1368.                 COUNT     := COUNT - 1;
  1369.           or
  1370.              terminate;
  1371.           end select;
  1372.        end loop;
  1373.     end BUFFER;
  1374.