OSDN Git Service

Add Fariborz to my last change.
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-osprim-vxworks.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS               --
4 --                                                                          --
5 --                  S Y S T E M . O S _ P R I M I T I V E S                 --
6 --                                                                          --
7 --                                  B o d y                                 --
8 --                                                                          --
9 --          Copyright (C) 1998-2004 Free Software Foundation, Inc.          --
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- --
13 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
14 -- sion. GNARL 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 GNARL; see file COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, 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 -- GNARL was developed by the GNARL team at Florida State University.       --
30 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 --  This version is for VxWorks targets
35
36 with System.OS_Interface;
37 --  Since the thread library is part of the VxWorks kernel, using OS_Interface
38 --  is not a problem here, as long as we only use System.OS_Interface as a
39 --  set of C imported routines: using Ada routines from this package would
40 --  create a dependency on libgnarl in libgnat, which is not desirable.
41
42 with Interfaces.C;
43 --  used for type int
44
45 package body System.OS_Primitives is
46
47    use System.OS_Interface;
48    use type Interfaces.C.int;
49
50    ------------------------
51    -- Internal functions --
52    ------------------------
53
54    function To_Clock_Ticks (D : Duration) return int;
55    --  Convert a duration value (in seconds) into clock ticks.
56    --  Note that this routine is duplicated from System.OS_Interface since
57    --  as explained above, we do not want to depend on libgnarl
58
59    function To_Clock_Ticks (D : Duration) return int is
60       Ticks          : Long_Long_Integer;
61       Rate_Duration  : Duration;
62       Ticks_Duration : Duration;
63
64    begin
65       if D < 0.0 then
66          return -1;
67       end if;
68
69       --  Ensure that the duration can be converted to ticks
70       --  at the current clock tick rate without overflowing.
71
72       Rate_Duration := Duration (sysClkRateGet);
73
74       if D > (Duration'Last / Rate_Duration) then
75          Ticks := Long_Long_Integer (int'Last);
76       else
77          Ticks_Duration := D * Rate_Duration;
78          Ticks := Long_Long_Integer (Ticks_Duration);
79
80          if Ticks_Duration > Duration (Ticks) then
81             Ticks := Ticks + 1;
82          end if;
83
84          if Ticks > Long_Long_Integer (int'Last) then
85             Ticks := Long_Long_Integer (int'Last);
86          end if;
87       end if;
88
89       return int (Ticks);
90    end To_Clock_Ticks;
91
92    -----------
93    -- Clock --
94    -----------
95
96    function Clock return Duration is
97       TS     : aliased timespec;
98       Result : int;
99
100       use type Interfaces.C.int;
101
102    begin
103       Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
104       pragma Assert (Result = 0);
105       return Duration (TS.ts_sec) + Duration (TS.ts_nsec) / 10#1#E9;
106    end Clock;
107
108    ---------------------
109    -- Monotonic_Clock --
110    ---------------------
111
112    function Monotonic_Clock return Duration renames Clock;
113
114    -----------------
115    -- Timed_Delay --
116    -----------------
117
118    procedure Timed_Delay
119      (Time : Duration;
120       Mode : Integer)
121    is
122       Rel_Time   : Duration;
123       Abs_Time   : Duration;
124       Check_Time : Duration := Clock;
125       Ticks      : int;
126
127       Result     : int;
128       pragma Unreferenced (Result);
129
130    begin
131       if Mode = Relative then
132          Rel_Time := Time;
133          Abs_Time := Time + Check_Time;
134       else
135          Rel_Time := Time - Check_Time;
136          Abs_Time := Time;
137       end if;
138
139       if Rel_Time > 0.0 then
140          loop
141             Ticks := To_Clock_Ticks (Rel_Time);
142
143             if Mode = Relative and then Ticks < int'Last then
144                --  The first tick will delay anytime between 0 and
145                --  1 / sysClkRateGet seconds, so we need to add one to
146                --  be on the safe side.
147
148                Ticks := Ticks + 1;
149             end if;
150
151             Result := taskDelay (Ticks);
152             Check_Time := Clock;
153
154             exit when Abs_Time <= Check_Time;
155
156             Rel_Time := Abs_Time - Check_Time;
157          end loop;
158       end if;
159    end Timed_Delay;
160
161 end System.OS_Primitives;