long =item
[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
199static void
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;
207}
208
3c72ec00 209static NV
dcf686c9 210myNVtime()
211{
212 struct timeval Tp;
213 int status;
214 status = gettimeofday (&Tp, NULL);
215 return Tp.tv_sec + (Tp.tv_usec / 1000000.);
216}
217
218#endif
219
220MODULE = Time::HiRes PACKAGE = Time::HiRes
221
222PROTOTYPES: ENABLE
223
224BOOT:
dcf686c9 225#ifdef HAS_GETTIMEOFDAY
226 hv_store(PL_modglobal, "Time::NVtime", 12, newSViv((IV) myNVtime), 0);
227 hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) myU2time), 0);
228#endif
dcf686c9 229
3c72ec00 230IV
231constant(name, arg)
232 char * name
233 int arg
234
dcf686c9 235#ifdef HAS_USLEEP
236
237void
238usleep(useconds)
239 int useconds
240
241void
242sleep(fseconds)
3c72ec00 243 NV fseconds
dcf686c9 244 CODE:
245 int useconds = fseconds * 1000000;
246 usleep (useconds);
247
248#endif
249
250#ifdef HAS_UALARM
251
252int
253ualarm(useconds,interval=0)
254 int useconds
255 int interval
256
257int
258alarm(fseconds,finterval=0)
3c72ec00 259 NV fseconds
260 NV finterval
dcf686c9 261 PREINIT:
262 int useconds, uinterval;
263 CODE:
264 useconds = fseconds * 1000000;
265 uinterval = finterval * 1000000;
266 RETVAL = ualarm (useconds, uinterval);
267
268#endif
269
270#ifdef HAS_GETTIMEOFDAY
271
272void
273gettimeofday()
274 PREINIT:
275 struct timeval Tp;
276 PPCODE:
277 int status;
278 status = gettimeofday (&Tp, NULL);
279 if (GIMME == G_ARRAY) {
280 EXTEND(sp, 2);
281 PUSHs(sv_2mortal(newSViv(Tp.tv_sec)));
282 PUSHs(sv_2mortal(newSViv(Tp.tv_usec)));
283 } else {
284 EXTEND(sp, 1);
285 PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
286 }
287
3c72ec00 288NV
dcf686c9 289time()
290 PREINIT:
291 struct timeval Tp;
292 CODE:
293 int status;
294 status = gettimeofday (&Tp, NULL);
295 RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.);
296 OUTPUT:
297 RETVAL
298
299#endif
300
3c72ec00 301#if defined(HAS_GETITIMER) && defined(HAS_SETITIMER)
302
303#define TV2NV(tv) ((NV)((tv).tv_sec) + 0.000001 * (NV)((tv).tv_usec))
304
305void
306setitimer(which, seconds, interval = 0)
307 int which
308 NV seconds
309 NV interval
310 PREINIT:
311 struct itimerval newit;
312 struct itimerval oldit;
313 PPCODE:
314 newit.it_value.tv_sec = seconds;
315 newit.it_value.tv_usec =
316 (seconds - (NV)newit.it_value.tv_sec) * 1000000.0;
317 newit.it_interval.tv_sec = interval;
318 newit.it_interval.tv_usec =
319 (interval - (NV)newit.it_interval.tv_sec) * 1000000.0;
320 if (setitimer(which, &newit, &oldit) == 0) {
321 EXTEND(sp, 1);
322 PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_value))));
323 if (GIMME == G_ARRAY) {
324 EXTEND(sp, 1);
325 PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_interval))));
326 }
327 }
328
329void
330getitimer(which)
331 int which
332 PREINIT:
333 struct itimerval nowit;
334 PPCODE:
335 if (getitimer(which, &nowit) == 0) {
336 EXTEND(sp, 1);
337 PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_value))));
338 if (GIMME == G_ARRAY) {
339 EXTEND(sp, 1);
340 PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_interval))));
341 }
342 }
343
344#endif
345
dcf686c9 346# $Id: HiRes.xs,v 1.11 1999/03/16 02:27:38 wegscd Exp wegscd $
347
348# $Log: HiRes.xs,v $
349# Revision 1.11 1999/03/16 02:27:38 wegscd
350# Add U2time, NVtime. Fix symbols for static link.
351#
352# Revision 1.10 1998/09/30 02:36:25 wegscd
353# Add VMS changes.
354#
355# Revision 1.9 1998/07/07 02:42:06 wegscd
356# Win32 usleep()
357#
358# Revision 1.8 1998/07/02 01:47:26 wegscd
359# Add Win32 code for gettimeofday.
360#
361# Revision 1.7 1997/11/13 02:08:12 wegscd
362# Add missing EXTEND in gettimeofday() scalar code.
363#
364# Revision 1.6 1997/11/11 02:32:35 wegscd
365# Do something useful when calling gettimeofday() in a scalar context.
366# The patch is courtesy of Gisle Aas.
367#
368# Revision 1.5 1997/11/06 03:10:47 wegscd
369# Fake ualarm() if we have setitimer.
370#
371# Revision 1.4 1997/11/05 05:41:23 wegscd
372# Turn prototypes ON (suggested by Gisle Aas)
373#
374# Revision 1.3 1997/10/13 20:56:15 wegscd
375# Add PROTOTYPES: DISABLE
376#
377# Revision 1.2 1997/05/23 01:01:38 wegscd
378# Conditional compilation, depending on what the OS gives us.
379#
380# Revision 1.1 1996/09/03 18:26:35 wegscd
381# Initial revision
382#
383#