OSDN Git Service

Update FSF address
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-osinte-fsu.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
4 --                                                                          --
5 --                   S Y S T E M . O S _ I N T E R F A C E                  --
6 --                                                                          --
7 --                                  B o d y                                 --
8 --                                                                          --
9 --             Copyright (C) 1991-1994, Florida State University            --
10 --                     Copyright (C) 1995-2005, AdaCore                     --
11 --                                                                          --
12 -- GNARL 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 2,  or (at your option) any later ver- --
15 -- sion. GNARL 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.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNARL; see file COPYING.  If not, write --
20 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
21 -- Boston, MA 02110-1301, USA.                                              --
22 --                                                                          --
23 -- As a special exception,  if other files  instantiate  generics from this --
24 -- unit, or you link  this unit with other files  to produce an executable, --
25 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
26 -- covered  by the  GNU  General  Public  License.  This exception does not --
27 -- however invalidate  any other reasons why  the executable file  might be --
28 -- covered by the  GNU Public License.                                      --
29 --                                                                          --
30 -- GNARL was developed by the GNARL team at Florida State University.       --
31 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
32 --                                                                          --
33 ------------------------------------------------------------------------------
34
35 --  This is a FSU Threads version of this package
36
37 pragma Polling (Off);
38 --  Turn off polling, we do not want ATC polling to take place during
39 --  tasking operations. It causes infinite loops and other problems.
40
41 with Interfaces.C;
42
43 package body System.OS_Interface is
44
45    use Interfaces.C;
46
47    -----------------
48    -- To_Duration --
49    -----------------
50
51    function To_Duration (TS : timespec) return Duration is
52    begin
53       return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
54    end To_Duration;
55
56    function To_Duration (TV : struct_timeval) return Duration is
57    begin
58       return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
59    end To_Duration;
60
61    -----------------
62    -- To_Timespec --
63    -----------------
64
65    function To_Timespec (D : Duration) return timespec is
66       S : time_t;
67       F : Duration;
68
69    begin
70       S := time_t (Long_Long_Integer (D));
71       F := D - Duration (S);
72
73       --  If F has negative value due to a round-up, adjust for positive F
74       --  value.
75
76       if F < 0.0 then
77          S := S - 1;
78          F := F + 1.0;
79       end if;
80
81       return timespec'(tv_sec  => S,
82                        tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
83    end To_Timespec;
84
85    ----------------
86    -- To_Timeval --
87    ----------------
88
89    function To_Timeval (D : Duration) return struct_timeval is
90       S : long;
91       F : Duration;
92
93    begin
94       S := long (Long_Long_Integer (D));
95       F := D - Duration (S);
96
97       --  If F has negative value due to a round-up, adjust for positive F
98       --  value.
99
100       if F < 0.0 then
101          S := S - 1;
102          F := F + 1.0;
103       end if;
104
105       return
106         struct_timeval'
107           (tv_sec  => S,
108            tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
109    end To_Timeval;
110
111    -------------
112    -- sigwait --
113    -------------
114
115    --  FSU_THREADS has a nonstandard sigwait
116
117    function sigwait
118      (set  : access sigset_t;
119       sig  : access Signal) return int
120    is
121       Result : int;
122
123       function sigwait_base (set : access sigset_t) return int;
124       pragma Import (C, sigwait_base, "sigwait");
125
126    begin
127       Result := sigwait_base (set);
128
129       if Result = -1 then
130          sig.all := 0;
131          return errno;
132       end if;
133
134       sig.all := Signal (Result);
135       return 0;
136    end sigwait;
137
138    ------------------------
139    -- pthread_mutex_lock --
140    ------------------------
141
142    --  FSU_THREADS has nonstandard pthread_mutex_lock and unlock.
143    --  It sets errno but the standard Posix requires it to be returned.
144
145    function pthread_mutex_lock (mutex : access pthread_mutex_t) return int is
146       function pthread_mutex_lock_base
147         (mutex : access pthread_mutex_t) return int;
148       pragma Import (C, pthread_mutex_lock_base, "pthread_mutex_lock");
149
150       Result : int;
151
152    begin
153       Result := pthread_mutex_lock_base (mutex);
154
155       if Result /= 0 then
156          return errno;
157       end if;
158
159       return 0;
160    end pthread_mutex_lock;
161
162    --------------------------
163    -- pthread_mutex_unlock --
164    --------------------------
165
166    function pthread_mutex_unlock
167      (mutex : access pthread_mutex_t) return int
168    is
169       function pthread_mutex_unlock_base
170         (mutex : access pthread_mutex_t) return int;
171       pragma Import (C, pthread_mutex_unlock_base, "pthread_mutex_unlock");
172
173       Result : int;
174
175    begin
176       Result := pthread_mutex_unlock_base (mutex);
177
178       if Result /= 0 then
179          return errno;
180       end if;
181
182       return 0;
183    end pthread_mutex_unlock;
184
185    -----------------------
186    -- pthread_cond_wait --
187    -----------------------
188
189    --  FSU_THREADS has a nonstandard pthread_cond_wait.
190    --  The FSU_THREADS version returns EINTR when interrupted.
191
192    function pthread_cond_wait
193      (cond  : access pthread_cond_t;
194       mutex : access pthread_mutex_t) return int
195    is
196       function pthread_cond_wait_base
197         (cond  : access pthread_cond_t;
198          mutex : access pthread_mutex_t) return int;
199       pragma Import (C, pthread_cond_wait_base, "pthread_cond_wait");
200
201       Result : int;
202
203    begin
204       Result := pthread_cond_wait_base (cond, mutex);
205
206       if Result = EINTR then
207          return 0;
208       else
209          return Result;
210       end if;
211    end pthread_cond_wait;
212
213    ----------------------------
214    -- pthread_cond_timedwait --
215    ----------------------------
216
217    --  FSU_THREADS has a nonstandard pthread_cond_timedwait. The
218    --  FSU_THREADS version returns -1 and set errno to EAGAIN for timeout.
219
220    function pthread_cond_timedwait
221      (cond    : access pthread_cond_t;
222       mutex   : access pthread_mutex_t;
223       abstime : access timespec) return int
224    is
225       function pthread_cond_timedwait_base
226         (cond    : access pthread_cond_t;
227          mutex   : access pthread_mutex_t;
228          abstime : access timespec) return int;
229       pragma Import (C, pthread_cond_timedwait_base, "pthread_cond_timedwait");
230
231       Result : int;
232
233    begin
234       Result := pthread_cond_timedwait_base (cond, mutex, abstime);
235
236       if Result = -1 then
237          if errno = EAGAIN then
238             return ETIMEDOUT;
239          else
240             return EINVAL;
241          end if;
242       end if;
243
244       return 0;
245    end pthread_cond_timedwait;
246
247    ---------------------------
248    -- pthread_setschedparam --
249    ---------------------------
250
251    --  FSU_THREADS does not have pthread_setschedparam
252
253    --  This routine returns a non-negative value upon failure
254    --  but the error code can not be set conforming the POSIX standard.
255
256    function pthread_setschedparam
257      (thread : pthread_t;
258       policy : int;
259       param  : access struct_sched_param) return int
260    is
261       function pthread_setschedattr
262         (thread : pthread_t;
263          attr   : pthread_attr_t) return int;
264       pragma Import (C, pthread_setschedattr, "pthread_setschedattr");
265
266       attr   : aliased pthread_attr_t;
267       Result : int;
268
269    begin
270       Result := pthread_attr_init (attr'Access);
271
272       if Result /= 0 then
273          return Result;
274       end if;
275
276       attr.sched := policy;
277
278       --  Short-cut around pthread_attr_setprio
279
280       attr.prio := param.sched_priority;
281
282       Result := pthread_setschedattr (thread, attr);
283
284       if Result /= 0 then
285          return Result;
286       end if;
287
288       Result := pthread_attr_destroy (attr'Access);
289
290       if Result /= 0 then
291          return Result;
292       else
293          return 0;
294       end if;
295    end pthread_setschedparam;
296
297    -------------------------
298    -- pthread_getspecific --
299    -------------------------
300
301    --  FSU_THREADS has a nonstandard pthread_getspecific
302
303    function pthread_getspecific (key : pthread_key_t) return System.Address is
304       function pthread_getspecific_base
305         (key   : pthread_key_t;
306          value : access System.Address) return int;
307       pragma Import (C, pthread_getspecific_base, "pthread_getspecific");
308
309       Tmp    : aliased System.Address;
310       Result : int;
311
312    begin
313       Result := pthread_getspecific_base (key, Tmp'Access);
314
315       if Result /= 0 then
316          return System.Null_Address;
317       end if;
318
319       return Tmp;
320    end pthread_getspecific;
321
322    ---------------------------------
323    -- pthread_attr_setdetachstate --
324    ---------------------------------
325
326    function pthread_attr_setdetachstate
327      (attr        : access pthread_attr_t;
328       detachstate : int) return int
329    is
330       function pthread_attr_setdetachstate_base
331         (attr        : access pthread_attr_t;
332          detachstate : access int) return int;
333       pragma Import
334         (C, pthread_attr_setdetachstate_base, "pthread_attr_setdetachstate");
335
336       Tmp : aliased int := detachstate;
337
338    begin
339       return pthread_attr_setdetachstate_base (attr, Tmp'Access);
340    end pthread_attr_setdetachstate;
341
342    -----------------
343    -- sched_yield --
344    -----------------
345
346    --  FSU_THREADS does not have sched_yield;
347
348    function sched_yield return int is
349       procedure sched_yield_base (arg : System.Address);
350       pragma Import (C, sched_yield_base, "pthread_yield");
351
352    begin
353       sched_yield_base (System.Null_Address);
354       return 0;
355    end sched_yield;
356
357    ----------------
358    -- Stack_Base --
359    ----------------
360
361    function Get_Stack_Base (thread : pthread_t) return Address is
362    begin
363       return thread.stack_base;
364    end Get_Stack_Base;
365
366 end System.OS_Interface;