1------------------------------------------------------------------------------ 2-- -- 3-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- 4-- -- 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 -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1992-2019, 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-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 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 provides overall initialization of the tasking portion of the 33-- RTS. This package must be elaborated before any tasking features are used. 34 35package System.Tasking.Initialization is 36 37 procedure Remove_From_All_Tasks_List (T : Task_Id); 38 -- Remove T from All_Tasks_List. Call this function with RTS_Lock taken 39 40 procedure Finalize_Attributes (T : Task_Id); 41 -- Finalize all attributes from T. This is to be called just before the 42 -- ATCB is deallocated. It relies on the caller holding T.L write-lock 43 -- on entry. 44 45 --------------------------------- 46 -- Tasking-Specific Soft Links -- 47 --------------------------------- 48 49 ------------------------- 50 -- Abort Defer/Undefer -- 51 ------------------------- 52 53 -- Defer_Abort defers the effects of low-level abort and priority change 54 -- in the calling task until a matching Undefer_Abort call is executed. 55 56 -- Undefer_Abort DOES MORE than just undo the effects of one call to 57 -- Defer_Abort. It is the universal "polling point" for deferred 58 -- processing, including the following: 59 60 -- 1) base priority changes 61 62 -- 2) abort/ATC 63 64 -- Abort deferral MAY be nested (Self_ID.Deferral_Level is a count), but 65 -- to avoid waste and undetected errors, it generally SHOULD NOT be 66 -- nested. The symptom of over-deferring abort is that an exception may 67 -- fail to be raised, or an abort may fail to take place. 68 69 -- Therefore, there are two sets of the inlineable defer/undefer routines, 70 -- which are the ones to be used inside GNARL. One set allows nesting. The 71 -- other does not. People who maintain the GNARL should try to avoid using 72 -- the nested versions, or at least look very critically at the places 73 -- where they are used. 74 75 -- In general, any GNARL call that is potentially blocking, or whose 76 -- semantics require that it sometimes raise an exception, or that is 77 -- required to be an abort completion point, must be made with abort 78 -- Deferral_Level = 1. 79 80 -- In general, non-blocking GNARL calls, which may be made from inside a 81 -- protected action, are likely to need to allow nested abort deferral. 82 83 -- With some critical exceptions (which are supposed to be documented), 84 -- internal calls to the tasking runtime system assume abort is already 85 -- deferred, and do not modify the deferral level. 86 87 -- There is also a set of non-inlineable defer/undefer routines, for direct 88 -- call from the compiler. These are not inlineable because they may need 89 -- to be called via pointers ("soft links"). For the sake of efficiency, 90 -- the version with Self_ID as parameter should used wherever possible. 91 -- These are all nestable. 92 93 -- Non-nestable inline versions 94 95 procedure Defer_Abort (Self_ID : Task_Id); 96 pragma Inline (Defer_Abort); 97 98 procedure Undefer_Abort (Self_ID : Task_Id); 99 pragma Inline (Undefer_Abort); 100 101 -- Nestable inline versions 102 103 procedure Defer_Abort_Nestable (Self_ID : Task_Id); 104 pragma Inline (Defer_Abort_Nestable); 105 106 procedure Undefer_Abort_Nestable (Self_ID : Task_Id); 107 pragma Inline (Undefer_Abort_Nestable); 108 109 procedure Do_Pending_Action (Self_ID : Task_Id); 110 -- Only call with no locks, and when Self_ID.Pending_Action = True Perform 111 -- necessary pending actions (e.g. abort, priority change). This procedure 112 -- is usually called when needed as a result of calling Undefer_Abort, 113 -- although in the case of e.g. No_Abort restriction, it can be necessary 114 -- to force execution of pending actions. 115 116 function Check_Abort_Status return Integer; 117 -- Returns Boolean'Pos (True) iff abort signal should raise 118 -- Standard'Abort_Signal. Only used by IRIX currently. 119 120 -------------------------- 121 -- Change Base Priority -- 122 -------------------------- 123 124 procedure Change_Base_Priority (T : Task_Id); 125 -- Change the base priority of T. Has to be called with the affected 126 -- task's ATCB write-locked. May temporarily release the lock. 127 128 ---------------------- 129 -- Task Lock/Unlock -- 130 ---------------------- 131 132 procedure Task_Lock (Self_ID : Task_Id); 133 pragma Inline (Task_Lock); 134 135 procedure Task_Unlock (Self_ID : Task_Id); 136 pragma Inline (Task_Unlock); 137 -- These are versions of Lock_Task and Unlock_Task created for use 138 -- within the GNARL. 139 140 procedure Final_Task_Unlock (Self_ID : Task_Id); 141 -- This version is only for use in Terminate_Task, when the task is 142 -- relinquishing further rights to its own ATCB. There is a very 143 -- interesting potential race condition there, where the old task may run 144 -- concurrently with a new task that is allocated the old tasks (now 145 -- reused) ATCB. The critical thing here is to not make any reference to 146 -- the ATCB after the lock is released. See also comments on 147 -- Terminate_Task and Unlock. 148 149 procedure Wakeup_Entry_Caller 150 (Self_ID : Task_Id; 151 Entry_Call : Entry_Call_Link; 152 New_State : Entry_Call_State); 153 pragma Inline (Wakeup_Entry_Caller); 154 -- This is called at the end of service of an entry call, to abort the 155 -- caller if he is in an abortable part, and to wake up the caller if he 156 -- is on Entry_Caller_Sleep. Call it holding the lock of Entry_Call.Self. 157 -- 158 -- Timed_Call or Simple_Call: 159 -- The caller is waiting on Entry_Caller_Sleep, in Wait_For_Completion, 160 -- or Wait_For_Completion_With_Timeout. 161 -- 162 -- Conditional_Call: 163 -- The caller might be in Wait_For_Completion, 164 -- waiting for a rendezvous (possibly requeued without abort) to 165 -- complete. 166 -- 167 -- Asynchronous_Call: 168 -- The caller may be executing in the abortable part an async. select, 169 -- or on a time delay, if Entry_Call.State >= Was_Abortable. 170 171 procedure Locked_Abort_To_Level 172 (Self_ID : Task_Id; 173 T : Task_Id; 174 L : ATC_Level_Base); 175 pragma Inline (Locked_Abort_To_Level); 176 -- Abort a task to a specified ATC level. Call this only with T locked 177 178end System.Tasking.Initialization; 179