ext/ + -Wall
[p5sagit/p5-mst-13.2.git] / ext / Time / HiRes / HiRes.xs
CommitLineData
dcf686c9 1#ifdef __cplusplus
2extern "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
3c72ec00 16static IV
17constant(char *name, int arg)
18{
19 errno = 0;
20 switch (*name) {
21 case 'I':
22 if (strEQ(name, "ITIMER_REAL"))
23#ifdef ITIMER_REAL
24 return ITIMER_REAL;
25#else
26 goto not_there;
27#endif
28 if (strEQ(name, "ITIMER_REALPROF"))
29#ifdef ITIMER_REALPROF
30 return ITIMER_REALPROF;
31#else
32 goto not_there;
33#endif
34 if (strEQ(name, "ITIMER_VIRTUAL"))
35#ifdef ITIMER_VIRTUAL
36 return ITIMER_VIRTUAL;
37#else
38 goto not_there;
39#endif
40 if (strEQ(name, "ITIMER_PROF"))
41#ifdef ITIMER_PROF
42 return ITIMER_PROF;
43#else
44 goto not_there;
45#endif
46 break;
47 }
48 errno = EINVAL;
49 return 0;
50
51not_there:
52 errno = ENOENT;
53 return 0;
54}
55
dcf686c9 56#if !defined(HAS_GETTIMEOFDAY) && defined(WIN32)
57#define HAS_GETTIMEOFDAY
58
59/* shows up in winsock.h?
60struct timeval {
61 long tv_sec;
62 long tv_usec;
63}
64*/
65
66int
67gettimeofday (struct timeval *tp, int nothing)
68{
69 SYSTEMTIME st;
70 time_t tt;
71 struct tm tmtm;
72 /* mktime converts local to UTC */
73 GetLocalTime (&st);
74 tmtm.tm_sec = st.wSecond;
75 tmtm.tm_min = st.wMinute;
76 tmtm.tm_hour = st.wHour;
77 tmtm.tm_mday = st.wDay;
78 tmtm.tm_mon = st.wMonth - 1;
79 tmtm.tm_year = st.wYear - 1900;
80 tmtm.tm_isdst = -1;
81 tt = mktime (&tmtm);
82 tp->tv_sec = tt;
83 tp->tv_usec = st.wMilliseconds * 1000;
84 return 0;
85}
86#endif
87
88#if !defined(HAS_GETTIMEOFDAY) && defined(VMS)
89#define HAS_GETTIMEOFDAY
90
91#include <time.h> /* gettimeofday */
92#include <stdlib.h> /* qdiv */
93#include <starlet.h> /* sys$gettim */
94#include <descrip.h>
95
96/*
97 VMS binary time is expressed in 100 nano-seconds since
98 system base time which is 17-NOV-1858 00:00:00.00
99*/
100
101#define DIV_100NS_TO_SECS 10000000L
102#define DIV_100NS_TO_USECS 10L
103
104/*
105 gettimeofday is supposed to return times since the epoch
106 so need to determine this in terms of VMS base time
107*/
108static $DESCRIPTOR(dscepoch,"01-JAN-1970 00:00:00.00");
109
110static __int64 base_adjust=0;
111
112int
113gettimeofday (struct timeval *tp, void *tpz)
114{
115 long ret;
116 __int64 quad;
117 __qdiv_t ans1,ans2;
118
119/*
120 In case of error, tv_usec = 0 and tv_sec = VMS condition code.
121 The return from function is also set to -1.
122 This is not exactly as per the manual page.
123*/
124
125 tp->tv_usec = 0;
126
127 if (base_adjust==0) { /* Need to determine epoch adjustment */
128 ret=sys$bintim(&dscepoch,&base_adjust);
129 if (1 != (ret &&1)) {
130 tp->tv_sec = ret;
131 return -1;
132 }
133 }
134
135 ret=sys$gettim(&quad); /* Get VMS system time */
136 if ((1 && ret) == 1) {
137 quad -= base_adjust; /* convert to epoch offset */
138 ans1=qdiv(quad,DIV_100NS_TO_SECS);
139 ans2=qdiv(ans1.rem,DIV_100NS_TO_USECS);
140 tp->tv_sec = ans1.quot; /* Whole seconds */
141 tp->tv_usec = ans2.quot; /* Micro-seconds */
142 } else {
143 tp->tv_sec = ret;
144 return -1;
145 }
146 return 0;
147}
148#endif
149
150#if !defined(HAS_USLEEP) && defined(HAS_SELECT)
151#ifndef SELECT_IS_BROKEN
152#define HAS_USLEEP
153#define usleep hrt_usleep /* could conflict with ncurses for static build */
154
155void
156hrt_usleep(unsigned long usec)
157{
158 struct timeval tv;
159 tv.tv_sec = 0;
160 tv.tv_usec = usec;
161 select(0, (Select_fd_set_t)NULL, (Select_fd_set_t)NULL,
162 (Select_fd_set_t)NULL, &tv);
163}
164#endif
165#endif
166
167#if !defined(HAS_USLEEP) && defined(WIN32)
168#define HAS_USLEEP
169#define usleep hrt_usleep /* could conflict with ncurses for static build */
170
171void
172hrt_usleep(unsigned long usec)
173{
174 long msec;
175 msec = usec / 1000;
176 Sleep (msec);
177}
178#endif
179
180
181#if !defined(HAS_UALARM) && defined(HAS_SETITIMER)
182#define HAS_UALARM
183#define ualarm hrt_ualarm /* could conflict with ncurses for static build */
184
185int
186hrt_ualarm(int usec, int interval)
187{
188 struct itimerval itv;
189 itv.it_value.tv_sec = usec / 1000000;
190 itv.it_value.tv_usec = usec % 1000000;
191 itv.it_interval.tv_sec = interval / 1000000;
192 itv.it_interval.tv_usec = interval % 1000000;
193 return setitimer(ITIMER_REAL, &itv, 0);
194}
195#endif
196
197#ifdef HAS_GETTIMEOFDAY
198
a2e20b18 199static int
dcf686c9 200myU2time(UV *ret)
201{
202 struct timeval Tp;
203 int status;
204 status = gettimeofday (&Tp, NULL);
205 ret[0] = Tp.tv_sec;
206 ret[1] = Tp.tv_usec;
a2e20b18 207 return status;
dcf686c9 208}
209
3c72ec00 210static NV
dcf686c9 211myNVtime()
212{
213 struct timeval Tp;
214 int status;
215 status = gettimeofday (&Tp, NULL);
a2e20b18 216 return status == 0 ? Tp.tv_sec + (Tp.tv_usec / 1000000.) : -1.0;
dcf686c9 217}
218
219#endif
220
221MODULE = Time::HiRes PACKAGE = Time::HiRes
222
223PROTOTYPES: ENABLE
224
225BOOT:
dcf686c9 226#ifdef HAS_GETTIMEOFDAY
a2e20b18 227{
228 UV auv[2];
229 hv_store(PL_modglobal, "Time::NVtime", 12, newSViv((IV) myNVtime()), 0);
230 if (myU2time(auv) == 0)
231 hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) auv[0]), 0);
232}
dcf686c9 233#endif
dcf686c9 234
3c72ec00 235IV
236constant(name, arg)
237 char * name
238 int arg
239
dcf686c9 240#ifdef HAS_USLEEP
241
242void
243usleep(useconds)
244 int useconds
245
246void
247sleep(fseconds)
3c72ec00 248 NV fseconds
dcf686c9 249 CODE:
250 int useconds = fseconds * 1000000;
251 usleep (useconds);
252
253#endif
254
255#ifdef HAS_UALARM
256
257int
258ualarm(useconds,interval=0)
259 int useconds
260 int interval
261
262int
263alarm(fseconds,finterval=0)
3c72ec00 264 NV fseconds
265 NV finterval
dcf686c9 266 PREINIT:
267 int useconds, uinterval;
268 CODE:
269 useconds = fseconds * 1000000;
270 uinterval = finterval * 1000000;
271 RETVAL = ualarm (useconds, uinterval);
272
c6c619a9 273 OUTPUT:
274 RETVAL
275
dcf686c9 276#endif
277
278#ifdef HAS_GETTIMEOFDAY
279
280void
281gettimeofday()
282 PREINIT:
283 struct timeval Tp;
284 PPCODE:
285 int status;
286 status = gettimeofday (&Tp, NULL);
287 if (GIMME == G_ARRAY) {
288 EXTEND(sp, 2);
289 PUSHs(sv_2mortal(newSViv(Tp.tv_sec)));
290 PUSHs(sv_2mortal(newSViv(Tp.tv_usec)));
291 } else {
292 EXTEND(sp, 1);
293 PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
294 }
295
3c72ec00 296NV
dcf686c9 297time()
298 PREINIT:
299 struct timeval Tp;
300 CODE:
301 int status;
302 status = gettimeofday (&Tp, NULL);
303 RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.);
304 OUTPUT:
305 RETVAL
306
307#endif
308
3c72ec00 309#if defined(HAS_GETITIMER) && defined(HAS_SETITIMER)
310
311#define TV2NV(tv) ((NV)((tv).tv_sec) + 0.000001 * (NV)((tv).tv_usec))
312
313void
314setitimer(which, seconds, interval = 0)
315 int which
316 NV seconds
317 NV interval
318 PREINIT:
319 struct itimerval newit;
320 struct itimerval oldit;
321 PPCODE:
322 newit.it_value.tv_sec = seconds;
323 newit.it_value.tv_usec =
324 (seconds - (NV)newit.it_value.tv_sec) * 1000000.0;
325 newit.it_interval.tv_sec = interval;
326 newit.it_interval.tv_usec =
327 (interval - (NV)newit.it_interval.tv_sec) * 1000000.0;
328 if (setitimer(which, &newit, &oldit) == 0) {
329 EXTEND(sp, 1);
330 PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_value))));
331 if (GIMME == G_ARRAY) {
332 EXTEND(sp, 1);
333 PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_interval))));
334 }
335 }
336
337void
338getitimer(which)
339 int which
340 PREINIT:
341 struct itimerval nowit;
342 PPCODE:
343 if (getitimer(which, &nowit) == 0) {
344 EXTEND(sp, 1);
345 PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_value))));
346 if (GIMME == G_ARRAY) {
347 EXTEND(sp, 1);
348 PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_interval))));
349 }
350 }
351
352#endif
353
dcf686c9 354# $Id: HiRes.xs,v 1.11 1999/03/16 02:27:38 wegscd Exp wegscd $
355
356# $Log: HiRes.xs,v $
357# Revision 1.11 1999/03/16 02:27:38 wegscd
358# Add U2time, NVtime. Fix symbols for static link.
359#
360# Revision 1.10 1998/09/30 02:36:25 wegscd
361# Add VMS changes.
362#
363# Revision 1.9 1998/07/07 02:42:06 wegscd
364# Win32 usleep()
365#
366# Revision 1.8 1998/07/02 01:47:26 wegscd
367# Add Win32 code for gettimeofday.
368#
369# Revision 1.7 1997/11/13 02:08:12 wegscd
370# Add missing EXTEND in gettimeofday() scalar code.
371#
372# Revision 1.6 1997/11/11 02:32:35 wegscd
373# Do something useful when calling gettimeofday() in a scalar context.
374# The patch is courtesy of Gisle Aas.
375#
376# Revision 1.5 1997/11/06 03:10:47 wegscd
377# Fake ualarm() if we have setitimer.
378#
379# Revision 1.4 1997/11/05 05:41:23 wegscd
380# Turn prototypes ON (suggested by Gisle Aas)
381#
382# Revision 1.3 1997/10/13 20:56:15 wegscd
383# Add PROTOTYPES: DISABLE
384#
385# Revision 1.2 1997/05/23 01:01:38 wegscd
386# Conditional compilation, depending on what the OS gives us.
387#
388# Revision 1.1 1996/09/03 18:26:35 wegscd
389# Initial revision
390#
391#