-lpthreads missing in AIX.
[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
5cdb7193 110#ifdef __VAX
111static long base_adjust=0L;
112#else
dcf686c9 113static __int64 base_adjust=0;
5cdb7193 114#endif
dcf686c9 115
116int
117gettimeofday (struct timeval *tp, void *tpz)
118{
119 long ret;
5cdb7193 120#ifdef __VAX
121 long quad;
122 div_t ans1,ans2;
123#else
dcf686c9 124 __int64 quad;
125 __qdiv_t ans1,ans2;
5cdb7193 126#endif
dcf686c9 127/*
128 In case of error, tv_usec = 0 and tv_sec = VMS condition code.
129 The return from function is also set to -1.
130 This is not exactly as per the manual page.
131*/
132
133 tp->tv_usec = 0;
134
135 if (base_adjust==0) { /* Need to determine epoch adjustment */
136 ret=sys$bintim(&dscepoch,&base_adjust);
137 if (1 != (ret &&1)) {
138 tp->tv_sec = ret;
139 return -1;
140 }
141 }
142
143 ret=sys$gettim(&quad); /* Get VMS system time */
144 if ((1 && ret) == 1) {
145 quad -= base_adjust; /* convert to epoch offset */
5cdb7193 146#ifdef __VAX
147 ans1=div(quad,DIV_100NS_TO_SECS);
148 ans2=div(ans1.rem,DIV_100NS_TO_USECS);
149#else
dcf686c9 150 ans1=qdiv(quad,DIV_100NS_TO_SECS);
151 ans2=qdiv(ans1.rem,DIV_100NS_TO_USECS);
5cdb7193 152#endif
dcf686c9 153 tp->tv_sec = ans1.quot; /* Whole seconds */
154 tp->tv_usec = ans2.quot; /* Micro-seconds */
155 } else {
156 tp->tv_sec = ret;
157 return -1;
158 }
159 return 0;
160}
161#endif
162
163#if !defined(HAS_USLEEP) && defined(HAS_SELECT)
164#ifndef SELECT_IS_BROKEN
165#define HAS_USLEEP
166#define usleep hrt_usleep /* could conflict with ncurses for static build */
167
168void
169hrt_usleep(unsigned long usec)
170{
171 struct timeval tv;
172 tv.tv_sec = 0;
173 tv.tv_usec = usec;
174 select(0, (Select_fd_set_t)NULL, (Select_fd_set_t)NULL,
175 (Select_fd_set_t)NULL, &tv);
176}
177#endif
178#endif
179
180#if !defined(HAS_USLEEP) && defined(WIN32)
181#define HAS_USLEEP
182#define usleep hrt_usleep /* could conflict with ncurses for static build */
183
184void
185hrt_usleep(unsigned long usec)
186{
187 long msec;
188 msec = usec / 1000;
189 Sleep (msec);
190}
191#endif
192
193
194#if !defined(HAS_UALARM) && defined(HAS_SETITIMER)
195#define HAS_UALARM
196#define ualarm hrt_ualarm /* could conflict with ncurses for static build */
197
198int
199hrt_ualarm(int usec, int interval)
200{
201 struct itimerval itv;
202 itv.it_value.tv_sec = usec / 1000000;
203 itv.it_value.tv_usec = usec % 1000000;
204 itv.it_interval.tv_sec = interval / 1000000;
205 itv.it_interval.tv_usec = interval % 1000000;
206 return setitimer(ITIMER_REAL, &itv, 0);
207}
208#endif
209
210#ifdef HAS_GETTIMEOFDAY
211
a2e20b18 212static int
dcf686c9 213myU2time(UV *ret)
214{
215 struct timeval Tp;
216 int status;
217 status = gettimeofday (&Tp, NULL);
218 ret[0] = Tp.tv_sec;
219 ret[1] = Tp.tv_usec;
a2e20b18 220 return status;
dcf686c9 221}
222
3c72ec00 223static NV
dcf686c9 224myNVtime()
225{
226 struct timeval Tp;
227 int status;
228 status = gettimeofday (&Tp, NULL);
a2e20b18 229 return status == 0 ? Tp.tv_sec + (Tp.tv_usec / 1000000.) : -1.0;
dcf686c9 230}
231
232#endif
233
234MODULE = Time::HiRes PACKAGE = Time::HiRes
235
236PROTOTYPES: ENABLE
237
238BOOT:
dcf686c9 239#ifdef HAS_GETTIMEOFDAY
a2e20b18 240{
241 UV auv[2];
242 hv_store(PL_modglobal, "Time::NVtime", 12, newSViv((IV) myNVtime()), 0);
243 if (myU2time(auv) == 0)
244 hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) auv[0]), 0);
245}
dcf686c9 246#endif
dcf686c9 247
3c72ec00 248IV
249constant(name, arg)
250 char * name
251 int arg
252
dcf686c9 253#ifdef HAS_USLEEP
254
255void
256usleep(useconds)
257 int useconds
258
259void
260sleep(fseconds)
3c72ec00 261 NV fseconds
dcf686c9 262 CODE:
263 int useconds = fseconds * 1000000;
264 usleep (useconds);
265
266#endif
267
268#ifdef HAS_UALARM
269
270int
271ualarm(useconds,interval=0)
272 int useconds
273 int interval
274
275int
276alarm(fseconds,finterval=0)
3c72ec00 277 NV fseconds
278 NV finterval
dcf686c9 279 PREINIT:
280 int useconds, uinterval;
281 CODE:
282 useconds = fseconds * 1000000;
283 uinterval = finterval * 1000000;
284 RETVAL = ualarm (useconds, uinterval);
285
c6c619a9 286 OUTPUT:
287 RETVAL
288
dcf686c9 289#endif
290
291#ifdef HAS_GETTIMEOFDAY
292
293void
294gettimeofday()
295 PREINIT:
296 struct timeval Tp;
297 PPCODE:
298 int status;
299 status = gettimeofday (&Tp, NULL);
300 if (GIMME == G_ARRAY) {
301 EXTEND(sp, 2);
302 PUSHs(sv_2mortal(newSViv(Tp.tv_sec)));
303 PUSHs(sv_2mortal(newSViv(Tp.tv_usec)));
304 } else {
305 EXTEND(sp, 1);
306 PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
307 }
308
3c72ec00 309NV
dcf686c9 310time()
311 PREINIT:
312 struct timeval Tp;
313 CODE:
314 int status;
315 status = gettimeofday (&Tp, NULL);
316 RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.);
317 OUTPUT:
318 RETVAL
319
320#endif
321
3c72ec00 322#if defined(HAS_GETITIMER) && defined(HAS_SETITIMER)
323
324#define TV2NV(tv) ((NV)((tv).tv_sec) + 0.000001 * (NV)((tv).tv_usec))
325
326void
327setitimer(which, seconds, interval = 0)
328 int which
329 NV seconds
330 NV interval
331 PREINIT:
332 struct itimerval newit;
333 struct itimerval oldit;
334 PPCODE:
335 newit.it_value.tv_sec = seconds;
336 newit.it_value.tv_usec =
337 (seconds - (NV)newit.it_value.tv_sec) * 1000000.0;
338 newit.it_interval.tv_sec = interval;
339 newit.it_interval.tv_usec =
340 (interval - (NV)newit.it_interval.tv_sec) * 1000000.0;
341 if (setitimer(which, &newit, &oldit) == 0) {
342 EXTEND(sp, 1);
343 PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_value))));
344 if (GIMME == G_ARRAY) {
345 EXTEND(sp, 1);
346 PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_interval))));
347 }
348 }
349
350void
351getitimer(which)
352 int which
353 PREINIT:
354 struct itimerval nowit;
355 PPCODE:
356 if (getitimer(which, &nowit) == 0) {
357 EXTEND(sp, 1);
358 PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_value))));
359 if (GIMME == G_ARRAY) {
360 EXTEND(sp, 1);
361 PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_interval))));
362 }
363 }
364
365#endif
366
dcf686c9 367# $Id: HiRes.xs,v 1.11 1999/03/16 02:27:38 wegscd Exp wegscd $
368
369# $Log: HiRes.xs,v $
370# Revision 1.11 1999/03/16 02:27:38 wegscd
371# Add U2time, NVtime. Fix symbols for static link.
372#
373# Revision 1.10 1998/09/30 02:36:25 wegscd
374# Add VMS changes.
375#
376# Revision 1.9 1998/07/07 02:42:06 wegscd
377# Win32 usleep()
378#
379# Revision 1.8 1998/07/02 01:47:26 wegscd
380# Add Win32 code for gettimeofday.
381#
382# Revision 1.7 1997/11/13 02:08:12 wegscd
383# Add missing EXTEND in gettimeofday() scalar code.
384#
385# Revision 1.6 1997/11/11 02:32:35 wegscd
386# Do something useful when calling gettimeofday() in a scalar context.
387# The patch is courtesy of Gisle Aas.
388#
389# Revision 1.5 1997/11/06 03:10:47 wegscd
390# Fake ualarm() if we have setitimer.
391#
392# Revision 1.4 1997/11/05 05:41:23 wegscd
393# Turn prototypes ON (suggested by Gisle Aas)
394#
395# Revision 1.3 1997/10/13 20:56:15 wegscd
396# Add PROTOTYPES: DISABLE
397#
398# Revision 1.2 1997/05/23 01:01:38 wegscd
399# Conditional compilation, depending on what the OS gives us.
400#
401# Revision 1.1 1996/09/03 18:26:35 wegscd
402# Initial revision
403#
404#