File : s-tassta.ads


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
   4 --                                                                          --
   5 --                 S Y S T E M . T A S K I N G . S T A G E S                --
   6 --                                                                          --
   7 --                                  S p e c                                 --
   8 --                                                                          --
   9 --          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNARL is free software; you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNARL was developed by the GNARL team at Florida State University.       --
  28 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 --  This package represents the high level tasking interface used by the
  33 --  compiler to expand Ada 95 tasking constructs into simpler run time calls
  34 --  (aka GNARLI, GNU Ada Run-time Library Interface)
  35 
  36 --  Note: Only the compiler is allowed to use this interface, by generating
  37 --  direct calls to it, via Rtsfind.
  38 
  39 --  Any changes to this interface may require corresponding compiler changes
  40 --  in exp_ch9.adb and possibly exp_ch7.adb
  41 
  42 with System.Task_Info;
  43 with System.Parameters;
  44 
  45 with Ada.Real_Time;
  46 
  47 package System.Tasking.Stages is
  48    pragma Elaborate_Body;
  49 
  50    --   The compiler will expand in the GNAT tree the following construct:
  51 
  52    --   task type T (Discr : Integer);
  53 
  54    --   task body T is
  55    --      ...declarations, possibly some controlled...
  56    --   begin
  57    --      ...B...;
  58    --   end T;
  59 
  60    --   T1 : T (1);
  61 
  62    --  as follows:
  63 
  64    --   enter_master.all;
  65 
  66    --   _chain : aliased activation_chain;
  67    --   activation_chainIP (_chain);
  68 
  69    --   task type t (discr : integer);
  70    --   tE : aliased boolean := false;
  71    --   tZ : size_type := unspecified_size;
  72    --   type tV (discr : integer) is limited record
  73    --      _task_id : task_id;
  74    --   end record;
  75    --   procedure tB (_task : access tV);
  76    --   freeze tV [
  77    --      procedure tVIP (_init : in out tV; _master : master_id;
  78    --        _chain : in out activation_chain; _task_id : in task_image_type;
  79    --        discr : integer) is
  80    --      begin
  81    --         _init.discr := discr;
  82    --         _init._task_id := null;
  83    --         create_task (unspecified_priority, tZ,
  84    --           unspecified_task_info, unspecified_cpu,
  85    --           ada__real_time__time_span_zero, 0, _master,
  86    --           task_procedure_access!(tB'address), _init'address,
  87    --           tE'unchecked_access, _chain, _task_id, _init._task_id);
  88    --         return;
  89    --      end tVIP;
  90    --   ]
  91 
  92    --   procedure tB (_task : access tV) is
  93    --      discr : integer renames _task.discr;
  94 
  95    --      procedure _clean is
  96    --      begin
  97    --         abort_defer.all;
  98    --         complete_task;
  99    --         finalize_list (F14b);
 100    --         abort_undefer.all;
 101    --         return;
 102    --      end _clean;
 103    --   begin
 104    --      abort_undefer.all;
 105    --      ...declarations...
 106    --      complete_activation;
 107    --      ...B...;
 108    --      return;
 109    --   at end
 110    --      _clean;
 111    --   end tB;
 112 
 113    --   tE := true;
 114    --   t1 : t (1);
 115    --   _master : constant master_id := current_master.all;
 116    --   t1S : task_image_type := new string'"t1";
 117    --   task_image_typeIP (t1, _master, _chain, t1S, 1);
 118 
 119    --   activate_tasks (_chain'unchecked_access);
 120 
 121    procedure Abort_Tasks (Tasks : Task_List);
 122    --  Compiler interface only. Do not call from within the RTS. Initiate
 123    --  abort, however, the actual abort is done by abortee by means of
 124    --  Abort_Handler and Abort_Undefer
 125    --
 126    --  source code:
 127    --     Abort T1, T2;
 128    --  code expansion:
 129    --     abort_tasks (task_list'(t1._task_id, t2._task_id));
 130 
 131    procedure Activate_Tasks (Chain_Access : Activation_Chain_Access);
 132    --  Compiler interface only. Do not call from within the RTS.
 133    --  This must be called by the creator of a chain of one or more new tasks,
 134    --  to activate them. The chain is a linked list that up to this point is
 135    --  only known to the task that created them, though the individual tasks
 136    --  are already in the All_Tasks_List.
 137    --
 138    --  The compiler builds the chain in LIFO order (as a stack). Another
 139    --  version of this procedure had code to reverse the chain, so as to
 140    --  activate the tasks in the order of declaration. This might be nice, but
 141    --  it is not needed if priority-based scheduling is supported, since all
 142    --  the activated tasks synchronize on the activators lock before they
 143    --  start activating and so they should start activating in priority order.
 144    --  ??? Actually, the body of this package DOES reverse the chain, so I
 145    --  don't understand the above comment.
 146 
 147    procedure Complete_Activation;
 148    --  Compiler interface only. Do not call from within the RTS.
 149    --  This should be called from the task body at the end of
 150    --  the elaboration code for its declarative part.
 151    --  Decrement the count of tasks to be activated by the activator and
 152    --  wake it up so it can check to see if all tasks have been activated.
 153    --  Except for the environment task, which should never call this procedure,
 154    --  T.Activator should only be null iff T has completed activation.
 155 
 156    procedure Complete_Master;
 157    --  Compiler interface only.  Do not call from within the RTS. This must
 158    --  be called on exit from any master where Enter_Master was called.
 159    --  Assume abort is deferred at this point.
 160 
 161    procedure Complete_Task;
 162    --  Compiler interface only. Do not call from within the RTS.
 163    --  This should be called from an implicit at-end handler
 164    --  associated with the task body, when it completes.
 165    --  From this point, the current task will become not callable.
 166    --  If the current task have not completed activation, this should be done
 167    --  now in order to wake up the activator (the environment task).
 168 
 169    procedure Create_Task
 170      (Priority          : Integer;
 171       Size              : System.Parameters.Size_Type;
 172       Task_Info         : System.Task_Info.Task_Info_Type;
 173       CPU               : Integer;
 174       Relative_Deadline : Ada.Real_Time.Time_Span;
 175       Domain            : Dispatching_Domain_Access;
 176       Num_Entries       : Task_Entry_Index;
 177       Master            : Master_Level;
 178       State             : Task_Procedure_Access;
 179       Discriminants     : System.Address;
 180       Elaborated        : Access_Boolean;
 181       Chain             : in out Activation_Chain;
 182       Task_Image        : String;
 183       Created_Task      : out Task_Id);
 184    --  Compiler interface only. Do not call from within the RTS.
 185    --  This must be called to create a new task.
 186    --
 187    --  Priority is the task's priority (assumed to be in range of type
 188    --   System.Any_Priority)
 189    --  Size is the stack size of the task to create
 190    --  Task_Info is the task info associated with the created task, or
 191    --   Unspecified_Task_Info if none.
 192    --  CPU is the task affinity. Passed as an Integer because the undefined
 193    --   value is not in the range of CPU_Range. Static range checks are
 194    --   performed when analyzing the pragma, and dynamic ones are performed
 195    --   before setting the affinity at run time.
 196    --  Relative_Deadline is the relative deadline associated with the created
 197    --   task by means of a pragma Relative_Deadline, or 0.0 if none.
 198    --  Domain is the dispatching domain associated with the created task by
 199    --   means of a Dispatching_Domain pragma or aspect, or null if none.
 200    --  State is the compiler generated task's procedure body
 201    --  Discriminants is a pointer to a limited record whose discriminants
 202    --   are those of the task to create. This parameter should be passed as
 203    --   the single argument to State.
 204    --  Elaborated is a pointer to a Boolean that must be set to true on exit
 205    --   if the task could be successfully elaborated.
 206    --  Chain is a linked list of task that needs to be created. On exit,
 207    --   Created_Task.Activation_Link will be Chain.T_ID, and Chain.T_ID
 208    --   will be Created_Task (e.g the created task will be linked at the front
 209    --   of Chain).
 210    --  Task_Image is a string created by the compiler that the
 211    --   run time can store to ease the debugging and the
 212    --   Ada.Task_Identification facility.
 213    --  Created_Task is the resulting task.
 214    --
 215    --  This procedure can raise Storage_Error if the task creation failed.
 216 
 217    function Current_Master return Master_Level;
 218    --  Compiler interface only.
 219    --  This is called to obtain the current master nesting level.
 220 
 221    procedure Enter_Master;
 222    --  Compiler interface only.  Do not call from within the RTS.
 223    --  This must be called on entry to any "master" where a task,
 224    --  or access type designating objects containing tasks, may be
 225    --  declared.
 226 
 227    procedure Expunge_Unactivated_Tasks (Chain : in out Activation_Chain);
 228    --  Compiler interface only. Do not call from within the RTS.
 229    --  This must be called by the compiler-generated code for an allocator if
 230    --  the allocated object contains tasks, if the allocator exits without
 231    --  calling Activate_Tasks for a given activation chains, as can happen if
 232    --  an exception occurs during initialization of the object.
 233    --
 234    --  This should be called ONLY for tasks created via an allocator. Recovery
 235    --  of storage for unactivated local task declarations is done by
 236    --  Complete_Master and Complete_Task.
 237    --
 238    --  We remove each task from Chain and All_Tasks_List before we free the
 239    --  storage of its ATCB.
 240    --
 241    --  In other places where we recover the storage of unactivated tasks, we
 242    --  need to clean out the entry queues, but here that should not be
 243    --  necessary, since these tasks should not have been visible to any other
 244    --  tasks, and so no task should be able to queue a call on their entries.
 245    --
 246    --  Just in case somebody misuses this subprogram, there is a check to
 247    --  verify this condition.
 248 
 249    procedure Finalize_Global_Tasks;
 250    --  This should be called to complete the execution of the environment task
 251    --  and shut down the tasking runtime system. It is the equivalent of
 252    --  Complete_Task, but for the environment task.
 253    --
 254    --  The environment task must first call Complete_Master, to wait for user
 255    --  tasks that depend on library-level packages to terminate. It then calls
 256    --  Abort_Dependents to abort the "independent" library-level server tasks
 257    --  that are created implicitly by the RTS packages (signal and timer server
 258    --  tasks), and then waits for them to terminate. Then, it calls
 259    --  Vulnerable_Complete_Task.
 260    --
 261    --  It currently also executes the global finalization list, and then resets
 262    --  the "soft links".
 263 
 264    procedure Free_Task (T : Task_Id);
 265    --  Recover all runtime system storage associated with the task T, but only
 266    --  if T has terminated. Do nothing in the other case. It is called from
 267    --  Unchecked_Deallocation, for objects that are or contain tasks.
 268 
 269    procedure Move_Activation_Chain
 270      (From, To   : Activation_Chain_Access;
 271       New_Master : Master_ID);
 272    --  Compiler interface only. Do not call from within the RTS.
 273    --  Move all tasks on From list to To list, and change their Master_of_Task
 274    --  to be New_Master. This is used to implement build-in-place function
 275    --  returns. Tasks that are part of the return object are initially placed
 276    --  on an activation chain local to the return statement, and their master
 277    --  is the return statement, in case the return statement is left
 278    --  prematurely (due to raising an exception, being aborted, or a goto or
 279    --  exit statement). Once the return statement has completed successfully,
 280    --  Move_Activation_Chain is called to move them to the caller's activation
 281    --  chain, and change their master to the one passed in by the caller. If
 282    --  that doesn't happen, they will never be activated, and will become
 283    --  terminated on leaving the return statement.
 284 
 285    function Terminated (T : Task_Id) return Boolean;
 286    --  This is called by the compiler to implement the 'Terminated attribute.
 287    --  Though is not required to be so by the ARM, we choose to synchronize
 288    --  with the task's ATCB, so that this is more useful for polling the state
 289    --  of a task, and so that it becomes an abort completion point for the
 290    --  calling task (via Undefer_Abort).
 291    --
 292    --  source code:
 293    --     T1'Terminated
 294    --
 295    --  code expansion:
 296    --     terminated (t1._task_id)
 297 
 298    procedure Terminate_Task (Self_ID : Task_Id);
 299    --  Terminate the calling task.
 300    --  This should only be called by the Task_Wrapper procedure, and to
 301    --  deallocate storage associate with foreign tasks.
 302 
 303 end System.Tasking.Stages;