Commit | Line | Data |
dcf686c9 |
1 | #ifdef __cplusplus |
2 | extern "C" { |
3 | #endif |
4 | #include "EXTERN.h" |
5 | #include "perl.h" |
6 | #include "XSUB.h" |
7 | #ifdef WIN32 |
8 | #include <time.h> |
9 | #else |
10 | #include <sys/time.h> |
11 | #endif |
12 | #ifdef __cplusplus |
13 | } |
14 | #endif |
15 | |
16 | #if !defined(HAS_GETTIMEOFDAY) && defined(WIN32) |
17 | #define HAS_GETTIMEOFDAY |
18 | |
19 | /* shows up in winsock.h? |
20 | struct timeval { |
21 | long tv_sec; |
22 | long tv_usec; |
23 | } |
24 | */ |
25 | |
26 | int |
27 | gettimeofday (struct timeval *tp, int nothing) |
28 | { |
29 | SYSTEMTIME st; |
30 | time_t tt; |
31 | struct tm tmtm; |
32 | /* mktime converts local to UTC */ |
33 | GetLocalTime (&st); |
34 | tmtm.tm_sec = st.wSecond; |
35 | tmtm.tm_min = st.wMinute; |
36 | tmtm.tm_hour = st.wHour; |
37 | tmtm.tm_mday = st.wDay; |
38 | tmtm.tm_mon = st.wMonth - 1; |
39 | tmtm.tm_year = st.wYear - 1900; |
40 | tmtm.tm_isdst = -1; |
41 | tt = mktime (&tmtm); |
42 | tp->tv_sec = tt; |
43 | tp->tv_usec = st.wMilliseconds * 1000; |
44 | return 0; |
45 | } |
46 | #endif |
47 | |
48 | #if !defined(HAS_GETTIMEOFDAY) && defined(VMS) |
49 | #define HAS_GETTIMEOFDAY |
50 | |
51 | #include <time.h> /* gettimeofday */ |
52 | #include <stdlib.h> /* qdiv */ |
53 | #include <starlet.h> /* sys$gettim */ |
54 | #include <descrip.h> |
55 | |
56 | /* |
57 | VMS binary time is expressed in 100 nano-seconds since |
58 | system base time which is 17-NOV-1858 00:00:00.00 |
59 | */ |
60 | |
61 | #define DIV_100NS_TO_SECS 10000000L |
62 | #define DIV_100NS_TO_USECS 10L |
63 | |
64 | /* |
65 | gettimeofday is supposed to return times since the epoch |
66 | so need to determine this in terms of VMS base time |
67 | */ |
68 | static $DESCRIPTOR(dscepoch,"01-JAN-1970 00:00:00.00"); |
69 | |
70 | static __int64 base_adjust=0; |
71 | |
72 | int |
73 | gettimeofday (struct timeval *tp, void *tpz) |
74 | { |
75 | long ret; |
76 | __int64 quad; |
77 | __qdiv_t ans1,ans2; |
78 | |
79 | /* |
80 | In case of error, tv_usec = 0 and tv_sec = VMS condition code. |
81 | The return from function is also set to -1. |
82 | This is not exactly as per the manual page. |
83 | */ |
84 | |
85 | tp->tv_usec = 0; |
86 | |
87 | if (base_adjust==0) { /* Need to determine epoch adjustment */ |
88 | ret=sys$bintim(&dscepoch,&base_adjust); |
89 | if (1 != (ret &&1)) { |
90 | tp->tv_sec = ret; |
91 | return -1; |
92 | } |
93 | } |
94 | |
95 | ret=sys$gettim(&quad); /* Get VMS system time */ |
96 | if ((1 && ret) == 1) { |
97 | quad -= base_adjust; /* convert to epoch offset */ |
98 | ans1=qdiv(quad,DIV_100NS_TO_SECS); |
99 | ans2=qdiv(ans1.rem,DIV_100NS_TO_USECS); |
100 | tp->tv_sec = ans1.quot; /* Whole seconds */ |
101 | tp->tv_usec = ans2.quot; /* Micro-seconds */ |
102 | } else { |
103 | tp->tv_sec = ret; |
104 | return -1; |
105 | } |
106 | return 0; |
107 | } |
108 | #endif |
109 | |
110 | #if !defined(HAS_USLEEP) && defined(HAS_SELECT) |
111 | #ifndef SELECT_IS_BROKEN |
112 | #define HAS_USLEEP |
113 | #define usleep hrt_usleep /* could conflict with ncurses for static build */ |
114 | |
115 | void |
116 | hrt_usleep(unsigned long usec) |
117 | { |
118 | struct timeval tv; |
119 | tv.tv_sec = 0; |
120 | tv.tv_usec = usec; |
121 | select(0, (Select_fd_set_t)NULL, (Select_fd_set_t)NULL, |
122 | (Select_fd_set_t)NULL, &tv); |
123 | } |
124 | #endif |
125 | #endif |
126 | |
127 | #if !defined(HAS_USLEEP) && defined(WIN32) |
128 | #define HAS_USLEEP |
129 | #define usleep hrt_usleep /* could conflict with ncurses for static build */ |
130 | |
131 | void |
132 | hrt_usleep(unsigned long usec) |
133 | { |
134 | long msec; |
135 | msec = usec / 1000; |
136 | Sleep (msec); |
137 | } |
138 | #endif |
139 | |
140 | |
141 | #if !defined(HAS_UALARM) && defined(HAS_SETITIMER) |
142 | #define HAS_UALARM |
143 | #define ualarm hrt_ualarm /* could conflict with ncurses for static build */ |
144 | |
145 | int |
146 | hrt_ualarm(int usec, int interval) |
147 | { |
148 | struct itimerval itv; |
149 | itv.it_value.tv_sec = usec / 1000000; |
150 | itv.it_value.tv_usec = usec % 1000000; |
151 | itv.it_interval.tv_sec = interval / 1000000; |
152 | itv.it_interval.tv_usec = interval % 1000000; |
153 | return setitimer(ITIMER_REAL, &itv, 0); |
154 | } |
155 | #endif |
156 | |
157 | #ifdef HAS_GETTIMEOFDAY |
158 | |
159 | static void |
160 | myU2time(UV *ret) |
161 | { |
162 | struct timeval Tp; |
163 | int status; |
164 | status = gettimeofday (&Tp, NULL); |
165 | ret[0] = Tp.tv_sec; |
166 | ret[1] = Tp.tv_usec; |
167 | } |
168 | |
169 | static double |
170 | myNVtime() |
171 | { |
172 | struct timeval Tp; |
173 | int status; |
174 | status = gettimeofday (&Tp, NULL); |
175 | return Tp.tv_sec + (Tp.tv_usec / 1000000.); |
176 | } |
177 | |
178 | #endif |
179 | |
180 | MODULE = Time::HiRes PACKAGE = Time::HiRes |
181 | |
182 | PROTOTYPES: ENABLE |
183 | |
184 | BOOT: |
185 | #ifdef ATLEASTFIVEOHOHFIVE |
186 | #ifdef HAS_GETTIMEOFDAY |
187 | hv_store(PL_modglobal, "Time::NVtime", 12, newSViv((IV) myNVtime), 0); |
188 | hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) myU2time), 0); |
189 | #endif |
190 | #endif |
191 | |
192 | #ifdef HAS_USLEEP |
193 | |
194 | void |
195 | usleep(useconds) |
196 | int useconds |
197 | |
198 | void |
199 | sleep(fseconds) |
200 | double fseconds |
201 | CODE: |
202 | int useconds = fseconds * 1000000; |
203 | usleep (useconds); |
204 | |
205 | #endif |
206 | |
207 | #ifdef HAS_UALARM |
208 | |
209 | int |
210 | ualarm(useconds,interval=0) |
211 | int useconds |
212 | int interval |
213 | |
214 | int |
215 | alarm(fseconds,finterval=0) |
216 | double fseconds |
217 | double finterval |
218 | PREINIT: |
219 | int useconds, uinterval; |
220 | CODE: |
221 | useconds = fseconds * 1000000; |
222 | uinterval = finterval * 1000000; |
223 | RETVAL = ualarm (useconds, uinterval); |
224 | |
225 | #endif |
226 | |
227 | #ifdef HAS_GETTIMEOFDAY |
228 | |
229 | void |
230 | gettimeofday() |
231 | PREINIT: |
232 | struct timeval Tp; |
233 | PPCODE: |
234 | int status; |
235 | status = gettimeofday (&Tp, NULL); |
236 | if (GIMME == G_ARRAY) { |
237 | EXTEND(sp, 2); |
238 | PUSHs(sv_2mortal(newSViv(Tp.tv_sec))); |
239 | PUSHs(sv_2mortal(newSViv(Tp.tv_usec))); |
240 | } else { |
241 | EXTEND(sp, 1); |
242 | PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0)))); |
243 | } |
244 | |
245 | double |
246 | time() |
247 | PREINIT: |
248 | struct timeval Tp; |
249 | CODE: |
250 | int status; |
251 | status = gettimeofday (&Tp, NULL); |
252 | RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.); |
253 | OUTPUT: |
254 | RETVAL |
255 | |
256 | #endif |
257 | |
258 | # $Id: HiRes.xs,v 1.11 1999/03/16 02:27:38 wegscd Exp wegscd $ |
259 | |
260 | # $Log: HiRes.xs,v $ |
261 | # Revision 1.11 1999/03/16 02:27:38 wegscd |
262 | # Add U2time, NVtime. Fix symbols for static link. |
263 | # |
264 | # Revision 1.10 1998/09/30 02:36:25 wegscd |
265 | # Add VMS changes. |
266 | # |
267 | # Revision 1.9 1998/07/07 02:42:06 wegscd |
268 | # Win32 usleep() |
269 | # |
270 | # Revision 1.8 1998/07/02 01:47:26 wegscd |
271 | # Add Win32 code for gettimeofday. |
272 | # |
273 | # Revision 1.7 1997/11/13 02:08:12 wegscd |
274 | # Add missing EXTEND in gettimeofday() scalar code. |
275 | # |
276 | # Revision 1.6 1997/11/11 02:32:35 wegscd |
277 | # Do something useful when calling gettimeofday() in a scalar context. |
278 | # The patch is courtesy of Gisle Aas. |
279 | # |
280 | # Revision 1.5 1997/11/06 03:10:47 wegscd |
281 | # Fake ualarm() if we have setitimer. |
282 | # |
283 | # Revision 1.4 1997/11/05 05:41:23 wegscd |
284 | # Turn prototypes ON (suggested by Gisle Aas) |
285 | # |
286 | # Revision 1.3 1997/10/13 20:56:15 wegscd |
287 | # Add PROTOTYPES: DISABLE |
288 | # |
289 | # Revision 1.2 1997/05/23 01:01:38 wegscd |
290 | # Conditional compilation, depending on what the OS gives us. |
291 | # |
292 | # Revision 1.1 1996/09/03 18:26:35 wegscd |
293 | # Initial revision |
294 | # |
295 | # |