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;