#ifdef _WIN32
/* Windows SYSTEMTIME only has 10 millisecond resolution, so we
- * also need to use a high resolution timer to get microseconds.
+ * also need to use a high resolution timer to get nanoseconds.
* This is pretty clunky.
*/
static LARGE_INTEGER _ldap_pvt_gt_freq;
#define SEC_TO_UNIX_EPOCH 11644473600LL
#define TICKS_PER_SECOND 10000000
+#define BILLION 1000000000L
static int
-ldap_pvt_gettimeusec(int *sec)
+ldap_pvt_gettimensec(int *sec)
{
LARGE_INTEGER count;
*/
LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
/* We assume Windows has at least a vague idea of
- * when a second begins. So we align our microsecond count
+ * when a second begins. So we align our nanosecond count
* with the Windows millisecond count using this offset.
* We retain the submillisecond portion of our own count.
*
ULARGE_INTEGER ut;
FILETIME ft0, ft1;
long long t;
- int usec;
+ int nsec;
/* Initialize our offset */
QueryPerformanceFrequency( &_ldap_pvt_gt_freq );
/* get second and fraction portion of counter */
t = c2.QuadPart % (_ldap_pvt_gt_freq.QuadPart*10);
- /* convert to microseconds */
- t *= 1000000;
- usec = t / _ldap_pvt_gt_freq.QuadPart;
+ /* convert to nanoseconds */
+ t *= BILLION;
+ nsec = t / _ldap_pvt_gt_freq.QuadPart;
ut.QuadPart /= 10;
- ut.QuadPart %= 10000000;
- _ldap_pvt_gt_offset = usec - ut.QuadPart;
+ ut.QuadPart %= (10 * BILLION);
+ _ldap_pvt_gt_offset = nsec - ut.QuadPart;
count = c2;
}
if ( count.QuadPart <= _ldap_pvt_gt_prev.QuadPart ) {
}
LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );
- /* convert to microseconds */
+ /* convert to nanoseconds */
count.QuadPart %= _ldap_pvt_gt_freq.QuadPart*10;
- count.QuadPart *= 1000000;
+ count.QuadPart *= BILLION;
count.QuadPart /= _ldap_pvt_gt_freq.QuadPart;
count.QuadPart -= _ldap_pvt_gt_offset;
- /* We've extracted the 1s and microseconds.
- * The 1sec digit is used to detect wraparound in microsecnds.
+ /* We've extracted the 1s and nanoseconds.
+ * The 1sec digit is used to detect wraparound in nanosecnds.
*/
if (count.QuadPart < 0)
- count.QuadPart += 10000000;
- else if (count.QuadPart >= 10000000)
- count.QuadPart -= 10000000;
+ count.QuadPart += (10 * BILLION);
+ else if (count.QuadPart >= (10 * BILLION))
+ count.QuadPart -= (10 * BILLION);
- *sec = count.QuadPart / 1000000;
- return count.QuadPart % 1000000;
+ *sec = count.QuadPart / BILLION;
+ return count.QuadPart % BILLION;
}
-/* emulate POSIX gettimeofday */
+/* emulate POSIX clock_gettime */
int
-ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
+ldap_pvt_clock_gettime( int clk_id, struct timespec *tv )
{
FILETIME ft;
ULARGE_INTEGER ut;
ut.LowPart = ft.dwLowDateTime;
ut.HighPart = ft.dwHighDateTime;
- /* convert to usec */
- ut.QuadPart /= (TICKS_PER_SECOND / 1000000);
+ /* convert to sec */
+ ut.QuadPart /= TICKS_PER_SECOND;
- tv->tv_usec = ldap_pvt_gettimeusec(&sec);
- tv->tv_sec = ut.QuadPart / 1000000 - SEC_TO_UNIX_EPOCH;
+ tv->tv_nsec = ldap_pvt_gettimensec(&sec);
+ tv->tv_sec = ut.QuadPart - SEC_TO_UNIX_EPOCH;
/* check for carry from microseconds */
sec0 = tv->tv_sec % 10;
return 0;
}
-/* return a broken out time, with microseconds
+/* emulate POSIX gettimeofday */
+int
+ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
+int
+{
+ struct timespec ts;
+ ldap_pvt_clock_gettime( 0, &ts );
+ tv->tv_sec = ts.tv_spec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ return 0;
+}
+
+
+/* return a broken out time, with nanoseconds
*/
void
ldap_pvt_gettime( struct lutil_tm *tm )
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
GetSystemTime( &st );
- tm->tm_usec = ldap_pvt_gettimeusec(&sec);
+ tm->tm_nsec = ldap_pvt_gettimensec(&sec);
tm->tm_usub = _ldap_pvt_gt_subs;
- /* any difference larger than microseconds is
+ /* any difference larger than nanoseconds is
* already reflected in st
*/
tm->tm_sec = st.wSecond;
tm->tm_mon = st.wMonth - 1;
tm->tm_year = st.wYear - 1900;
- /* check for carry from microseconds */
+ /* check for carry from nanoseconds */
sec0 = tm->tm_sec % 10;
if (sec0 < sec || (sec0 == 9 && !sec)) {
tm->tm_sec++;
}
#else
+#ifdef HAVE_CLOCK_GETTIME
+static struct timespec _ldap_pvt_gt_prevTv;
+#else
static struct timeval _ldap_pvt_gt_prevTv;
+#endif
void
ldap_pvt_gettime( struct lutil_tm *ltm )
{
- struct timeval tv;
-
struct tm tm;
time_t t;
+#ifdef HAVE_CLOCK_GETTIME
+#define FRAC tv_nsec
+#define NSECS(x) x
+ struct timespec tv;
+
+ clock_gettime( CLOCK_REALTIME, &tv );
+#else
+#define FRAC tv_usec
+#define NSECS(x) x * 1000
+ struct timeval tv;
gettimeofday( &tv, NULL );
+#endif
t = tv.tv_sec;
LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
if ( tv.tv_sec < _ldap_pvt_gt_prevTv.tv_sec
|| ( tv.tv_sec == _ldap_pvt_gt_prevTv.tv_sec
- && tv.tv_usec <= _ldap_pvt_gt_prevTv.tv_usec )) {
+ && tv.FRAC <= _ldap_pvt_gt_prevTv.FRAC )) {
_ldap_pvt_gt_subs++;
} else {
_ldap_pvt_gt_subs = 0;
ltm->tm_mday = tm.tm_mday;
ltm->tm_mon = tm.tm_mon;
ltm->tm_year = tm.tm_year;
- ltm->tm_usec = tv.tv_usec;
+ ltm->tm_nsec = NSECS(tv.FRAC);
}
#endif
n = snprintf( buf, len,
"%4d%02d%02d%02d%02d%02d.%06dZ#%06x#%03x#%06x",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
- tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_usub, replica, mod );
+ tm.tm_min, tm.tm_sec, tm.tm_nsec / 1000, tm.tm_usub, replica, mod );
if( n < 0 ) return 0;
return ( (size_t) n < len ) ? n : 0;