OSDN Git Service

2006-10-31 Javier Miranda <miranda@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-solita.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --             S Y S T E M . S O F T _ L I N K S . T A S K I N G            --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 2004-2006, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT 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.  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.  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 GNAT;  see file COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
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.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 pragma Style_Checks (All_Checks);
35 --  Turn off subprogram alpha ordering check, since we group soft link
36 --  bodies and dummy soft link bodies together separately in this unit.
37
38 pragma Polling (Off);
39 --  Turn polling off for this package. We don't need polling during any
40 --  of the routines in this package, and more to the point, if we try
41 --  to poll it can cause infinite loops.
42
43 with System.Task_Primitives.Operations;
44 --  Used for Self
45 --           Timed_Delay
46
47 with System.Tasking;
48 --  Used for Task_Id
49 --           Cause_Of_Termination
50
51 with Ada.Exceptions;
52 --  Used for Exception_Id
53 --           Exception_Occurrence
54 --           Save_Occurrence
55
56 with Ada.Exceptions.Is_Null_Occurrence;
57
58 package body System.Soft_Links.Tasking is
59
60    package STPO renames System.Task_Primitives.Operations;
61    package SSL  renames System.Soft_Links;
62
63    use Ada.Exceptions;
64
65    use type System.Tasking.Task_Id;
66    use type System.Tasking.Termination_Handler;
67
68    ----------------
69    -- Local Data --
70    ----------------
71
72    Initialized : Boolean := False;
73    --  Boolean flag that indicates whether the tasking soft links have
74    --  already been set.
75
76    -----------------------------------------------------------------
77    -- Tasking Versions of Services Needed by Non-Tasking Programs --
78    -----------------------------------------------------------------
79
80    function  Get_Jmpbuf_Address return  Address;
81    procedure Set_Jmpbuf_Address (Addr : Address);
82    --  Get/Set Jmpbuf_Address for current task
83
84    function  Get_Sec_Stack_Addr return  Address;
85    procedure Set_Sec_Stack_Addr (Addr : Address);
86    --  Get/Set location of current task's secondary stack
87
88    function Get_Current_Excep return SSL.EOA;
89    --  Task-safe version of SSL.Get_Current_Excep
90
91    procedure Timed_Delay_T (Time : Duration; Mode : Integer);
92    --  Task-safe version of SSL.Timed_Delay
93
94    procedure Task_Termination_Handler_T  (Excep : SSL.EO);
95    --  Task-safe version of the task termination procedure
96
97    --------------------------
98    -- Soft-Link Get Bodies --
99    --------------------------
100
101    function Get_Current_Excep return SSL.EOA is
102    begin
103       return STPO.Self.Common.Compiler_Data.Current_Excep'Access;
104    end Get_Current_Excep;
105
106    function Get_Jmpbuf_Address return  Address is
107    begin
108       return STPO.Self.Common.Compiler_Data.Jmpbuf_Address;
109    end Get_Jmpbuf_Address;
110
111    function Get_Sec_Stack_Addr return  Address is
112    begin
113       return STPO.Self.Common.Compiler_Data.Sec_Stack_Addr;
114    end Get_Sec_Stack_Addr;
115
116    --------------------------
117    -- Soft-Link Set Bodies --
118    --------------------------
119
120    procedure Set_Jmpbuf_Address (Addr : Address) is
121    begin
122       STPO.Self.Common.Compiler_Data.Jmpbuf_Address := Addr;
123    end Set_Jmpbuf_Address;
124
125    procedure Set_Sec_Stack_Addr (Addr : Address) is
126    begin
127       STPO.Self.Common.Compiler_Data.Sec_Stack_Addr := Addr;
128    end Set_Sec_Stack_Addr;
129
130    -------------------
131    -- Timed_Delay_T --
132    -------------------
133
134    procedure Timed_Delay_T (Time : Duration; Mode : Integer) is
135       Self_Id : constant System.Tasking.Task_Id := STPO.Self;
136
137    begin
138       --  In case pragma Detect_Blocking is active then Program_Error
139       --  must be raised if this potentially blocking operation
140       --  is called from a protected operation.
141
142       if System.Tasking.Detect_Blocking
143         and then Self_Id.Common.Protected_Action_Nesting > 0
144       then
145          raise Program_Error with "potentially blocking operation";
146       else
147          Abort_Defer.all;
148          STPO.Timed_Delay (Self_Id, Time, Mode);
149          Abort_Undefer.all;
150       end if;
151    end Timed_Delay_T;
152
153    --------------------------------
154    -- Task_Termination_Handler_T --
155    --------------------------------
156
157    procedure Task_Termination_Handler_T (Excep : SSL.EO) is
158       Self_Id : constant System.Tasking.Task_Id := STPO.Self;
159       Cause   : System.Tasking.Cause_Of_Termination;
160       EO      : Ada.Exceptions.Exception_Occurrence;
161
162    begin
163       --  We can only be here because we are terminating the environment task.
164       --  Task termination for the rest of the tasks is handled in the
165       --  Task_Wrapper.
166
167       pragma Assert (Self_Id = STPO.Environment_Task);
168
169       --  Normal task termination
170
171       if Is_Null_Occurrence (Excep) then
172          Cause := System.Tasking.Normal;
173          Ada.Exceptions.Save_Occurrence (EO, Ada.Exceptions.Null_Occurrence);
174
175       --  Abnormal task termination
176
177       elsif Exception_Identity (Excep) = Standard'Abort_Signal'Identity then
178          Cause := System.Tasking.Abnormal;
179          Ada.Exceptions.Save_Occurrence (EO, Ada.Exceptions.Null_Occurrence);
180
181       --  Termination because of an unhandled exception
182
183       else
184          Cause := System.Tasking.Unhandled_Exception;
185          Ada.Exceptions.Save_Occurrence (EO, Excep);
186       end if;
187
188       --  There is no need for explicit protection against race conditions
189       --  for this part because it can only be executed by the environment
190       --  task after all the other tasks have been finalized.
191
192       if Self_Id.Common.Specific_Handler /= null then
193          Self_Id.Common.Specific_Handler.all (Cause, Self_Id, EO);
194       elsif Self_Id.Common.Fall_Back_Handler /= null then
195          Self_Id.Common.Fall_Back_Handler.all (Cause, Self_Id, EO);
196       end if;
197    end Task_Termination_Handler_T;
198
199    -----------------------------
200    -- Init_Tasking_Soft_Links --
201    -----------------------------
202
203    procedure Init_Tasking_Soft_Links is
204    begin
205       --  Set links only if not set already
206
207       if not Initialized then
208
209          --  Mark tasking soft links as initialized
210
211          Initialized := True;
212
213          --  The application being executed uses tasking so that the tasking
214          --  version of the following soft links need to be used.
215
216          SSL.Get_Jmpbuf_Address       := Get_Jmpbuf_Address'Access;
217          SSL.Set_Jmpbuf_Address       := Set_Jmpbuf_Address'Access;
218          SSL.Get_Sec_Stack_Addr       := Get_Sec_Stack_Addr'Access;
219          SSL.Set_Sec_Stack_Addr       := Set_Sec_Stack_Addr'Access;
220          SSL.Get_Current_Excep        := Get_Current_Excep'Access;
221          SSL.Timed_Delay              := Timed_Delay_T'Access;
222          SSL.Task_Termination_Handler := Task_Termination_Handler_T'Access;
223
224          --  No need to create a new Secondary Stack, since we will use the
225          --  default one created in s-secsta.adb
226
227          SSL.Set_Sec_Stack_Addr     (SSL.Get_Sec_Stack_Addr_NT);
228          SSL.Set_Jmpbuf_Address     (SSL.Get_Jmpbuf_Address_NT);
229       end if;
230    end Init_Tasking_Soft_Links;
231
232 end System.Soft_Links.Tasking;