home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / s-taskin.ads < prev    next >
Text File  |  1996-09-28  |  28KB  |  697 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                 GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS               --
  4. --                                                                          --
  5. --                        S Y S T E M . T A S K I N G                       --
  6. --                                                                          --
  7. --                                  S p e c                                 --
  8. --                                                                          --
  9. --                             $Revision: 1.27 $                            --
  10. --                                                                          --
  11. --     Copyright (c) 1991,1992,1993,1994,1995 FSU, All Rights Reserved      --
  12. --                                                                          --
  13. -- GNARL is free software; you can redistribute it  and/or modify it  under --
  14. -- terms  of  the  GNU  Library General Public License  as published by the --
  15. -- Free Software  Foundation;  either version 2, or (at  your  option)  any --
  16. -- later  version.  GNARL is distributed  in the hope that  it will be use- --
  17. -- ful, but but WITHOUT ANY WARRANTY;  without even the implied warranty of --
  18. -- MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Gen- --
  19. -- eral Library Public License  for more details.  You should have received --
  20. -- a  copy of the GNU Library General Public License along with GNARL;  see --
  21. -- file COPYING.LIB.  If not,  write to the  Free Software Foundation,  675 --
  22. -- Mass Ave, Cambridge, MA 02139, USA.                                      --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. --  This package provides necessary type definitions for compiler interface.
  27.  
  28. with Ada.Finalization;
  29.  
  30. with System.Task_Primitives;
  31. --  Used for,  Task_Primitives.Lock
  32.  
  33. with System.Compiler_Exceptions;
  34. --  Used for, Exception_ID
  35.  
  36. package System.Tasking is
  37.  
  38.    ---------------------------------
  39.    -- Task_ID related definitions --
  40.    ---------------------------------
  41.  
  42.    type Ada_Task_Control_Block;
  43.  
  44.    type Task_ID is access Ada_Task_Control_Block;
  45.    --  This should be a private type. However, compiler generates internal
  46.    --  while compiling s-taprob.adb
  47.  
  48.    Null_Task : constant Task_ID;
  49.  
  50.    type Task_List is array (Positive range <>) of Task_ID;
  51.  
  52.    function Self return Task_ID;
  53.    pragma Inline (Self);
  54.  
  55.    -----------------------------------
  56.    -- Master_ID related definitions --
  57.    -----------------------------------
  58.  
  59.    type Master_ID is private;
  60.  
  61.    ----------------------------------------------
  62.    -- Task size, interrupt info, priority info --
  63.    ----------------------------------------------
  64.  
  65.    type Task_Storage_Size is new integer;
  66.  
  67.    type Interrupt_ID is range 0 .. 31;
  68.  
  69.    type Size_Type is new Task_Storage_Size;
  70.  
  71.    Unspecified_Size : constant Size_Type := Size_Type'First;
  72.  
  73.    Unspecified_Priority : constant Integer := System.Priority'First - 1;
  74.  
  75.    Priority_Not_Boosted : constant Integer := System.Priority'First - 1;
  76.  
  77.    subtype Rendezvous_Priority is Integer
  78.      range Priority_Not_Boosted .. System.Priority'Last;
  79.  
  80.    -----------------------
  81.    -- Enumeration types --
  82.    -----------------------
  83.  
  84.    type Task_Stage is (
  85.       Created,
  86.       --  Task has been created but has not begun activation.
  87.  
  88.       Can_Activate,
  89.       --  Task has begin activation.
  90.  
  91.       Active,
  92.       --  Task has completed activation and is executing the task body.
  93.  
  94.       Await_Dependents,
  95.       --  Task is trying to complete a task master other than itself,
  96.       --  and is waiting for the tasks dependent on that master to become
  97.       --  passive (be complete, terminated, or be waiting on a terminate
  98.       --  alternative).
  99.  
  100.       Passive,
  101.       --  The task is passive.
  102.  
  103.       Completing,
  104.       --  The task is committed to becoming complete, but has not yet
  105.       --  satisfied all of the conditions for completion. This
  106.       --  acts as a claim to completion; once Stage is set to this value,
  107.       --  no other task can continue with completion.
  108.  
  109.       Complete,
  110.       --  The task is complete. The task and all of its dependents are
  111.       --  passive; some dependents may still be waiting on terminate
  112.       --  alternatives.
  113.  
  114.       Terminated);
  115.       --  The task is terminated. All dependents waiting on terminate
  116.       --  alternatives have been awakened and have terminated themselves.
  117.  
  118.    type Accepting_State is (
  119.       Not_Accepting,   --  task is not ready to accept any entry call
  120.       Trivial_Accept,   --  "accept E;"
  121.       Simple_Accept,    --  "accept E do ... end E;"
  122.       Select_Wait);     --  most general case
  123.  
  124.    type Call_Modes is (Simple_Call, Conditional_Call, Asynchronous_Call);
  125.  
  126.    type Select_Modes is (Simple_Mode, Else_Mode, Terminate_Mode);
  127.  
  128.    -----------------------------------
  129.    -- ATC_Level related definitions --
  130.    -----------------------------------
  131.  
  132.    Max_ATC_Nesting : constant Natural := 20;
  133.  
  134.    subtype ATC_Level_Base is Integer range 0 .. Max_ATC_Nesting;
  135.  
  136.    ATC_Level_Infinity : constant ATC_Level_Base := ATC_Level_Base'Last;
  137.  
  138.    subtype ATC_Level is ATC_Level_Base range
  139.      ATC_Level_Base'First .. ATC_Level_Base'Last - 1;
  140.  
  141.    subtype ATC_Level_Index is ATC_Level
  142.      range ATC_Level'First + 1 .. ATC_Level'Last;
  143.  
  144.    -------------------------------
  145.    -- Entry related definitions --
  146.    -------------------------------
  147.  
  148.    Null_Entry : constant := 0;
  149.  
  150.    Max_Entry : constant := Integer'Last;
  151.  
  152.    Interrupt_Entry : constant := -2;
  153.  
  154.    Cancelled_Entry : constant := -1;
  155.  
  156.    type Entry_Index is range Interrupt_Entry .. Max_Entry;
  157.  
  158.    type Entry_Call_Record;
  159.  
  160.    type Entry_Call_Link is access all Entry_Call_Record;
  161.  
  162.    type Entry_Queue is record
  163.       Head : Entry_Call_Link;
  164.       Tail : Entry_Call_Link;
  165.    end record;
  166.  
  167.    ----------------------------
  168.    -- PO related definitions --
  169.    ----------------------------
  170.  
  171.    Null_Protected_Entry : constant := Null_Entry;
  172.  
  173.    Max_Protected_Entry : constant := Max_Entry;
  174.  
  175.    type Protected_Entry_Index is new Entry_Index
  176.      range Null_Protected_Entry .. Max_Protected_Entry;
  177.  
  178.    subtype Positive_Protected_Entry_Index is
  179.      Protected_Entry_Index range  1 .. Protected_Entry_Index'Last;
  180.  
  181.    type Protection (Num_Entries : Protected_Entry_Index) is private;
  182.    --  This type contains the GNARL state of a protected object. The
  183.    --  application-defined portion of the state (i.e. private objects)
  184.    --  is maintained by the compiler-generated code.
  185.  
  186.    type Protection_Access is access all Protection;
  187.  
  188.    Null_PO : constant Protection_Access := null;
  189.  
  190.    type Communication_Block is private;
  191.    --  Objects of this type are passed between GNARL calls to allow RTS
  192.    --  information to be preserved.
  193.  
  194.    ------------------------------------
  195.    -- Rendezvous related definitions --
  196.    ------------------------------------
  197.  
  198.    Null_Task_Entry : constant := Null_Entry;
  199.  
  200.    Max_Task_Entry : constant := Max_Entry;
  201.  
  202.    type Task_Entry_Index is new Entry_Index
  203.      range Null_Task_Entry .. Max_Task_Entry;
  204.  
  205.    type Task_Entry_Queue_Array is
  206.      array (Task_Entry_Index range <>) of
  207.      Entry_Queue;
  208.  
  209.    No_Rendezvous : constant := 0;
  210.  
  211.    Max_Select : constant Integer := Integer'Last;
  212.    --  RTS-defined
  213.  
  214.    subtype Select_Index is Integer range No_Rendezvous .. Max_Select;
  215.    --   type Select_Index is range No_Rendezvous .. Max_Select;
  216.  
  217.    subtype Positive_Select_Index is
  218.      Select_Index range 1 .. Select_Index'Last;
  219.  
  220.    type Accept_Alternative is record --  should be packed
  221.       Null_Body : Boolean;
  222.       S : Task_Entry_Index;
  223.    end record;
  224.  
  225.    type Accept_List is
  226.      array (Positive_Select_Index range <>) of Accept_Alternative;
  227.  
  228.    type Accept_List_Access is access constant Accept_List;
  229.  
  230.    ----------------------------------
  231.    -- Entry_Call_Record definition --
  232.    ----------------------------------
  233.  
  234.    type Entry_Call_Record is record
  235.  
  236.       Prev : Entry_Call_Link;
  237.       Next : Entry_Call_Link;
  238.  
  239.       Self  : Task_ID;
  240.       Level : ATC_Level;
  241.       --  One of Self and Level are redundant in this implementation, since
  242.       --  each Entry_Call_Record is at Self.Entry_Calls (Level). Since we must
  243.       --  have access to the entry call record to be reading this, we could
  244.       --  get Self from Level, or Level from Self. However, this requires
  245.       --  non-portable address arithmetic.
  246.  
  247.       Mode : Call_Modes;
  248.  
  249.       Abortable : Boolean;
  250.       --  This call is queued abortably.
  251.       --  Protection: Acceptor.L. If the call is not on a queue, it should
  252.       --  only be accessed by the task doing the call or requeue, and the
  253.       --  mutex need not be locked in those cases.
  254.  
  255.       Done : Boolean;
  256.       --  The call has been completed.
  257.       --  Protection : Self.L, except in certain circumstances where
  258.       --  Self knows that the acceptor is suspended waiting for a call,
  259.       --  and Self holds the acceptor's mutex.
  260.  
  261.       Has_Been_Abortable : Boolean;
  262.       --  The call has been blocked abortably at some point.
  263.       --  Currently only used for protected entry calls.
  264.       --  Protection: Called_PO.L.
  265.  
  266.       E : Entry_Index;
  267.  
  268.       Prio : System.Any_Priority;
  269.  
  270.       --  The above fields are those that there may be some hope of packing.
  271.       --  They are gathered together to allow for compilers that lay records
  272.       --  out contiguously, to allow for such packing.
  273.  
  274.       Uninterpreted_Data : System.Address;
  275.  
  276.       Exception_To_Raise : System.Compiler_Exceptions.Exception_ID;
  277.       --  The exception to raise once this call has been completed without
  278.       --  being aborted.
  279.  
  280.       --  Server : Server_Record;
  281.  
  282.       Called_Task : Task_ID;
  283.       --  For task entry calls only. Only one of Called_Task and Called_PO
  284.       --  are valid; the other must be Null_Task or null, respectively.
  285.       --  In general, Called_Task must be either a legitimate Task_ID or
  286.       --  Null_Task.  Both Called_Task and Called_PO must be null
  287.       --  if the call record is not in use.
  288.       --  Protection:  Called_Task.L. There are situations in which
  289.       --  it is necessary to access this field given only an Entry_Call_Record.
  290.       --  This is difficult, since Called_Task.L must be locked to access
  291.       --  Called_Task. This is done by doing the lock and then checking
  292.       --  to make sure that Called_Task has not changed; see
  293.       --  System.Tasking.Utilities.Lock_Server.
  294.  
  295.       Acceptor_Prev_Call : Entry_Call_Link;
  296.       --  For task entry calls only.
  297.  
  298.       Acceptor_Prev_Priority : Rendezvous_Priority;
  299.       --  For task entry calls only.
  300.       --  The priority of the most recent prior call being serviced.
  301.       --  For protected entry calls, this function should be performed by
  302.       --  GNULLI ceiling locking.
  303.  
  304.       Called_PO : Protection_Access;
  305.       --  For protected entry calls only. Only one of Called_Task and
  306.       --  Called_PO are valid; the other must be Null_Task or Null_PO,
  307.       --  respectively. In general, Called_PO must be either a legitimate
  308.       --  Protection_Access value or null.  Both Called_Task and
  309.       --  Called_PO must be null if the call record is not in use.
  310.       --  Protection: Called_PO.L. See notes under Called_Task, above.
  311.  
  312.    end record;
  313.  
  314.    ------------------------------------
  315.    -- Task related other definitions --
  316.    ------------------------------------
  317.  
  318.    type Activation_Chain is limited private;
  319.  
  320.    type Activation_Chain_Access is access all Activation_Chain;
  321.  
  322.    type Task_Procedure_Access is access procedure (Arg : System.Address);
  323.  
  324.    type Access_Boolean is access all Boolean;
  325.  
  326.    ----------------------------------------------
  327.    -- Ada_Task_Control_Block (ATCB) definition --
  328.    ----------------------------------------------
  329.  
  330.    type Entry_Call_Array is array (ATC_Level_Index) of
  331.      aliased Entry_Call_Record;
  332.  
  333.    --  Notes on protection (synchronization) of TRTS data structures.
  334.  
  335.    --  Any field of the TCB can be written by the activator of a task when the
  336.    --  task is created, since no other task can access the new task's
  337.    --  state until creation is complete.
  338.  
  339.    --  The protection for each field is described in a comment starting with
  340.    --  "Protection:".
  341.  
  342.    --  When a lock is used to protect an ATCB field, this lock is simply named.
  343.  
  344.    --  Some protection is described in terms of tasks related to the
  345.    --  ATCB being protected. These are:
  346.  
  347.    --    Self: The task which is controlled by this ATCB.
  348.    --    Acceptor: A task accepting a call from Self.
  349.    --    Caller: A task calling an entry of Self.
  350.    --    Parent: The task executing the master on which Self depends.
  351.    --    Dependent: A task dependent on Self.
  352.    --    Activator: The task that created Self and initiated its activation.
  353.    --    Created: A task created and activated by Self.
  354.  
  355.    type Ada_Task_Control_Block (Entry_Num : Task_Entry_Index) is record
  356.  
  357.       LL_TCB : aliased System.Task_Primitives.Task_Control_Block;
  358.       --  Control block used by the underlying low-level tasking service
  359.       --  (GNULLI).
  360.       --  Protection: This is used only by the GNULLI implementation, which
  361.       --  takes care of all of its synchronization.
  362.  
  363.       Task_Entry_Point : Task_Procedure_Access;
  364.       --  Information needed to call the procedure containing the code for
  365.       --  the body of this task.
  366.       --  Protection: Part of the synchronization between Self and
  367.       --  Activator. Activator writes it, once, before Self starts
  368.       --  executing. Self reads it, once, as part of its execution.
  369.  
  370.       Task_Arg : System.Address;
  371.       --  The argument to to task procedure. Currently unused; this will
  372.       --  provide a handle for discriminant information.
  373.       --  Protection: Part of the synchronization between Self and
  374.       --  Activator. Activator writes it, once, before Self starts
  375.       --  executing. Thereafter, Self only reads it.
  376.  
  377.       Stack_Size : Size_Type;
  378.       --  Requested stack size.
  379.       --  Protection: Only used by Self.
  380.  
  381.       Current_Priority : System.Priority;
  382.       --  Active priority, except that the effects of protected object
  383.       --  priority ceilings are not reflected. This only reflects explicit
  384.       --  priority changes and priority inherited through task activation
  385.       --  and rendezvous.
  386.       --  Ada 95 notes: In Ada 95, this field will be transferred to the
  387.       --  Priority field of an Entry_Calls component when an entry call
  388.       --  is initiated. The Priority of the Entry_Calls component will not
  389.       --  change for the duration of the call. The accepting task can
  390.       --  use it to boost its own priority without fear of its changing in
  391.       --  the meantime.
  392.       --  This can safely be used in the priority ordering
  393.       --  of entry queues. Once a call is queued, its priority does not
  394.       --  change.
  395.       --  Since an entry call cannot be made while executing
  396.       --  a protected action, the priority of a task will never reflect a
  397.       --  priority ceiling change at the point of an entry call.
  398.       --  Protection: Only written by Self, and only accessed when Acceptor
  399.       --  accepts an entry or when Created activates, at which points Self is
  400.       --  suspended.
  401.  
  402.       Base_Priority : System.Priority;
  403.       --  Base priority, not changed during entry calls, only changed
  404.       --  via dynamic priorities package.
  405.       --  Protection: Only written by Self, accessed by anyone.
  406.  
  407.       New_Base_Priority : System.Priority;
  408.       --  New value for Base_Priority (for dynamic priorities package).
  409.       --  Protection: Self.L.
  410.  
  411.       L : System.Task_Primitives.Lock;
  412.       --  General purpose lock; protects most fields in the ATCB.
  413.  
  414.       Compiler_Data : System.Address;
  415.       --  Untyped task-specific data needed by the compiler to store
  416.       --  per-task structures.
  417.       --  Protection: Only accessed by Self.
  418.  
  419.       --  the following declarations are for Rendezvous
  420.  
  421.       Cond : System.Task_Primitives.Condition_Variable;
  422.       --  Used by Self to wait for a condition to become true.
  423.       --  It is invariant in the GNARL that a task waits only on its
  424.       --  own condition variable.
  425.       --  Protection: Condition variables are always associated with a lock.
  426.       --  The runtime places no restrictions on which lock is used, except
  427.       --  that it must protection the condition upon which the task is waiting.
  428.  
  429.       All_Tasks_Link : Task_ID;
  430.       --  Used to link this task to the list of all tasks in the system.
  431.       --  Protection: All_Tasks.L.
  432.  
  433.       Global_Task_Lock_Nesting : Natural;
  434.       --  This is the current nesting level of calls to
  435.       --  System.Tasking.Stages.Lock_Task_T.
  436.       --  This allows a task to call Lock_Task_T multiple times without
  437.       --  deadlocking. A task only locks All_Task_Lock when its
  438.       --  All_Tasks_Nesting goes from 0 to 1, and only unlocked when it
  439.       --  goes from 1 to 0.
  440.       --  Protection: Only accessed by Self.
  441.  
  442.       Activation_Link : Task_ID;
  443.       --  Used to link this task to a list of tasks to be activated.
  444.       --  Protection: Only used by Activator.
  445.  
  446.       Open_Accepts : Accept_List_Access;
  447.       --  This points to the Open_Accepts array of accept alternatives passed
  448.       --  to the RTS by the compiler-generated code to Selective_Wait.
  449.       --  Protection: Self.L.
  450.  
  451.       Exception_To_Raise : System.Compiler_Exceptions.Exception_ID;
  452.       Exception_Address : System.Address;
  453.       --  An exception which should be raised by this task when it regains
  454.       --  control, and the address at which it should be raised.
  455.       --  Protection: Read only by Self, under circumstances where it will
  456.       --  be notified by the writer when it is safe to read it:
  457.       --  1. Written by Acceptor, when Self is suspended.
  458.       --  2. Written by Notify_Exception, executed by Self through a
  459.       --     synchronous signal handler, which redirects control to a
  460.       --     routine to read it and raise the exception.
  461.  
  462.       Chosen_Index : Select_Index;
  463.       --  The index in Open_Accepts of the entry call accepted by a selective
  464.       --  wait executed by this task.
  465.       --  Protection: Written by both Self and Caller. Usually protected
  466.       --  by Self.L. However, once the selection is known to have been
  467.       --  written it can be accessed without protection. This happens
  468.       --  after Self has updated it itself using information from a suspended
  469.       --  Caller, or after Caller has updated it and awakened Self.
  470.  
  471.       Call : Entry_Call_Link;
  472.       --  The entry call that has been accepted by this task.
  473.       --  Protection: Self.L. Self will modify this field
  474.       --  when Self.Accepting is False, and will not need the mutex to do so.
  475.       --  Once a task sets Stage=Completing, no other task can access this
  476.       --  field.
  477.  
  478.       --  The following fields are used to manage the task's life cycle.
  479.  
  480.       Activator : Task_ID;
  481.       --  The task that created this task, either by declaring it as a task
  482.       --  object or by executing a task allocator.
  483.       --  Protection: Set by Activator before Self is activated, and
  484.       --  read after Self is activated.
  485.  
  486.       Parent : Task_ID;
  487.       Master_of_Task : Master_ID;
  488.       --  The task executing the master of this task, and the ID of this task's
  489.       --  master (unique only among masters currently active within Parent).
  490.       --  Protection: Set by Activator before Self is activated, and
  491.       --  read after Self is activated.
  492.  
  493.       Master_Within : Master_ID;
  494.       --  The ID of the master currently executing within this task; that is,
  495.       --  the most deeply nested currently active master.
  496.       --  Protection: Only written by Self, and only read by Self or by
  497.       --  dependents when Self is attempting to exit a master. Since Self
  498.       --  will not write this field until the master is complete, the
  499.       --  synchronization should be adequate to prevent races.
  500.  
  501.       Activation_Count : Integer;
  502.       --  This is the number of tasks that this task is activating, i.e. the
  503.       --  children that have started activation but have not completed it.
  504.       --  Protection: Self.L and Created.L. Both mutexes must be locked,
  505.       --  since Self.Activation_Count and Created.Stage must be synchronized.
  506.  
  507.       Awake_Count : Integer;
  508.       --  Number of tasks dependent on this task (including this task) that are
  509.       --  still "awake": not terminated and not waiting on a terminate
  510.       --  alternative.
  511.       --  Protection: Self.L. Parent.L must also be locked when this is
  512.       --  updated, so that it can be synchronized with
  513.       --  Parent.Awaited_Dependent_Count, except under special circumstances
  514.       --  where we know that the two can be out of sync without allowing the
  515.       --  parent to terminate before its dependents.
  516.  
  517.       Awaited_Dependent_Count : Integer;
  518.       --  This is the awake count of a master being completed by this task.
  519.       --  Protection: Self.L. Dependent.L must also be locked so that
  520.       --  this field and Dependent.Awake_Count can be synchronized, except
  521.       --  under special circumstances where we know that the two can be out
  522.       --  of sync without allowing the parent to terminate before its
  523.       --  dependents.
  524.  
  525.       Terminating_Dependent_Count : Integer;
  526.       --  This is the count of tasks dependent on a master being completed by
  527.       --  this task which are waiting on a terminate alternative. Only valid
  528.       --  when there none of the dependents are awake.
  529.       --  Protection: Self.L.
  530.  
  531.       Pending_Priority_Change : Boolean;
  532.       --  Flag to indicate pending priority change (for dynamic priorities
  533.       --  package). The base priority is updated on the next abortion
  534.       --  completion point (aka. synchronization point).
  535.       --  Protection: Self.L.
  536.  
  537.       Pending_Action : Boolean;
  538.       --  Unified flag indicating pending action on abortion completion
  539.       --  point (aka. synchronization point). Currently set if:
  540.       --  . Pending_Priority_Change is set or
  541.       --  . Pending_ATC_Level is changed.
  542.       --  Protection: Self.L.
  543.  
  544.       Pending_ATC_Level : ATC_Level_Base;
  545.       --  The ATC level to which this task is currently being aborted.
  546.       --  Protection: Self.L.
  547.  
  548.       ATC_Nesting_Level : ATC_Level;
  549.       --  The dynamic level of ATC nesting (currently executing nested
  550.       --  asynchronous select statements) in this task.
  551.       --  Protection: This is only used by Self. However, decrementing it
  552.       --  in effect deallocates an Entry_Calls component, and care must be
  553.       --  taken that all references to that component are eliminated before
  554.       --  doing the decrement. This in turn will probably required locking
  555.       --  a protected object (for a protected entry call) or the Acceptor's
  556.       --  lock (for a task entry call). However, ATC_Nesting_Level itself can
  557.       --  be accessed without a lock.
  558.  
  559.       Deferral_Level : Natural;
  560.       --  This is the number of times that Defer_Abortion has been called by
  561.       --  this task without a matching Undefer_Abortion call. Abortion is
  562.       --  only allowed when this zero.
  563.       --  Protection: Only updated by Self; access assumed to be atomic.
  564.  
  565.       Elaborated : Access_Boolean;
  566.       --  Pointer to a flag indicating that this task's body has been
  567.       --  elaborated. The flag is created and managed by the
  568.       --  compiler-generated code.
  569.       --  Protection: The field itself is only accessed by Activator. The flag
  570.       --  that it points to is updated by Master and read by Activator; access
  571.       --  is assumed to be atomic.
  572.  
  573.       Stage : Task_Stage;
  574.       --  The general stage of the task in it's life cycle.
  575.       --  Protection: Self.L.
  576.  
  577.       --  beginning of flags
  578.  
  579.       Cancel_Was_Successful : Boolean;
  580.       --  This indicates that the last attempt to cancel an entry call was
  581.       --  successful. It needs to be accurate between a call to
  582.       --  *Cancel_*_Entry_Call and the following call to Complete_*_Entry_Call.
  583.       --  These calls cannot be nested; that is, there can be no intervening
  584.       --  *Cancel_*_Entry_Call, so this single field is adequate.
  585.       --  Protection: Accessed only by Self.
  586.  
  587.       Accepting : Accepting_State;
  588.       --  The ability of this task to accept an entry call.
  589.       --  Protection: Self.L.
  590.  
  591.       Aborting : Boolean;
  592.       --  Self is in the process of aborting. While set, prevents multiple
  593.       --  abortion signals from being sent by different aborter while abortion
  594.       --  is acted upon. This is essential since an aborter which calls
  595.       --  Abort_To_Level could set the Pending_ATC_Level to yet a lower level
  596.       --  (than the current level), may be preempted and would send the
  597.       --  abortion signal when resuming execution. At this point, the abortee
  598.       --  may have completed abortion to the proper level such that the
  599.       --  signal (and resulting abortion exception) are not handled any more.
  600.       --  In other words, the flag prevents a race between multiple aborters
  601.       --  and the abortee.
  602.       --  Protection: Self.L.
  603.  
  604.       --  end of flags
  605.  
  606.       Entry_Calls : Entry_Call_Array;
  607.       --  An array of entry calls.
  608.       --  Protection: The elements of this array are on entry call queues
  609.       --  associated with protected objects or task entries, and are protected
  610.       --  by the protected object lock or Acceptor.L, respectively.
  611.  
  612.       Entry_Queues : Task_Entry_Queue_Array (1 .. Entry_Num);
  613.       --  An array of task entry queues.
  614.       --  Protection: Self.L. Once a task has set Self.Stage to Completing, it
  615.       --  has exclusive access to this field.
  616.  
  617.       Aborter_Link : Task_ID;
  618.       --  Link to the list of tasks which tries to abort this task but
  619.       --  blocked by another aborter who has already been aborting the task.
  620.  
  621.       Terminate_Alternative : Boolean;
  622.       --  Task is accepting Select with Terminate Alternative.
  623.  
  624.    end record;
  625.  
  626.    type Barrier_Function_Pointer is access
  627.      function
  628.        (O : System.Address;
  629.         E : Protected_Entry_Index)
  630.         return Boolean;
  631.    --  Pointer to a function which evaluates the barrier of a protected
  632.    --  entry body. O is a pointer to the compiler-generated record
  633.    --  representing the protected object, and E is the index of the
  634.    --  entry serviced by the body.
  635.  
  636.    type Entry_Action_Pointer is access
  637.      procedure
  638.        (O : System.Address;
  639.         P : System.Address;
  640.         E : Protected_Entry_Index);
  641.    --  Pointer to a procedure which executes the sequence of statements
  642.    --  of a protected entry body. O is a pointer to the compiler-generated
  643.    --  record representing the protected object, P is a pointer to the
  644.    --  record of entry parameters, and E is the index of the
  645.    --  entry serviced by the body.
  646.  
  647.    type Entry_Body is record
  648.       Barrier : Barrier_Function_Pointer;
  649.       Action  : Entry_Action_Pointer;
  650.    end record;
  651.    --  The compiler-generated code passes objects of this type to the GNARL
  652.    --  to allow it to access the executable code of an entry body.
  653.  
  654.    type Protected_Entry_Body_Array is
  655.      array (Positive_Protected_Entry_Index range <>) of Entry_Body;
  656.    --  This is an array of the executable code for all entry bodies of
  657.    --  a protected type.
  658.  
  659.    type Protected_Entry_Body_Access is access all Protected_Entry_Body_Array;
  660.  
  661. private
  662.  
  663.    Null_Task : constant Task_ID := null;
  664.  
  665.    type Activation_Chain is new Task_ID;
  666.  
  667.    type Master_ID is new Integer;
  668.  
  669.    type Communication_Block is record
  670.       Self      : Task_ID;
  671.       Enqueued  : Boolean := False;
  672.       Cancelled : Boolean;
  673.    end record;
  674.  
  675.    type Protected_Entry_Queue_Array is
  676.         array (Protected_Entry_Index range <>) of
  677.         Entry_Queue;
  678.  
  679.    type Protection (Num_Entries : Protected_Entry_Index) is new
  680.      Ada.Finalization.Controlled
  681.    with record
  682.         L                 : Task_Primitives.Lock;
  683.         Compiler_Info     : System.Address;
  684.         Call_In_Progress  : Entry_Call_Link;
  685.         Ceiling           : System.Priority;
  686.         Old_Base_Priority : System.Priority;
  687.         Pending_Action    : Boolean;
  688.         Entry_Bodies      : Protected_Entry_Body_Access;
  689.         Entry_Queues      : Protected_Entry_Queue_Array (1 .. Num_Entries);
  690.    end record;
  691.  
  692.    procedure Finalize (Object : in out Protection);
  693.    --  Clean up a Protection object; in particular, finalize the associated
  694.    --  Lock object.
  695.  
  696. end System.Tasking;
  697.