1 /* hires_timer: this implements a cross-platform, high temporal
2 resolution timer using POSIX standard C routines. Call
3 init_hires_timer to initialize and call hires_timer to get the time
4 in seconds since the call to init_hires_timer as a double (fortran
7 On platforms that support clock_gettime, nanosecond resolution will
8 be provided. On platforms that don't, gettimeofday will be used,
9 and microsecond resolution will be provided.
11 If init_hires_timer is never called, the time returned is seconds
12 since the system epoch, but with lower precision. On unix, the
13 epoch is midnight, the morning of January 1, 1970, in either UTC or
14 GMT depending on your particular flavor of unix. However, a
15 double-precision floating point number cannot represent the time in
16 seconds since that epoch to nanosecond resolution, so you'll end up
17 with something more like 10^-5 second resolution unless you call
25 #if defined(OLD_TIMERS)
26 /* User does not want to use the high-res timers. To
27 make sure they are not used, we don't even compile
28 them. We'll make sure the object file isn't empty
29 though, to avoid confusing ld: */
30 void hires_timer_dummy() {
35 static int initialized
=0; /* =1 if start and startnano are valid */
37 static time_t start_ipart
=0; /* integer part of starting time in seconds */
38 static double start_fpart
=0; /* fractional part */
40 /* DETERMINE IF CLOCK_GETTIME IS AVAILABLE */
43 #if defined(_POSIX_TIMERS)
44 #if ( _POSIX_TIMERS > 0 )
45 /* According to the POSIX standard, we only get here if the system
46 supports clock_gettime. */
51 void init_hires_timer() {
52 #if ( USE_HIRES == 1 )
54 if(!clock_gettime(CLOCK_REALTIME
,&when
)) {
55 start_ipart
=when
.tv_sec
;
56 start_fpart
=when
.tv_nsec
/1e9
;
57 } else { /* clock_gettime failed */
60 if(!gettimeofday(&tv
,NULL
)) {
61 start_ipart
=tv
.tv_sec
;
62 start_fpart
=tv
.tv_usec
/1e6
;
64 /* Should never get here; gettimeofday never fails
65 unless tv is outside of the address space. Just
66 as a paranoid fallback, we check for a failure
68 start_ipart
=time(NULL
);
71 #if ( USE_HIRES == 1 )
78 void hires_timer(double *d
) {
80 #if ( USE_HIRES == 1 )
83 if(!initialized
) init_hires_timer();
84 #if ( USE_HIRES == 1 )
85 if(!clock_gettime(CLOCK_REALTIME
,&when
)) {
86 *d
=(double)(when
.tv_sec
-start_ipart
) + ( ((double)when
.tv_nsec
)/1e9
- start_fpart
);
87 } else { /* clock_gettime failed */
89 if(!gettimeofday(&tv
,NULL
)) {
90 *d
=(double)(tv
.tv_sec
-start_ipart
) + ( ((double)tv
.tv_usec
)/1e6
- start_fpart
);
92 /* Should never get here; gettimeofday never fails
93 unless tv is outside of the address space. Just
94 as a paranoid fallback, we check for a failure
96 *d
=(double)(time(NULL
)-start_ipart
) - start_fpart
;
98 #if ( USE_HIRES == 1 )
103 /* Support all common fortran name mangling schemes: */
104 void hires_timer_(double *d
) { hires_timer(d
); }
105 void hires_timer__(double *d
) { hires_timer(d
); }
106 void HIRES_TIMER(double *d
) { hires_timer(d
); }
107 void HIRES_TIMER_(double *d
) { hires_timer(d
); }
108 void HIRES_TIMER__(double *d
) { hires_timer(d
); }
110 void init_hires_timer_() { init_hires_timer(); }
111 void init_hires_timer__() { init_hires_timer(); }
112 void INIT_HIRES_TIMER() { init_hires_timer(); }
113 void INIT_HIRES_TIMER_() { init_hires_timer(); }
114 void INIT_HIRES_TIMER__() { init_hires_timer(); }
116 #endif /* ELSE for the "if(OLD_TIMERS)" */