YAP 7.1.0
time.c
1
2#include "sysbits.h"
3
4#ifdef SIMICS
5#ifdef HAVE_GETRUSAGE
6#undef HAVE_GETRUSAGE
7#endif
8#ifdef HAVE_TIMES
9#undef HAVE_TIMES
10#endif
11#endif /* SIMICS */
12
13#ifdef _WIN32
14#if HAVE_GETRUSAGE
15#undef HAVE_GETRUSAGE
16#endif
17#endif
18
19#if HAVE_GETRUSAGE
20
21#if THREADS
22#define StartOfTimes (*(LOCAL_ThreadHandle.start_of_timesp))
23#define last_time (*(LOCAL_ThreadHandle.last_timep))
24
25#define StartOfTimes_sys (*(LOCAL_ThreadHandle.start_of_times_sysp))
26#define last_time_sys (*(LOCAL_ThreadHandle.last_time_sysp))
27
28#else
29/* since the point YAP was started */
30static struct timeval StartOfTimes;
31
32/* since last call to runtime */
33static struct timeval last_time;
34
35/* same for system time */
36static struct timeval last_time_sys;
37static struct timeval StartOfTimes_sys;
38#endif
39
40/* store user time in this variable */
41void Yap_InitTime(int wid) {
42 struct rusage rusage;
43
44#if THREADS
45 REMOTE_ThreadHandle(wid).start_of_timesp =
46 (struct timeval *)malloc(sizeof(struct timeval));
47 REMOTE_ThreadHandle(wid).last_timep =
48 (struct timeval *)malloc(sizeof(struct timeval));
49 REMOTE_ThreadHandle(wid).start_of_times_sysp =
50 (struct timeval *)malloc(sizeof(struct timeval));
51 REMOTE_ThreadHandle(wid).last_time_sysp =
52 (struct timeval *)malloc(sizeof(struct timeval));
53 getrusage(RUSAGE_SELF, &rusage);
54 (*REMOTE_ThreadHandle(wid).last_timep).tv_sec =
55 (*REMOTE_ThreadHandle(wid).start_of_timesp).tv_sec =
56 rusage.ru_utime.tv_sec;
57 (*REMOTE_ThreadHandle(wid).last_timep).tv_usec =
58 (*REMOTE_ThreadHandle(wid).start_of_timesp).tv_usec =
59 rusage.ru_utime.tv_usec;
60 (*REMOTE_ThreadHandle(wid).last_time_sysp).tv_sec =
61 (*REMOTE_ThreadHandle(wid).start_of_times_sysp).tv_sec =
62 rusage.ru_stime.tv_sec;
63 (*REMOTE_ThreadHandle(wid).last_time_sysp).tv_usec =
64 (*REMOTE_ThreadHandle(wid).start_of_times_sysp).tv_usec =
65 rusage.ru_stime.tv_usec;
66#else
67 getrusage(RUSAGE_SELF, &rusage);
68 last_time.tv_sec = StartOfTimes.tv_sec = rusage.ru_utime.tv_sec;
69 last_time.tv_usec = StartOfTimes.tv_usec = rusage.ru_utime.tv_usec;
70 last_time_sys.tv_sec = StartOfTimes_sys.tv_sec = rusage.ru_stime.tv_sec;
71 last_time_sys.tv_usec = StartOfTimes_sys.tv_usec = rusage.ru_stime.tv_usec;
72#endif
73}
74
75UInt Yap_cputime(void) {
76 CACHE_REGS
77 struct rusage rusage;
78
79 getrusage(RUSAGE_SELF, &rusage);
80 return ((rusage.ru_utime.tv_sec - StartOfTimes.tv_sec)) * 1000 +
81 ((rusage.ru_utime.tv_usec - StartOfTimes.tv_usec) / 1000);
82}
83
84void Yap_cputime_interval(Int *now, Int *interval) {
85 CACHE_REGS
86 struct rusage rusage;
87
88 getrusage(RUSAGE_SELF, &rusage);
89 *now = (rusage.ru_utime.tv_sec - StartOfTimes.tv_sec) * 1000 +
90 (rusage.ru_utime.tv_usec - StartOfTimes.tv_usec) / 1000;
91 *interval = (rusage.ru_utime.tv_sec - last_time.tv_sec) * 1000 +
92 (rusage.ru_utime.tv_usec - last_time.tv_usec) / 1000;
93 last_time.tv_usec = rusage.ru_utime.tv_usec;
94 last_time.tv_sec = rusage.ru_utime.tv_sec;
95}
96
97void Yap_systime_interval(Int *now, Int *interval) {
98 CACHE_REGS
99 struct rusage rusage;
100
101 getrusage(RUSAGE_SELF, &rusage);
102 *now = (rusage.ru_stime.tv_sec - StartOfTimes_sys.tv_sec) * 1000 +
103 (rusage.ru_stime.tv_usec - StartOfTimes_sys.tv_usec) / 1000;
104 *interval = (rusage.ru_stime.tv_sec - last_time_sys.tv_sec) * 1000 +
105 (rusage.ru_stime.tv_usec - last_time_sys.tv_usec) / 1000;
106 last_time_sys.tv_usec = rusage.ru_stime.tv_usec;
107 last_time_sys.tv_sec = rusage.ru_stime.tv_sec;
108}
109
110#elif defined(_WIN32)
111
112#ifdef __GNUC__
113
114/* This is stolen from the Linux kernel.
115 The problem is that mingw32 does not seem to have acces to div */
116#ifndef do_div
117#define do_div(n, base) \
118 ({ \
119 unsigned long __upper, __low, __high, __mod; \
120 asm("" : "=a"(__low), "=d"(__high) : "A"(n)); \
121 __upper = __high; \
122 if (__high) { \
123 __upper = __high % (base); \
124 __high = __high / (base); \
125 } \
126 asm("divl %2" \
127 : "=a"(__low), "=d"(__mod) \
128 : "rm"(base), "0"(__low), "1"(__upper)); \
129 asm("" : "=A"(n) : "a"(__low), "d"(__high)); \
130 __mod; \
131 })
132#endif
133
134#endif
135
136#include <time.h>
137
138typedef union {
139 FILETIME f;
140 __int64 t;
141} win64_time_t;
142
143static win64_time_t StartOfTimes, last_time;
144
145static win64_time_t StartOfTimes_sys, last_time_sys;
146
147static clock_t TimesStartOfTimes, Times_last_time;
148
149/* store user time in this variable */
150void Yap_InitTime(int wid) {
151 HANDLE hProcess = GetCurrentProcess();
152 win64_time_t CreationTime, ExitTime, KernelTime, UserTime;
153 if (!GetProcessTimes(hProcess, &CreationTime.f, &ExitTime.f, &KernelTime.f,
154 &UserTime.f)) {
155 /* WIN98 */
156 clock_t t;
157 t = clock();
158 Times_last_time = TimesStartOfTimes = t;
159 } else {
160#if THREADS
161 REMOTE_ThreadHandle(wid).start_of_timesp =
162 (struct _win64_time_t *)malloc(sizeof(win64_time_t));
163 REMOTE_ThreadHandle(wid).last_timep =
164 (struct _win64_time_t *)malloc(sizeof(win64_time_t));
165 REMOTE_ThreadHandle(wid).start_of_times_sysp =
166 (struct _win64_time_t *)malloc(sizeof(win64_time_t));
167 REMOTE_ThreadHandle(wid).last_time_sysp =
168 (struct _win64_time_t *)malloc(sizeof(win64_time_t));
169 (*REMOTE_ThreadHandle(wid).last_timep).f.dwLowDateTime =
170 UserTime.dwLowDateTime;
171 (*REMOTE_ThreadHandle(wid).last_timep).dwHighDateTime =
172 UserTime.dwHighDateTime;
173 (*REMOTE_ThreadHandle(wid).start_of_timesp).f.dwLowDateTime =
174 UserTime.dwLowDateTime;
175 (*REMOTE_ThreadHandle(wid).start_of_timesp).f.dwHighDateTime =
176 UserTime.dwHighDateTime;
177 (*REMOTE_ThreadHandle(wid).last_time_sysp).f.dwLowDateTime =
178 KernelTime.dwLowDateTime;
179 (*REMOTE_ThreadHandle(wid).last_time_sysp).f.dwHighDateTime =
180 KernelTime.dwHighDateTime;
181 (*REMOTE_ThreadHandle(wid).start_of_times_sysp).f.dwLowDateTime =
182 KernelTime.dwLowDateTime;
183 (*REMOTE_ThreadHandle(wid).start_of_times_sysp).f.dwHighDateTime =
184 KernelTime.dwHighDateTime;
185#else
186 last_time.f.dwLowDateTime = UserTime.f.dwLowDateTime;
187 last_time.f.dwHighDateTime = UserTime.f.dwHighDateTime;
188 StartOfTimes.f.dwLowDateTime = UserTime.f.dwLowDateTime;
189 StartOfTimes.f.dwHighDateTime = UserTime.f.dwHighDateTime;
190 last_time_sys.f.dwLowDateTime = KernelTime.f.dwLowDateTime;
191 last_time_sys.f.dwHighDateTime = KernelTime.f.dwHighDateTime;
192 StartOfTimes_sys.f.dwLowDateTime = KernelTime.f.dwLowDateTime;
193 StartOfTimes_sys.f.dwHighDateTime = KernelTime.f.dwHighDateTime;
194#endif
195 }
196}
197
198UInt Yap_cputime(void) {
199 HANDLE hProcess = GetCurrentProcess();
200 win64_time_t CreationTime, ExitTime, KernelTime, UserTime;
201 if (!GetProcessTimes(hProcess, &CreationTime.f, & ExitTime.f, &KernelTime.f,
202 &UserTime.f)) {
203 clock_t t;
204 t = clock();
205 return (((t - TimesStartOfTimes) * 1000) / CLOCKS_PER_SEC);
206 } else {
207 __int64 t = UserTime.t - StartOfTimes.t;
208 return ((Int)(t / 10000));
209 }
210}
211
212void Yap_cputime_interval(Int *now, Int *interval) {
213 HANDLE hProcess = GetCurrentProcess();
214 win64_time_t CreationTime, ExitTime, KernelTime, UserTime;
215 if (!GetProcessTimes(hProcess, &CreationTime.f, & ExitTime.f, &KernelTime.f,
216 &UserTime.f)) {
217 clock_t t;
218 t = clock();
219 *now = ((t - TimesStartOfTimes) * 1000) / CLOCKS_PER_SEC;
220 *interval = (t - Times_last_time) * 1000 / CLOCKS_PER_SEC;
221 Times_last_time = t;
222 } else {
223 __int64 t1 = UserTime.t - StartOfTimes.t;
224 __int64 t2 = UserTime.t - last_time.t;
225 *now = (Int)(t1 / 10000);
226 *interval = (Int)(t2 / 10000);
227 last_time.f.dwLowDateTime = UserTime.f.dwLowDateTime;
228 last_time.f.dwHighDateTime = UserTime.f.dwHighDateTime;
229 }
230}
231
232void Yap_systime_interval(Int *now, Int *interval) {
233 HANDLE hProcess = GetCurrentProcess();
234 win64_time_t CreationTime, ExitTime, KernelTime, UserTime;
235 if (!GetProcessTimes(hProcess, &CreationTime.f, &ExitTime.f, &KernelTime.f,
236 &UserTime.f)) {
237 *now = *interval = 0; /* not available */
238 } else {
239 __int64 t1 = KernelTime.t - StartOfTimes_sys.t;
240 __int64 t2 = KernelTime.t - last_time_sys.t;
241 *now = (Int)(t1 / 10000);
242 *interval = (Int)(t2 / 10000);
243 last_time_sys.f.dwLowDateTime = KernelTime.f.dwLowDateTime;
244 last_time_sys.f.dwHighDateTime = KernelTime.f.dwHighDateTime;
245 }
246}
247
248#elif HAVE_TIMES
249
250#if defined(_WIN32)
251
252#include <time.h>
253
254#define TicksPerSec CLOCKS_PER_SEC
255
256#else
257
258#if HAVE_SYS_TIMES_H
259#include <sys/times.h>
260#endif
261
262#endif
263
264#if defined(__sun__) && (defined(__svr4__) || defined(__SVR4))
265
266#if HAVE_LIMITS_H
267#include <limits.h>
268#endif
269
270#define TicksPerSec CLK_TCK
271#endif
272
273#if defined(__alpha) || defined(__FreeBSD__) || defined(__linux__) || \
274 defined(__DragonFly__)
275
276#if HAVE_TIME_H
277#include <time.h>
278#endif
279
280#define TicksPerSec sysconf(_SC_CLK_TCK)
281
282#endif
283
284#if !TMS_IN_SYS_TIME
285#if HAVE_SYS_TIMES_H
286#include <sys/times.h>
287#endif
288#endif
289
290static clock_t StartOfTimes, last_time;
291
292static clock_t StartOfTimes_sys, last_time_sys;
293
294/* store user time in this variable */
295static void InitTime(void) {
296 struct tms t;
297 times(&t);
298 (*REMOTE_ThreadHandle(wid).last_timep) = StartOfTimes = t.tms_utime;
299 last_time_sys = StartOfTimes_sys = t.tms_stime;
300}
301
302UInt Yap_cputime(void) {
303 struct tms t;
304 times(&t);
305 return ((t.tms_utime - StartOfTimes) * 1000 / TicksPerSec);
306}
307
308void Yap_cputime_interval(Int *now, Int *interval) {
309 struct tms t;
310 times(&t);
311 *now = ((t.tms_utime - StartOfTimes) * 1000) / TicksPerSec;
312 *interval = (t.tms_utime - last_time) * 1000 / TicksPerSec;
313 last_time = t.tms_utime;
314}
315
316void Yap_systime_interval(Int *now, Int *interval) {
317 struct tms t;
318 times(&t);
319 *now = ((t.tms_stime - StartOfTimes_sys) * 1000) / TicksPerSec;
320 *interval = (t.tms_stime - last_time_sys) * 1000 / TicksPerSec;
321 last_time_sys = t.tms_stime;
322}
323
324#else /* HAVE_TIMES */
325
326#ifdef SIMICS
327
328#include <sys/time.h>
329
330/* since the point YAP was started */
331static struct timeval StartOfTimes;
332
333/* since last call to runtime */
334static struct timeval last_time;
335
336/* store user time in this variable */
337static void InitTime(int wid) {
338 struct timeval tp;
339
340 gettimeofday(&tp, NULL);
341 (*REMOTE_ThreadHandle(wid).last_timep).f.tv_sec =
342 (*REMOTE_ThreadHandle.start_of_timesp(wid)).tv_sec = tp.tv_sec;
343 (*REMOTE_ThreadHandle(wid).last_timep).f.tv_usec =
344 (*REMOTE_ThreadHandle.start_of_timesp(wid)).tv_usec = tp.tv_usec;
345}
346
347UInt Yap_cputime(void) {
348 struct timeval tp;
349
350 gettimeofday(&tp, NULL);
351 if (StartOfTimes.tv_usec > tp.tv_usec)
352 return ((tp.tv_sec - StartOfTimes.tv_sec - 1) * 1000 +
353 (StartOfTimes.tv_usec - tp.tv_usec) / 1000);
354 else
355 return ((tp.tv_sec - StartOfTimes.tv_sec)) * 1000 +
356 ((tp.tv_usec - StartOfTimes.tv_usec) / 1000);
357}
358
359void Yap_cputime_interval(Int *now, Int *interval) {
360 struct timeval tp;
361
362 gettimeofday(&tp, NULL);
363 *now = (tp.tv_sec - StartOfTimes.tv_sec) * 1000 +
364 (tp.tv_usec - StartOfTimes.tv_usec) / 1000;
365 *interval = (tp.tv_sec - last_time.tv_sec) * 1000 +
366 (tp.tv_usec - last_time.tv_usec) / 1000;
367 last_time.tv_usec = tp.tv_usec;
368 last_time.tv_sec = tp.tv_sec;
369}
370
371void Yap_systime_interval(Int *now, Int *interval) {
372 *now = *interval = 0; /* not available */
373}
374
375#endif /* SIMICS */
376
377#ifdef COMMENTED_OUT
378/* This code is not working properly. I left it here to help future ports */
379#ifdef MPW
380
381#include <Events.h>
382#include <files.h>
383
384#define TicksPerSec 60.0
385
386static double real_cputime() { return (((double)TickCount()) / TicksPerSec); }
387
388#endif /* MPW */
389
390#ifdef LATTICE
391
392#include "osbind.h"
393
394static long *ptime;
395
396gettime() { *ptime = *(long *)0x462; }
397
398static double real_cputime() {
399 long thetime;
400 ptime = &thetime;
401 xbios(38, gettime);
402 return (((double)thetime) / (Getrez() == 2 ? 70 : 60));
403}
404
405#endif /* LATTICE */
406
407#ifdef M_WILLIAMS
408
409#include <osbind.h>
410#include <xbios.h>
411
412static long *ptime;
413
414static long readtime() { return (*((long *)0x4ba)); }
415
416static double real_cputime() {
417 long time;
418
419 time = Supexec(readtime);
420 return (time / 200.0);
421}
422
423#endif /* M_WILLIAMS */
424
425#ifdef LIGHT
426
427#undef FALSE
428#undef TRUE
429
430#include <FileMgr.h>
431
432#define TicksPerSec 60.0
433
434static double real_cputime() { return (((double)TickCount()) / TicksPerSec); }
435
436#endif /* LIGHT */
437
438#endif /* COMMENTED_OUT */
439
440#endif /* HAVE_GETRUSAGE */
441
442uint64_t Yap_StartOfWTimes;
443
444#if HAVE_GETHRTIME
445
446#if HAVE_TIME_H
447#include <time.h>
448#endif
449
450/* since the point YAP was started */
451
452void Yap_InitWTime(void) { Yap_StartOfWTimes = (uint64_t)gethrtime(); }
453
455uint64_t Yap_walltime(uint64_t old) {
456 hrtime_t tp = gethrtime();
457 /* return time in milliseconds */
458 return (uint64_t)tp;
459}
460
461#elif HAVE_GETTIMEOFDAY
462
463/* since the point YAP was started */
464/* store user time in this variable */
465void Yap_InitWTime(void) {
466 struct timeval tp;
467
468 gettimeofday(&tp, NULL);
469 Yap_StartOfWTimes =
470 (uint64_t)tp.tv_sec * 1000000000 + (uint64_t)tp.tv_usec * 1000;
471}
472
474uint64_t Yap_walltime(void) {
475 struct timeval tp;
476
477 gettimeofday(&tp, NULL);
478 return (uint64_t)tp.tv_sec * 1000000000 + (uint64_t)tp.tv_usec * 1000;
479}
480
481#elif defined(_WIN32)
482
483#include <sys/timeb.h>
484#include <time.h>
485
486/* since the point YAP was started */
487static LARGE_INTEGER Frequency;
488
489/* store user time in this variable */
490void Yap_InitWTime(void) {
491 LARGE_INTEGER ElapsedNanoseconds;
492 QueryPerformanceFrequency(&Frequency);
493 QueryPerformanceCounter(&ElapsedNanoseconds);
494 ElapsedNanoseconds.QuadPart *= 1000000;
495 ElapsedNanoseconds.QuadPart /= Frequency.QuadPart;
496 Yap_StartOfWTimes = (uint64_t)ElapsedNanoseconds.QuadPart;
497}
498
499uint64_t Yap_walltime(void) {
500 LARGE_INTEGER ElapsedNanoseconds;
501 QueryPerformanceCounter(&ElapsedNanoseconds);
502 //
503 // We now have the elapsed number of ticks, along with the
504 // number of ticks-per-second. We use these values
505 // to convert to the number of elapsed microseconds.
506 // To guard against loss-of-precision, we convert
507 // to microseconds *before* dividing by ticks-per-second.
508 //
509
510 ElapsedNanoseconds.QuadPart *= 1000000;
511 ElapsedNanoseconds.QuadPart /= Frequency.QuadPart;
512 return ElapsedNanoseconds.QuadPart;
513}
514
515#elif HAVE_TIMES
516
517/* store user time in this variable */
518void Yap_InitWTime(void) {
519 // start thread 0
520 REMOTE_LastWTime(0) = Yap_StartOfWTimes =
521 ((uint64_t)times(NULL)) * 10000000 / TicksPerSec;
522}
523
524uint64_t Yap_walltime(void) {
525 clock_t t;
526 t = times(NULL);
527 return = ((uint64_t)times(NULL)) * 10000000 / TicksPerSec;
528}
529
530#endif /* HAVE_TIMES */
531void Yap_ReInitWTime(void) { Yap_InitWTime(); }
532
533void Yap_InitTimePreds(void) {
534 /* can only do after heap is initialized */
535 Yap_InitWTime();
536}