OSDN Git Service

2008-08-22 Sergey Rybin <rybin@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-2008, 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 bodies
36 --  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 of the
40 --  routines in this package, and more to the point, if we try to poll it can
41 --  cause infinite loops.
42
43 with Ada.Exceptions;
44 with Ada.Exceptions.Is_Null_Occurrence;
45
46 with System.Task_Primitives.Operations;
47 with System.Tasking;
48 with System.Stack_Checking;
49
50 package body System.Soft_Links.Tasking is
51
52    package STPO renames System.Task_Primitives.Operations;
53    package SSL  renames System.Soft_Links;
54
55    use Ada.Exceptions;
56
57    use type System.Tasking.Task_Id;
58    use type System.Tasking.Termination_Handler;
59
60    ----------------
61    -- Local Data --
62    ----------------
63
64    Initialized : Boolean := False;
65    --  Boolean flag that indicates whether the tasking soft links have
66    --  already been set.
67
68    -----------------------------------------------------------------
69    -- Tasking Versions of Services Needed by Non-Tasking Programs --
70    -----------------------------------------------------------------
71
72    function  Get_Jmpbuf_Address return  Address;
73    procedure Set_Jmpbuf_Address (Addr : Address);
74    --  Get/Set Jmpbuf_Address for current task
75
76    function  Get_Sec_Stack_Addr return  Address;
77    procedure Set_Sec_Stack_Addr (Addr : Address);
78    --  Get/Set location of current task's secondary stack
79
80    procedure Timed_Delay_T (Time : Duration; Mode : Integer);
81    --  Task-safe version of SSL.Timed_Delay
82
83    procedure Task_Termination_Handler_T  (Excep : SSL.EO);
84    --  Task-safe version of the task termination procedure
85
86    function Get_Stack_Info return Stack_Checking.Stack_Access;
87    --  Get access to the current task's Stack_Info
88
89    --------------------------
90    -- Soft-Link Get Bodies --
91    --------------------------
92
93    function Get_Jmpbuf_Address return  Address is
94    begin
95       return STPO.Self.Common.Compiler_Data.Jmpbuf_Address;
96    end Get_Jmpbuf_Address;
97
98    function Get_Sec_Stack_Addr return  Address is
99    begin
100       return STPO.Self.Common.Compiler_Data.Sec_Stack_Addr;
101    end Get_Sec_Stack_Addr;
102
103    function Get_Stack_Info return Stack_Checking.Stack_Access is
104    begin
105       return STPO.Self.Common.Compiler_Data.Pri_Stack_Info'Access;
106    end Get_Stack_Info;
107
108    --------------------------
109    -- Soft-Link Set Bodies --
110    --------------------------
111
112    procedure Set_Jmpbuf_Address (Addr : Address) is
113    begin
114       STPO.Self.Common.Compiler_Data.Jmpbuf_Address := Addr;
115    end Set_Jmpbuf_Address;
116
117    procedure Set_Sec_Stack_Addr (Addr : Address) is
118    begin
119       STPO.Self.Common.Compiler_Data.Sec_Stack_Addr := Addr;
120    end Set_Sec_Stack_Addr;
121
122    -------------------
123    -- Timed_Delay_T --
124    -------------------
125
126    procedure Timed_Delay_T (Time : Duration; Mode : Integer) is
127       Self_Id : constant System.Tasking.Task_Id := STPO.Self;
128
129    begin
130       --  In case pragma Detect_Blocking is active then Program_Error
131       --  must be raised if this potentially blocking operation
132       --  is called from a protected operation.
133
134       if System.Tasking.Detect_Blocking
135         and then Self_Id.Common.Protected_Action_Nesting > 0
136       then
137          raise Program_Error with "potentially blocking operation";
138       else
139          Abort_Defer.all;
140          STPO.Timed_Delay (Self_Id, Time, Mode);
141          Abort_Undefer.all;
142       end if;
143    end Timed_Delay_T;
144
145    --------------------------------
146    -- Task_Termination_Handler_T --
147    --------------------------------
148
149    procedure Task_Termination_Handler_T (Excep : SSL.EO) is
150       Self_Id : constant System.Tasking.Task_Id := STPO.Self;
151       Cause   : System.Tasking.Cause_Of_Termination;
152       EO      : Ada.Exceptions.Exception_Occurrence;
153
154    begin
155       --  We can only be here because we are terminating the environment task.
156       --  Task termination for the rest of the tasks is handled in the
157       --  Task_Wrapper.
158
159       pragma Assert (Self_Id = STPO.Environment_Task);
160
161       --  Normal task termination
162
163       if Is_Null_Occurrence (Excep) then
164          Cause := System.Tasking.Normal;
165          Ada.Exceptions.Save_Occurrence (EO, Ada.Exceptions.Null_Occurrence);
166
167       --  Abnormal task termination
168
169       elsif Exception_Identity (Excep) = Standard'Abort_Signal'Identity then
170          Cause := System.Tasking.Abnormal;
171          Ada.Exceptions.Save_Occurrence (EO, Ada.Exceptions.Null_Occurrence);
172
173       --  Termination because of an unhandled exception
174
175       else
176          Cause := System.Tasking.Unhandled_Exception;
177          Ada.Exceptions.Save_Occurrence (EO, Excep);
178       end if;
179
180       --  There is no need for explicit protection against race conditions
181       --  for this part because it can only be executed by the environment
182       --  task after all the other tasks have been finalized.
183
184       if Self_Id.Common.Specific_Handler /= null then
185          Self_Id.Common.Specific_Handler.all (Cause, Self_Id, EO);
186       elsif Self_Id.Common.Fall_Back_Handler /= null then
187          Self_Id.Common.Fall_Back_Handler.all (Cause, Self_Id, EO);
188       end if;
189    end Task_Termination_Handler_T;
190
191    -----------------------------
192    -- Init_Tasking_Soft_Links --
193    -----------------------------
194
195    procedure Init_Tasking_Soft_Links is
196    begin
197       --  Set links only if not set already
198
199       if not Initialized then
200
201          --  Mark tasking soft links as initialized
202
203          Initialized := True;
204
205          --  The application being executed uses tasking so that the tasking
206          --  version of the following soft links need to be used.
207
208          SSL.Get_Jmpbuf_Address       := Get_Jmpbuf_Address'Access;
209          SSL.Set_Jmpbuf_Address       := Set_Jmpbuf_Address'Access;
210          SSL.Get_Sec_Stack_Addr       := Get_Sec_Stack_Addr'Access;
211          SSL.Get_Stack_Info           := Get_Stack_Info'Access;
212          SSL.Set_Sec_Stack_Addr       := Set_Sec_Stack_Addr'Access;
213          SSL.Timed_Delay              := Timed_Delay_T'Access;
214          SSL.Task_Termination_Handler := Task_Termination_Handler_T'Access;
215
216          --  No need to create a new Secondary Stack, since we will use the
217          --  default one created in s-secsta.adb
218
219          SSL.Set_Sec_Stack_Addr     (SSL.Get_Sec_Stack_Addr_NT);
220          SSL.Set_Jmpbuf_Address     (SSL.Get_Jmpbuf_Address_NT);
221       end if;
222    end Init_Tasking_Soft_Links;
223
224 end System.Soft_Links.Tasking;