OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [s-taprob.adb] - Blame information for rev 848

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
4
--                                                                          --
5
--      S Y S T E M . T A S K I N G . P R O T E C T E D _ O B J E C T S     --
6
--                                                                          --
7
--                                  B o d y                                 --
8
--                                                                          --
9
--            Copyright (C) 1991-1994, Florida State University             --
10
--                     Copyright (C) 1995-2011, AdaCore                     --
11
--                                                                          --
12
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
13
-- terms of the  GNU General Public License as published  by the Free Soft- --
14
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
15
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
18
--                                                                          --
19
-- As a special exception under Section 7 of GPL version 3, you are granted --
20
-- additional permissions described in the GCC Runtime Library Exception,   --
21
-- version 3.1, as published by the Free Software Foundation.               --
22
--                                                                          --
23
-- You should have received a copy of the GNU General Public License and    --
24
-- a copy of the GCC Runtime Library Exception along with this program;     --
25
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
26
-- <http://www.gnu.org/licenses/>.                                          --
27
--                                                                          --
28
-- GNARL was developed by the GNARL team at Florida State University.       --
29
-- Extensive contributions were provided by Ada Core Technologies, Inc.     --
30
--                                                                          --
31
------------------------------------------------------------------------------
32
 
33
pragma Polling (Off);
34
--  Turn off polling, we do not want ATC polling to take place during
35
--  tasking operations. It causes infinite loops and other problems.
36
 
37
with System.Task_Primitives.Operations;
38
with System.Parameters;
39
with System.Traces;
40
with System.Soft_Links.Tasking;
41
 
42
package body System.Tasking.Protected_Objects is
43
 
44
   use System.Task_Primitives.Operations;
45
   use System.Traces;
46
 
47
   ----------------
48
   -- Local Data --
49
   ----------------
50
 
51
   Locking_Policy : Character;
52
   pragma Import (C, Locking_Policy, "__gl_locking_policy");
53
 
54
   -------------------------
55
   -- Finalize_Protection --
56
   -------------------------
57
 
58
   procedure Finalize_Protection (Object : in out Protection) is
59
   begin
60
      Finalize_Lock (Object.L'Unrestricted_Access);
61
   end Finalize_Protection;
62
 
63
   ---------------------------
64
   -- Initialize_Protection --
65
   ---------------------------
66
 
67
   procedure Initialize_Protection
68
     (Object           : Protection_Access;
69
      Ceiling_Priority : Integer)
70
   is
71
      Init_Priority : Integer := Ceiling_Priority;
72
 
73
   begin
74
      if Init_Priority = Unspecified_Priority then
75
         Init_Priority  := System.Priority'Last;
76
      end if;
77
 
78
      Initialize_Lock (Init_Priority, Object.L'Access);
79
      Object.Ceiling := System.Any_Priority (Init_Priority);
80
      Object.New_Ceiling := System.Any_Priority (Init_Priority);
81
      Object.Owner := Null_Task;
82
   end Initialize_Protection;
83
 
84
   -----------------
85
   -- Get_Ceiling --
86
   -----------------
87
 
88
   function Get_Ceiling
89
     (Object : Protection_Access) return System.Any_Priority is
90
   begin
91
      return Object.New_Ceiling;
92
   end Get_Ceiling;
93
 
94
   ----------
95
   -- Lock --
96
   ----------
97
 
98
   procedure Lock (Object : Protection_Access) is
99
      Ceiling_Violation : Boolean;
100
 
101
   begin
102
      --  The lock is made without deferring abort
103
 
104
      --  Therefore the abort has to be deferred before calling this routine.
105
      --  This means that the compiler has to generate a Defer_Abort call
106
      --  before the call to Lock.
107
 
108
      --  The caller is responsible for undeferring abort, and compiler
109
      --  generated calls must be protected with cleanup handlers to ensure
110
      --  that abort is undeferred in all cases.
111
 
112
      --  If pragma Detect_Blocking is active then, as described in the ARM
113
      --  9.5.1, par. 15, we must check whether this is an external call on a
114
      --  protected subprogram with the same target object as that of the
115
      --  protected action that is currently in progress (i.e., if the caller
116
      --  is already the protected object's owner). If this is the case hence
117
      --  Program_Error must be raised.
118
 
119
      if Detect_Blocking and then Object.Owner = Self then
120
         raise Program_Error;
121
      end if;
122
 
123
      Write_Lock (Object.L'Access, Ceiling_Violation);
124
 
125
      if Parameters.Runtime_Traces then
126
         Send_Trace_Info (PO_Lock);
127
      end if;
128
 
129
      if Ceiling_Violation then
130
         raise Program_Error;
131
      end if;
132
 
133
      --  We are entering in a protected action, so that we increase the
134
      --  protected object nesting level (if pragma Detect_Blocking is
135
      --  active), and update the protected object's owner.
136
 
137
      if Detect_Blocking then
138
         declare
139
            Self_Id : constant Task_Id := Self;
140
         begin
141
            --  Update the protected object's owner
142
 
143
            Object.Owner := Self_Id;
144
 
145
            --  Increase protected object nesting level
146
 
147
            Self_Id.Common.Protected_Action_Nesting :=
148
              Self_Id.Common.Protected_Action_Nesting + 1;
149
         end;
150
      end if;
151
   end Lock;
152
 
153
   --------------------
154
   -- Lock_Read_Only --
155
   --------------------
156
 
157
   procedure Lock_Read_Only (Object : Protection_Access) is
158
      Ceiling_Violation : Boolean;
159
 
160
   begin
161
      --  If pragma Detect_Blocking is active then, as described in the ARM
162
      --  9.5.1, par. 15, we must check whether this is an external call on
163
      --  protected subprogram with the same target object as that of the
164
      --  protected action that is currently in progress (i.e., if the caller
165
      --  is already the protected object's owner). If this is the case hence
166
      --  Program_Error must be raised.
167
      --
168
      --  Note that in this case (getting read access), several tasks may have
169
      --  read ownership of the protected object, so that this method of
170
      --  storing the (single) protected object's owner does not work reliably
171
      --  for read locks. However, this is the approach taken for two major
172
      --  reasons: first, this function is not currently being used (it is
173
      --  provided for possible future use), and second, it largely simplifies
174
      --  the implementation.
175
 
176
      if Detect_Blocking and then Object.Owner = Self then
177
         raise Program_Error;
178
      end if;
179
 
180
      Read_Lock (Object.L'Access, Ceiling_Violation);
181
 
182
      if Parameters.Runtime_Traces then
183
         Send_Trace_Info (PO_Lock);
184
      end if;
185
 
186
      if Ceiling_Violation then
187
         raise Program_Error;
188
      end if;
189
 
190
      --  We are entering in a protected action, so we increase the protected
191
      --  object nesting level (if pragma Detect_Blocking is active).
192
 
193
      if Detect_Blocking then
194
         declare
195
            Self_Id : constant Task_Id := Self;
196
         begin
197
            --  Update the protected object's owner
198
 
199
            Object.Owner := Self_Id;
200
 
201
            --  Increase protected object nesting level
202
 
203
            Self_Id.Common.Protected_Action_Nesting :=
204
              Self_Id.Common.Protected_Action_Nesting + 1;
205
         end;
206
      end if;
207
   end Lock_Read_Only;
208
 
209
   -----------------
210
   -- Set_Ceiling --
211
   -----------------
212
 
213
   procedure Set_Ceiling
214
     (Object : Protection_Access;
215
      Prio   : System.Any_Priority) is
216
   begin
217
      Object.New_Ceiling := Prio;
218
   end Set_Ceiling;
219
 
220
   ------------
221
   -- Unlock --
222
   ------------
223
 
224
   procedure Unlock (Object : Protection_Access) is
225
   begin
226
      --  We are exiting from a protected action, so that we decrease the
227
      --  protected object nesting level (if pragma Detect_Blocking is
228
      --  active), and remove ownership of the protected object.
229
 
230
      if Detect_Blocking then
231
         declare
232
            Self_Id : constant Task_Id := Self;
233
 
234
         begin
235
            --  Calls to this procedure can only take place when being within
236
            --  a protected action and when the caller is the protected
237
            --  object's owner.
238
 
239
            pragma Assert (Self_Id.Common.Protected_Action_Nesting > 0
240
                             and then Object.Owner = Self_Id);
241
 
242
            --  Remove ownership of the protected object
243
 
244
            Object.Owner := Null_Task;
245
 
246
            --  We are exiting from a protected action, so we decrease the
247
            --  protected object nesting level.
248
 
249
            Self_Id.Common.Protected_Action_Nesting :=
250
              Self_Id.Common.Protected_Action_Nesting - 1;
251
         end;
252
      end if;
253
 
254
      --  Before releasing the mutex we must actually update its ceiling
255
      --  priority if it has been changed.
256
 
257
      if Object.New_Ceiling /= Object.Ceiling then
258
         if Locking_Policy = 'C' then
259
            System.Task_Primitives.Operations.Set_Ceiling
260
              (Object.L'Access, Object.New_Ceiling);
261
         end if;
262
 
263
         Object.Ceiling := Object.New_Ceiling;
264
      end if;
265
 
266
      Unlock (Object.L'Access);
267
 
268
      if Parameters.Runtime_Traces then
269
         Send_Trace_Info (PO_Unlock);
270
      end if;
271
   end Unlock;
272
 
273
begin
274
   --  Ensure that tasking is initialized, as well as tasking soft links
275
   --  when using protected objects.
276
 
277
   Tasking.Initialize;
278
   System.Soft_Links.Tasking.Init_Tasking_Soft_Links;
279
end System.Tasking.Protected_Objects;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.