File : s-taskin-xi-full.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                       --
   6 --                                                                          --
   7 --                                  S p e c                                 --
   8 --                                                                          --
   9 --          Copyright (C) 1992-2016, 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. GNARL 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 is a Ravenscar version of this package, extended with support for
  33 --  exception propagation.
  34 
  35 --  Note: the compiler generates direct calls to this interface, via Rtsfind.
  36 --  Any changes to this interface may require corresponding compiler changes.
  37 
  38 pragma Restrictions (No_Elaboration_Code);
  39 --  The Initialize procedure is called by System.Init.Install_Handler prior to
  40 --  the elaboration procs, and we must enforce that nothing in the latter might
  41 --  clobber what the early inits did. This is very tricky in presence of
  42 --  elaboration code for this unit, so we make sure that we don't have any and
  43 --  stick a few Suppress_Initialization pragmas to honor the restriction. The
  44 --  code relies on a few components of globals being implicitly initialized
  45 --  to 0, still. We expect this to be achieved by startup code clearing the
  46 --  bss section.
  47 
  48 with Ada.Exceptions;
  49 with Ada.Unchecked_Conversion;
  50 
  51 with System.Storage_Elements;
  52 with System.Parameters;
  53 with System.Task_Info;
  54 with System.Task_Primitives;
  55 with System.Multiprocessors;
  56 
  57 package System.Tasking is
  58    pragma Preelaborate;
  59 
  60    ---------------------------------
  61    -- Task_Id related definitions --
  62    ---------------------------------
  63 
  64    type Ada_Task_Control_Block;
  65 
  66    type Task_Id is access all Ada_Task_Control_Block;
  67 
  68    function To_Task_Id is
  69       new Ada.Unchecked_Conversion
  70          (System.Task_Primitives.Task_Address, Task_Id);
  71 
  72    function To_Address is
  73       new Ada.Unchecked_Conversion
  74          (Task_Id, System.Task_Primitives.Task_Address);
  75 
  76    Null_Task : constant Task_Id := null;
  77 
  78    type Task_List is array (Positive range <>) of Task_Id;
  79    pragma Suppress_Initialization (Task_List);
  80 
  81    function Self return Task_Id;
  82    --  This is the compiler interface version of this function. Do not call
  83    --  from the run-time system.
  84 
  85    -----------------------
  86    -- Enumeration types --
  87    -----------------------
  88 
  89    type Task_States is
  90      (Unactivated,
  91       --  Task has been created but has not been activated. It cannot be
  92       --  executing.
  93 
  94       --  Active states
  95 
  96       --  For all states from here down, the task has been activated. In
  97       --  addition, for all states from here down, except for Terminated,
  98       --  the task may be executing.
  99 
 100       Runnable,
 101       --  Task is not blocked for any reason known to Ada. (It may be waiting
 102       --  for a mutex, though.) It is conceptually "executing" in normal mode.
 103 
 104       Terminated,
 105       --  The task is terminated, in the sense of ARM 9.3 (5)
 106 
 107       Activator_Sleep,
 108       --  Task is waiting for created tasks to complete activation
 109 
 110       Acceptor_Sleep,
 111       --  Task is waiting on an accept or selective wait statement
 112 
 113       Entry_Caller_Sleep,
 114       --  Task is waiting on an entry call
 115 
 116       Async_Select_Sleep,
 117       --  Task is waiting to start the abortable part of an asynchronous select
 118       --  statement.
 119 
 120       Delay_Sleep,
 121       --  Task is waiting on a delay statement
 122 
 123       Master_Completion_Sleep,
 124       --  Master completion has two phases. In Phase 1 the task is sleeping
 125       --  in Complete_Master having completed a master within itself, and is
 126       --  waiting for the tasks dependent on that master to become terminated
 127       --  or waiting on a terminate Phase.
 128 
 129       Master_Phase_2_Sleep,
 130       --  In Phase 2 the task is sleeping in Complete_Master waiting for tasks
 131       --  on terminate alternatives to finish terminating.
 132 
 133       Interrupt_Server_Idle_Sleep,
 134       Interrupt_Server_Blocked_Interrupt_Sleep,
 135       Timer_Server_Sleep,
 136       AST_Server_Sleep,
 137       --  Special uses of sleep, for server tasks within the run-time system
 138 
 139       Asynchronous_Hold,
 140       --  The task has been held by Asynchronous_Task_Control.Hold_Task
 141 
 142       Interrupt_Server_Blocked_On_Event_Flag
 143       --  The task has been blocked on a system call waiting for the
 144       --  completion event.
 145      );
 146 
 147    --  The following status indicators are never used in a Ravenscar run time.
 148    --  They Are defined for debugging purposes: The same code in GDB to get
 149    --  the Current status of a task in a full run-time environment and in a
 150    --  Ravenscar environment.
 151 
 152    pragma Unreferenced (Activator_Sleep);
 153    pragma Unreferenced (Acceptor_Sleep);
 154    pragma Unreferenced (Async_Select_Sleep);
 155    pragma Unreferenced (Master_Completion_Sleep);
 156    pragma Unreferenced (Master_Phase_2_Sleep);
 157    pragma Unreferenced (Interrupt_Server_Idle_Sleep);
 158    pragma Unreferenced (Interrupt_Server_Blocked_Interrupt_Sleep);
 159    pragma Unreferenced (Timer_Server_Sleep);
 160    pragma Unreferenced (AST_Server_Sleep);
 161    pragma Unreferenced (Asynchronous_Hold);
 162    pragma Unreferenced (Interrupt_Server_Blocked_On_Event_Flag);
 163 
 164    -------------------------------
 165    -- Entry related definitions --
 166    -------------------------------
 167 
 168    --  These need comments ???
 169 
 170    Null_Entry : constant := 0;
 171 
 172    Max_Entry : constant := Integer'Last;
 173 
 174    Interrupt_Entry : constant := -2;
 175 
 176    Cancelled_Entry : constant := -1;
 177 
 178    type Entry_Index is range Interrupt_Entry .. Max_Entry;
 179 
 180    Null_Task_Entry : constant := Null_Entry;
 181 
 182    Max_Task_Entry : constant := Max_Entry;
 183 
 184    type Task_Entry_Index is new Entry_Index
 185      range Null_Task_Entry .. Max_Task_Entry;
 186 
 187    type Entry_Call_Record;
 188 
 189    type Entry_Call_Link is access all Entry_Call_Record;
 190 
 191    ----------------------------------
 192    -- Entry_Call_Record definition --
 193    ----------------------------------
 194 
 195    type Entry_Call_Record is record
 196       Self : Task_Id;
 197       --  ID of the caller
 198 
 199       Uninterpreted_Data : System.Address;
 200       --  Data passed by the compiler
 201 
 202       Exception_To_Raise : Ada.Exceptions.Exception_Id;
 203       --  The exception to raise once this call has been completed without
 204       --  being aborted.
 205 
 206       Next : Entry_Call_Link;
 207       --  Entry_Call List
 208    end record;
 209    pragma Suppress_Initialization (Entry_Call_Record);
 210 
 211    -------------------------------------------
 212    -- Task termination procedure definition --
 213    -------------------------------------------
 214 
 215    --  We need to redefine this type (already defined in Ada.Task_Termination)
 216    --  here to avoid circular dependencies.
 217 
 218    type Termination_Handler is access protected procedure (T : Task_Id);
 219    --  Used to represent protected procedures to be executed when a task
 220    --  terminates.
 221 
 222    Fall_Back_Handler : Termination_Handler;
 223    --  This is the fall-back handler that applies to all the tasks in the
 224    --  partition (this is only for Ravenscar-compliant systems).
 225 
 226    ------------------------------------
 227    -- Other Task-Related Definitions --
 228    ------------------------------------
 229 
 230    Idle_Priority : constant Integer := Any_Priority'First - 1;
 231    --  A priority lower than any user priority. Used by the idle task
 232 
 233    subtype Extended_Priority is
 234      Integer range Idle_Priority .. Any_Priority'Last;
 235    --  Priority range that also includes the idle priority
 236 
 237    type Activation_Chain is limited private;
 238 
 239    type Activation_Chain_Access is access all Activation_Chain;
 240 
 241    type Task_Procedure_Access is access procedure (Arg : System.Address);
 242 
 243    type Access_Boolean is access all Boolean;
 244 
 245    ----------------------------------------------
 246    -- Ada_Task_Control_Block (ATCB) definition --
 247    ----------------------------------------------
 248 
 249    --  Notes on protection (synchronization) of TRTS data structures
 250 
 251    --  Any field of the TCB can be written by the activator of a task when the
 252    --  task is created, since no other task can access the new task's state
 253    --  until creation is complete.
 254 
 255    --  The protection for each field is described in a comment starting with
 256    --  "Protection:".
 257 
 258    --  When a lock is used to protect an ATCB field, this lock is simply named
 259 
 260    --  Some protection is described in terms of tasks related to the ATCB being
 261    --  protected. These are:
 262 
 263    --    Self: The task which is controlled by this ATCB.
 264    --    Activator: The task that created Self and initiated its activation.
 265    --    Created: A task created and activated by Self.
 266 
 267    type Stack_Info is record
 268       Start_Address : System.Address := System.Null_Address;
 269       Size          : System.Storage_Elements.Storage_Offset;
 270    end record;
 271    pragma Suppress_Initialization (Stack_Info);
 272    --  Above pragma should be documented ???
 273 
 274    type TSD is record
 275       Pri_Stack_Info : aliased Stack_Info;
 276       --  Stack address and size of the task
 277 
 278       Sec_Stack_Addr : Address;
 279       --  Address of currently allocated secondary stack
 280 
 281       Current_Excep : aliased Ada.Exceptions.Exception_Occurrence;
 282       --  Exception occurrence that contains the information for the current
 283       --  exception. Note that any exception in the same task destroys this
 284       --  information, so the data in this variable must be copied out before
 285       --  another exception can occur.
 286 
 287    end record;
 288    pragma Suppress_Initialization (TSD);
 289 
 290    type Common_ATCB is record
 291       State : Task_States;
 292       pragma Atomic (State);
 293       --  Encodes some basic information about the state of a task, including
 294       --  whether it has been activated, whether it is sleeping, and whether
 295       --  it is terminated.
 296       --
 297       --  Protection: Only accessed by Self
 298 
 299       Base_CPU : System.Multiprocessors.CPU_Range;
 300       --  Protection: Only written during initialization, accessed by anyone
 301 
 302       Base_Priority : Extended_Priority;
 303       --  Base priority
 304       --
 305       --  Protection: Only written by Self, accessed by anyone
 306 
 307       Protected_Action_Nesting : Natural;
 308       pragma Atomic (Protected_Action_Nesting);
 309       --  The dynamic level of protected action nesting for this task. This
 310       --  field is needed for checking whether potentially blocking operations
 311       --  are invoked from protected actions. pragma Atomic is used because it
 312       --  can be read/written from protected interrupt handlers.
 313 
 314       LL : aliased Task_Primitives.Private_Data;
 315       --  Control block used by the underlying low-level tasking service
 316       --  (GNULLI).
 317       --
 318       --  Protection: This is used only by the GNULLI implementation, which
 319       --  takes care of all of its synchronization.
 320 
 321       Task_Arg : System.Address;
 322       --  The argument to task procedure. Currently unused, this will provide
 323       --  a handle for discriminant information.
 324       --
 325       --  Protection: Part of the synchronization between Self and Activator.
 326       --  Activator writes it, once, before Self starts executing. Thereafter,
 327       --  Self only reads it.
 328 
 329       Task_Entry_Point : Task_Procedure_Access;
 330       --  Information needed to call the procedure containing the code for
 331       --  the body of this task.
 332       --
 333       --  Protection: Part of the synchronization between Self and Activator.
 334       --  Activator writes it, once, before Self starts executing. Self reads
 335       --  it, once, as part of its execution.
 336 
 337       Compiler_Data : TSD;
 338       --  Task-specific data needed by compiler to store per-task stuctures
 339       --
 340       --  Protection: Only accessed by Self
 341 
 342       Activation_Link : Task_Id;
 343       --  Used to link this task to a list of tasks to be activated
 344       --
 345       --  Protection: Only used by Activator. Once the task is activated, this
 346       --  can also be reused by System.Tasking.Debug for the list of known
 347       --  tasks.
 348 
 349       Task_Info : System.Task_Info.Task_Info_Type;
 350       --  System-specific attributes of the task as specified by the
 351       --  Task_Info pragma.
 352 
 353       Global_Task_Lock_Nesting : Natural := 0;
 354       --  This is the current nesting level of calls to
 355       --  System.Tasking.Initialization.Lock_Task. This allows a task to call
 356       --  Lock_Task multiple times without deadlocking. A task only locks
 357       --  Global_Task_Lock when its Global_Task_Lock_Nesting goes from 0 to 1,
 358       --  and only unlocked when it goes from 1 to 0.
 359       --
 360       --  Protection: Only accessed by Self
 361    end record;
 362    pragma Suppress_Initialization (Common_ATCB);
 363 
 364    type Ada_Task_Control_Block (Entry_Num : Task_Entry_Index) is record
 365    --  The discriminant Entry_Num is not needed, but we keep it here for
 366    --  compatibility reasons with the rest of the run times, so that the
 367    --  expander does not need to know which run time is being used.
 368 
 369       Common : Common_ATCB;
 370 
 371       Entry_Call : aliased Entry_Call_Record;
 372       --  Protection: This field is used on entry call queues associated with
 373       --  protected objects, and is protected by the protected object lock.
 374    end record;
 375    pragma Suppress_Initialization (Ada_Task_Control_Block);
 376 
 377    --------------------------------
 378    -- Master Related Definitions --
 379    --------------------------------
 380 
 381    subtype Master_Level is Integer;
 382    subtype Master_ID is Master_Level;
 383 
 384    Library_Task_Level : constant Master_Level := 3;
 385 
 386    ----------------------------------
 387    -- Secondary Stack Manipulation --
 388    ----------------------------------
 389 
 390    function Get_Sec_Stack return Address;
 391    pragma Export (C, Get_Sec_Stack, "__gnat_get_secondary_stack");
 392    --  Return the address of the task specific secondary stack, as expected by
 393    --  System.Secondary_Stack.
 394 
 395    procedure Set_Sec_Stack (Stk : Address);
 396    --  Set the task specific secondary stack, as expected by
 397    --  System.Secondary_Stack.
 398 
 399    ----------------------------------------
 400    -- Task size, priority, affinity info --
 401    ----------------------------------------
 402 
 403    function Storage_Size (T : Task_Id) return System.Parameters.Size_Type;
 404    --  Retrieve from the TCB of the task the allocated size of its stack,
 405    --  either the system default or the size specified by a pragma. This
 406    --  is in general a non-static value that can depend on discriminants
 407    --  of the task.
 408 
 409    Unspecified_Priority : constant := -1;
 410    --  No specified priority. This value is also hard-coded in gnatbind.
 411 
 412    Unspecified_CPU : constant := -1;
 413    --  No affinity specified
 414 
 415    --------------------
 416    -- Initialization --
 417    --------------------
 418 
 419    procedure Initialize;
 420    --  This procedure constitutes the first part of the initialization of the
 421    --  GNARL. This includes creating data structures to make the initial thread
 422    --  into the environment task. The last part of the initialization is done
 423    --  in System.Tasking.Initialization or System.Tasking.Restricted.Stages.
 424    --  All the initializations used to be in Tasking.Initialization, but this
 425    --  is no longer possible with the run time simplification (including
 426    --  optimized PO and the restricted run time) since one cannot rely on
 427    --  System.Tasking.Initialization being present, as was done before.
 428 
 429    procedure Initialize_ATCB
 430      (Task_Entry_Point : Task_Procedure_Access;
 431       Task_Arg         : System.Address;
 432       Base_Priority    : Extended_Priority;
 433       Base_CPU         : System.Multiprocessors.CPU_Range;
 434       Task_Info        : System.Task_Info.Task_Info_Type;
 435       Stack_Address    : System.Address;
 436       Stack_Size       : System.Parameters.Size_Type;
 437       T                : Task_Id;
 438       Success          : out Boolean);
 439    --  Initialize fields of a TCB and link into global TCB structures
 440    --  Call this only with abort deferred and holding All_Tasks_L.
 441 
 442 private
 443 
 444    type Activation_Chain is limited record
 445       T_ID : Task_Id;
 446       --  Null terminated simply linked list of tasks
 447    end record;
 448 
 449 end System.Tasking;