1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
5 -- S Y S T E M . T A S K I N G . I N I T I A L I Z A T I O N --
9 -- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
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 2, 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. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNARL; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNARL was developed by the GNARL team at Florida State University. --
30 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
32 ------------------------------------------------------------------------------
34 -- This package provides overall initialization of the tasking portion of the
35 -- RTS. This package must be elaborated before any tasking features are used.
37 package System
.Tasking
.Initialization
is
39 procedure Remove_From_All_Tasks_List
(T
: Task_Id
);
40 -- Remove T from All_Tasks_List. Call this function with RTS_Lock taken
42 ---------------------------------
43 -- Tasking-Specific Soft Links --
44 ---------------------------------
46 -- These permit us to leave out certain portions of the tasking
47 -- run-time system if they are not used. They are only used internally
48 -- by the tasking run-time system.
50 -- So far, the only example is support for Ada.Task_Attributes
52 type Proc_T
is access procedure (T
: Task_Id
);
54 procedure Finalize_Attributes
(T
: Task_Id
);
55 procedure Initialize_Attributes
(T
: Task_Id
);
57 Finalize_Attributes_Link
: Proc_T
:= Finalize_Attributes
'Access;
58 -- should be called with abort deferred and T.L write-locked
60 Initialize_Attributes_Link
: Proc_T
:= Initialize_Attributes
'Access;
61 -- should be called with abort deferred, but holding no locks
63 -------------------------
64 -- Abort Defer/Undefer --
65 -------------------------
67 -- Defer_Abort defers the affects of low-level abort and priority change
68 -- in the calling task until a matching Undefer_Abort call is executed.
70 -- Undefer_Abort DOES MORE than just undo the effects of one call to
71 -- Defer_Abort. It is the universal "polling point" for deferred
72 -- processing, including the following:
74 -- 1) base priority changes
78 -- Abort deferral MAY be nested (Self_ID.Deferral_Level is a count), but
79 -- to avoid waste and undetected errors, it generally SHOULD NOT be
80 -- nested. The symptom of over-deferring abort is that an exception may
81 -- fail to be raised, or an abort may fail to take place.
83 -- Therefore, there are two sets of the inlinable defer/undefer routines,
84 -- which are the ones to be used inside GNARL. One set allows nesting. The
85 -- other does not. People who maintain the GNARL should try to avoid using
86 -- the nested versions, or at least look very critically at the places
87 -- where they are used.
89 -- In general, any GNARL call that is potentially blocking, or whose
90 -- semantics require that it sometimes raise an exception, or that is
91 -- required to be an abort completion point, must be made with abort
92 -- Deferral_Level = 1.
94 -- In general, non-blocking GNARL calls, which may be made from inside a
95 -- protected action, are likely to need to allow nested abort deferral.
97 -- With some critical exceptions (which are supposed to be documented),
98 -- internal calls to the tasking runtime system assume abort is already
99 -- deferred, and do not modify the deferral level.
101 -- There is also a set of non-linable defer/undefer routines, for direct
102 -- call from the compiler. These are not in-lineable because they may need
103 -- to be called via pointers ("soft links"). For the sake of efficiency,
104 -- the version with Self_ID as parameter should used wherever possible.
105 -- These are all nestable.
107 -- Non-nestable inline versions
109 procedure Defer_Abort
(Self_ID
: Task_Id
);
110 pragma Inline
(Defer_Abort
);
112 procedure Undefer_Abort
(Self_ID
: Task_Id
);
113 pragma Inline
(Undefer_Abort
);
115 -- Nestable inline versions
117 procedure Defer_Abort_Nestable
(Self_ID
: Task_Id
);
118 pragma Inline
(Defer_Abort_Nestable
);
120 procedure Undefer_Abort_Nestable
(Self_ID
: Task_Id
);
121 pragma Inline
(Undefer_Abort_Nestable
);
123 -- NON-INLINE versions without Self_ID for code generated by the
124 -- expander and for soft links
126 procedure Defer_Abortion
;
127 procedure Undefer_Abortion
;
129 -- Try to phase out all uses of the above versions ???
131 procedure Do_Pending_Action
(Self_ID
: Task_Id
);
132 -- Only call with no locks, and when Self_ID.Pending_Action = True Perform
133 -- necessary pending actions (e.g. abort, priority change). This procedure
134 -- is usually called when needed as a result of calling Undefer_Abort,
135 -- although in the case of e.g. No_Abort restriction, it can be necessary
136 -- to force execution of pending actions.
138 function Check_Abort_Status
return Integer;
139 -- Returns Boolean'Pos (True) iff abort signal should raise
140 -- Standard.Abort_Signal. Only used by IRIX currently.
142 --------------------------
143 -- Change Base Priority --
144 --------------------------
146 procedure Change_Base_Priority
(T
: Task_Id
);
147 -- Change the base priority of T. Has to be called with the affected
148 -- task's ATCB write-locked. May temporariliy release the lock.
150 procedure Poll_Base_Priority_Change
(Self_ID
: Task_Id
);
151 -- Has to be called with Self_ID's ATCB write-locked.
152 -- May temporariliy release the lock.
153 pragma Inline
(Poll_Base_Priority_Change
);
155 ----------------------
156 -- Task Lock/Unlock --
157 ----------------------
159 procedure Task_Lock
(Self_ID
: Task_Id
);
160 pragma Inline
(Task_Lock
);
162 procedure Task_Unlock
(Self_ID
: Task_Id
);
163 pragma Inline
(Task_Unlock
);
164 -- These are versions of Lock_Task and Unlock_Task created for use
167 procedure Final_Task_Unlock
(Self_ID
: Task_Id
);
168 -- This version is only for use in Terminate_Task, when the task is
169 -- relinquishing further rights to its own ATCB. There is a very
170 -- interesting potential race condition there, where the old task may run
171 -- concurrently with a new task that is allocated the old tasks (now
172 -- reused) ATCB. The critical thing here is to not make any reference to
173 -- the ATCB after the lock is released. See also comments on
174 -- Terminate_Task and Unlock.
176 procedure Wakeup_Entry_Caller
178 Entry_Call
: Entry_Call_Link
;
179 New_State
: Entry_Call_State
);
180 pragma Inline
(Wakeup_Entry_Caller
);
181 -- This is called at the end of service of an entry call, to abort the
182 -- caller if he is in an abortable part, and to wake up the caller if he
183 -- is on Entry_Caller_Sleep. Call it holding the lock of Entry_Call.Self.
185 -- Timed_Call or Simple_Call:
186 -- The caller is waiting on Entry_Caller_Sleep, in Wait_For_Completion,
187 -- or Wait_For_Completion_With_Timeout.
190 -- The caller might be in Wait_For_Completion,
191 -- waiting for a rendezvous (possibly requeued without abort) to
194 -- Asynchronous_Call:
195 -- The caller may be executing in the abortable part an async. select,
196 -- or on a time delay, if Entry_Call.State >= Was_Abortable.
198 procedure Locked_Abort_To_Level
202 pragma Inline
(Locked_Abort_To_Level
);
203 -- Abort a task to a specified ATC level. Call this only with T locked
205 end System
.Tasking
.Initialization
;