#include <time.h> /* clock_gettime(), clock_nanosleep() */
#include <stdlib.h> /* lldiv() */
#include <assert.h>
+#include <errno.h>
#if defined( PTH_INIT_IN_PTH_H ) /* GNU Pth */
static unsigned prec = 0;
static volatile mtime_t cached_time = 0;
+#if defined( HAVE_CLOCK_NANOSLEEP )
+# if (_POSIX_MONOTONIC_CLOCK - 0 < 0)
+# define CLOCK_MONOTONIC CLOCK_REALTIME
+# endif
+#endif
/**
* Return high precision date
#if defined (HAVE_CLOCK_NANOSLEEP)
struct timespec ts;
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
/* Try to use POSIX monotonic clock if available */
- if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
-# endif
+ if( clock_gettime( CLOCK_MONOTONIC, &ts ) == EINVAL )
/* Run-time fallback to real-time clock (always available) */
(void)clock_gettime( CLOCK_REALTIME, &ts );
{
/* Counter wrapped */
i_wrap_counts++;
- usec_time += I64C(0x100000000) * 1000;
+ res += I64C(0x100000000) * 1000;
}
- i_previous_time = usec_time;
+ i_previous_time = res;
LeaveCriticalSection( &date_lock );
}
#else
lldiv_t d = lldiv( date, 1000000 );
struct timespec ts = { d.quot, d.rem * 1000 };
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
- if( clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL ) )
-# endif
- clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL );
+ int val;
+ while( ( val = clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts,
+ NULL ) ) == EINTR );
+ if( val == EINVAL )
+ {
+ ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
+ while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL ) == EINTR );
+ }
#else
mtime_t delay = date - mdate();
lldiv_t d = lldiv( delay, 1000000 );
struct timespec ts = { d.quot, d.rem * 1000 };
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
- if( clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, NULL ) )
-# endif
- clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL );
+ int val;
+ while( ( val = clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, &ts ) ) == EINTR );
+ if( val == EINVAL )
+ {
+ ts.tv_sec = d.quot; ts.tv_nsec = d.rem * 1000;
+ while( clock_nanosleep( CLOCK_REALTIME, 0, &ts, &ts ) == EINTR );
+ }
#elif defined( HAVE_KERNEL_OS_H )
snooze( delay );
ts_delay.tv_sec = delay / 1000000;
ts_delay.tv_nsec = (delay % 1000000) * 1000;
- nanosleep( &ts_delay, NULL );
+ while( nanosleep( &ts_delay, &ts_delay ) && ( errno == EINTR ) );
#else
struct timeval tv_delay;
tv_delay.tv_sec = delay / 1000000;
tv_delay.tv_usec = delay % 1000000;
- /* select() return value should be tested, since several possible errors
- * can occur. However, they should only happen in very particular occasions
- * (i.e. when a signal is sent to the thread, or when memory is full), and
- * can be ignored. */
+ /* If a signal is caught, you are screwed. Update your OS to nanosleep()
+ * or clock_nanosleep() if this is an issue. */
select( 0, NULL, NULL, NULL, &tv_delay );
#endif
return p_date->date;
}
+#ifndef HAVE_GETTIMEOFDAY
+
#ifdef WIN32
+
/*
* Number of micro-seconds between the beginning of the Windows epoch
* (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
tv->tv_usec = (long) (tim % 1000000L);
return (0);
}
-#endif
+#endif
+#endif
/**
* @return NTP 64-bits timestamp in host byte order.