]>
Commit | Line | Data |
---|---|---|
c32d0452 | 1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
8bed087e | 3 | -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- |
c32d0452 | 4 | -- -- |
5 | -- S Y S T E M . T A S K I N G -- | |
6 | -- -- | |
7 | -- B o d y -- | |
8 | -- -- | |
d9c927cc | 9 | -- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- |
c32d0452 | 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- -- | |
6bc9506f | 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- -- | |
c32d0452 | 15 | -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- |
6bc9506f | 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/>. -- | |
c32d0452 | 26 | -- -- |
9dfe12ae | 27 | -- GNARL was developed by the GNARL team at Florida State University. -- |
28 | -- Extensive contributions were provided by Ada Core Technologies, Inc. -- | |
c32d0452 | 29 | -- -- |
30 | ------------------------------------------------------------------------------ | |
31 | ||
32 | pragma Polling (Off); | |
35e3878c | 33 | -- Turn off polling, we do not want ATC polling to take place during tasking |
34 | -- operations. It causes infinite loops and other problems. | |
c32d0452 | 35 | |
f89cc618 | 36 | with Ada.Unchecked_Deallocation; |
37 | ||
c32d0452 | 38 | with System.Task_Primitives.Operations; |
c32d0452 | 39 | with System.Storage_Elements; |
c32d0452 | 40 | |
c32d0452 | 41 | package body System.Tasking is |
42 | ||
43 | package STPO renames System.Task_Primitives.Operations; | |
44 | ||
f89cc618 | 45 | ---------------------------- |
46 | -- Free_Entry_Names_Array -- | |
47 | ---------------------------- | |
48 | ||
49 | procedure Free_Entry_Names_Array (Obj : in out Entry_Names_Array) is | |
50 | procedure Free_String is new | |
51 | Ada.Unchecked_Deallocation (String, String_Access); | |
52 | begin | |
53 | for Index in Obj'Range loop | |
54 | Free_String (Obj (Index)); | |
55 | end loop; | |
56 | end Free_Entry_Names_Array; | |
57 | ||
51e69f04 | 58 | --------------------- |
59 | -- Detect_Blocking -- | |
60 | --------------------- | |
61 | ||
62 | function Detect_Blocking return Boolean is | |
63 | GL_Detect_Blocking : Integer; | |
64 | pragma Import (C, GL_Detect_Blocking, "__gl_detect_blocking"); | |
e156dd80 | 65 | -- Global variable exported by the binder generated file. A value equal |
66 | -- to 1 indicates that pragma Detect_Blocking is active, while 0 is used | |
67 | -- for the pragma not being present. | |
51e69f04 | 68 | |
69 | begin | |
70 | return GL_Detect_Blocking = 1; | |
71 | end Detect_Blocking; | |
72 | ||
c32d0452 | 73 | ---------- |
74 | -- Self -- | |
75 | ---------- | |
76 | ||
7f9be362 | 77 | function Self return Task_Id renames STPO.Self; |
c32d0452 | 78 | |
ebf18fc8 | 79 | ------------------ |
80 | -- Storage_Size -- | |
81 | ------------------ | |
82 | ||
83 | function Storage_Size (T : Task_Id) return System.Parameters.Size_Type is | |
84 | begin | |
85 | return | |
86 | System.Parameters.Size_Type | |
87 | (T.Common.Compiler_Data.Pri_Stack_Info.Size); | |
88 | end Storage_Size; | |
89 | ||
c32d0452 | 90 | --------------------- |
91 | -- Initialize_ATCB -- | |
92 | --------------------- | |
93 | ||
c32d0452 | 94 | procedure Initialize_ATCB |
7f9be362 | 95 | (Self_ID : Task_Id; |
c32d0452 | 96 | Task_Entry_Point : Task_Procedure_Access; |
97 | Task_Arg : System.Address; | |
7f9be362 | 98 | Parent : Task_Id; |
c32d0452 | 99 | Elaborated : Access_Boolean; |
100 | Base_Priority : System.Any_Priority; | |
d9c927cc | 101 | Base_CPU : System.Multiprocessors.CPU_Range; |
c32d0452 | 102 | Task_Info : System.Task_Info.Task_Info_Type; |
103 | Stack_Size : System.Parameters.Size_Type; | |
8f71d067 | 104 | T : Task_Id; |
e156dd80 | 105 | Success : out Boolean) |
106 | is | |
c32d0452 | 107 | begin |
108 | T.Common.State := Unactivated; | |
109 | ||
110 | -- Initialize T.Common.LL | |
111 | ||
112 | STPO.Initialize_TCB (T, Success); | |
113 | ||
114 | if not Success then | |
c32d0452 | 115 | return; |
116 | end if; | |
117 | ||
405d066a | 118 | -- Wouldn't the following be better done using an assignment of an |
119 | -- aggregate so that we could be sure no components were forgotten??? | |
120 | ||
121 | T.Common.Parent := Parent; | |
122 | T.Common.Base_Priority := Base_Priority; | |
d9c927cc | 123 | T.Common.Base_CPU := Base_CPU; |
405d066a | 124 | T.Common.Current_Priority := 0; |
44d43e97 | 125 | T.Common.Protected_Action_Nesting := 0; |
405d066a | 126 | T.Common.Call := null; |
127 | T.Common.Task_Arg := Task_Arg; | |
128 | T.Common.Task_Entry_Point := Task_Entry_Point; | |
129 | T.Common.Activator := Self_ID; | |
130 | T.Common.Wait_Count := 0; | |
131 | T.Common.Elaborated := Elaborated; | |
132 | T.Common.Activation_Failed := False; | |
133 | T.Common.Task_Info := Task_Info; | |
0b8fc818 | 134 | T.Common.Global_Task_Lock_Nesting := 0; |
405d066a | 135 | T.Common.Fall_Back_Handler := null; |
136 | T.Common.Specific_Handler := null; | |
137 | T.Common.Debug_Events := (others => False); | |
c32d0452 | 138 | |
139 | if T.Common.Parent = null then | |
e156dd80 | 140 | |
141 | -- For the environment task, the adjusted stack size is meaningless. | |
142 | -- For example, an unspecified Stack_Size means that the stack size | |
143 | -- is determined by the environment, or can grow dynamically. The | |
144 | -- Stack_Checking algorithm therefore needs to use the requested | |
145 | -- size, or 0 in case of an unknown size. | |
c32d0452 | 146 | |
147 | T.Common.Compiler_Data.Pri_Stack_Info.Size := | |
148 | Storage_Elements.Storage_Offset (Stack_Size); | |
149 | ||
150 | else | |
151 | T.Common.Compiler_Data.Pri_Stack_Info.Size := | |
152 | Storage_Elements.Storage_Offset | |
153 | (Parameters.Adjust_Storage_Size (Stack_Size)); | |
154 | end if; | |
155 | ||
0311af6a | 156 | -- Link the task into the list of all tasks |
c32d0452 | 157 | |
158 | T.Common.All_Tasks_Link := All_Tasks_List; | |
159 | All_Tasks_List := T; | |
160 | end Initialize_ATCB; | |
161 | ||
51e69f04 | 162 | ---------------- |
163 | -- Initialize -- | |
164 | ---------------- | |
165 | ||
cf6d853e | 166 | Main_Task_Image : constant String := "main_task"; |
51e69f04 | 167 | -- Image of environment task |
c32d0452 | 168 | |
9dfe12ae | 169 | Main_Priority : Integer; |
c32d0452 | 170 | pragma Import (C, Main_Priority, "__gl_main_priority"); |
e156dd80 | 171 | -- Priority for main task. Note that this is of type Integer, not Priority, |
172 | -- because we use the value -1 to indicate the default main priority, and | |
173 | -- that is of course not in Priority'range. | |
c32d0452 | 174 | |
d9c927cc | 175 | Main_CPU : Integer; |
176 | pragma Import (C, Main_CPU, "__gl_main_cpu"); | |
177 | -- Affinity for main task. Note that this is of type Integer, not | |
178 | -- CPU_Range, because we use the value -1 to indicate the unassigned | |
179 | -- affinity, and that is of course not in CPU_Range'Range. | |
180 | ||
51e69f04 | 181 | Initialized : Boolean := False; |
182 | -- Used to prevent multiple calls to Initialize | |
183 | ||
184 | procedure Initialize is | |
7f9be362 | 185 | T : Task_Id; |
c32d0452 | 186 | Base_Priority : Any_Priority; |
d9c927cc | 187 | Base_CPU : System.Multiprocessors.CPU_Range; |
fdbbc018 | 188 | Success : Boolean; |
ed683f94 | 189 | |
c32d0452 | 190 | begin |
51e69f04 | 191 | if Initialized then |
192 | return; | |
193 | end if; | |
194 | ||
195 | Initialized := True; | |
196 | ||
c32d0452 | 197 | -- Initialize Environment Task |
198 | ||
7f2cf564 | 199 | Base_Priority := |
200 | (if Main_Priority = Unspecified_Priority | |
201 | then Default_Priority | |
202 | else Priority (Main_Priority)); | |
c32d0452 | 203 | |
d9c927cc | 204 | Base_CPU := |
205 | (if Main_CPU = Unspecified_CPU | |
206 | then System.Multiprocessors.Not_A_Specific_CPU | |
207 | else System.Multiprocessors.CPU_Range (Main_CPU)); | |
208 | ||
c32d0452 | 209 | T := STPO.New_ATCB (0); |
210 | Initialize_ATCB | |
d9c927cc | 211 | (null, null, Null_Address, Null_Task, null, Base_Priority, Base_CPU, |
c32d0452 | 212 | Task_Info.Unspecified_Task_Info, 0, T, Success); |
213 | pragma Assert (Success); | |
214 | ||
215 | STPO.Initialize (T); | |
216 | STPO.Set_Priority (T, T.Common.Base_Priority); | |
217 | T.Common.State := Runnable; | |
9dfe12ae | 218 | T.Common.Task_Image_Len := Main_Task_Image'Length; |
219 | T.Common.Task_Image (Main_Task_Image'Range) := Main_Task_Image; | |
c32d0452 | 220 | |
221 | -- Only initialize the first element since others are not relevant | |
222 | -- in ravenscar mode. Rest of the initialization is done in Init_RTS. | |
223 | ||
224 | T.Entry_Calls (1).Self := T; | |
51e69f04 | 225 | end Initialize; |
226 | ||
c32d0452 | 227 | end System.Tasking; |