]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9513 Change all lutil time structs to use nanoseconds
authorHoward Chu <hyc@openldap.org>
Tue, 23 Mar 2021 16:03:13 +0000 (16:03 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Wed, 31 Mar 2021 18:53:50 +0000 (18:53 +0000)
Instead of microseconds

configure.ac
contrib/slapd-modules/smbk5pwd/smbk5pwd.c
include/ac/time.h
include/ldap_pvt.h
include/lutil.h
libraries/libldap/util-int.c
libraries/liblutil/utils.c
servers/slapd/main.c
servers/slapd/overlays/ppolicy.c
tests/progs/slapd-watcher.c

index 458e0209ba93b7548140e2797f7ee7f03698ee1c..cb94e150cc1752a054d79dfc320d0eb5d72b60ae 100644 (file)
@@ -2371,6 +2371,7 @@ fi
 
 AC_CHECK_FUNCS(                        \
        bcopy                   \
+       clock_gettime   \
        closesocket             \
        chroot                  \
        endgrent                \
index de5745b59886510bf091992acc4ba1d151a5ea4d..7dc25621e08f96d8366ed7c2277fa953c1432293 100644 (file)
@@ -289,7 +289,7 @@ static int k5key_chk(
                        struct lutil_tm tm;
                        struct lutil_timet tt;
                        if ( lutil_parsetime( a->a_vals[0].bv_val, &tm ) == 0 &&
-                               lutil_tm2time( &tm, &tt ) == 0 && tt.tt_usec < op->o_time ) {
+                               lutil_tm2time( &tm, &tt ) == 0 && tt.tt_sec < op->o_time ) {
                                /* Account is expired */
                                rc = LUTIL_PASSWD_ERR;
                                break;
index fe618e126b4925d13ace4ebf35bcff1987048c62..05ffb0cadd6637abd0f2752c7c9a0e5985733e9d 100644 (file)
 # include <time.h>
 #endif
 
+#if defined(_WIN32) && !defined(HAVE_CLOCK_GETTIME)
+       struct timespec {
+               time_t  tv_sec;
+               int     tv_nsec;
+       };
+#endif
+
 #endif /* _AC_TIME_H */
index 3e8ad8e976b56bd08ab6da23a3c9ba086d80c164..8d32701a5efe2e7bead7994ec37f60c411c36197 100644 (file)
@@ -131,6 +131,13 @@ ldap_pvt_gettime LDAP_P(( struct lutil_tm * ));
 struct timeval;
 LDAP_F( int )
 ldap_pvt_gettimeofday LDAP_P(( struct timeval *tv, void *unused ));
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME 0
+#endif
+#define clock_gettime(clkid,tv)        ldap_pvt_clock_gettime(clkid,tv)
+struct timespec;
+LDAP_F( int )
+ldap_pvt_clock_gettime LDAP_P(( int clkid, struct timespec *tv ));
 #endif
 
 /* use this macro to allocate buffer for ldap_pvt_csnstr */
index 8d6406bd83ee577c5a393b76d8e2e9bf8cc233e9..cdbdbb21dd56118f48ee7b337e38add1f6132268 100644 (file)
@@ -172,7 +172,7 @@ typedef struct lutil_tm {
        int tm_mday;    /* day 1-31 */
        int tm_mon;     /* month 0-11 */
        int tm_year;    /* year - 1900 */
-       int tm_usec;    /* microseconds */
+       int tm_nsec;    /* nanoseconds */
        int tm_usub;    /* submicro */
 } lutil_tm;
 
@@ -180,7 +180,7 @@ typedef struct lutil_timet {
        unsigned int tt_sec;    /* seconds since epoch, 0000 or 1970 */
        int tt_gsec;            /* seconds since epoch, high 7 bits, maybe sign-flipped */
                                                /* sign flipped to sort properly as unsigned ints */
-       unsigned int tt_usec;   /* microseconds */
+       unsigned int tt_nsec;   /* nanoseconds */
 } lutil_timet;
 
 /* Parse a timestamp string into a structure */
index 7161a769484ae3228b94edcc2369316093c0f293..aa69f7091350ee52d7441b0320629555510fb2fe 100644 (file)
@@ -178,7 +178,7 @@ static int _ldap_pvt_gt_subs;
 
 #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;
@@ -187,9 +187,10 @@ static int _ldap_pvt_gt_offset;
 
 #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;
 
@@ -200,7 +201,7 @@ ldap_pvt_gettimeusec(int *sec)
         */
        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.
         *
@@ -214,7 +215,7 @@ ldap_pvt_gettimeusec(int *sec)
                ULARGE_INTEGER ut;
                FILETIME ft0, ft1;
                long long t;
-               int usec;
+               int nsec;
 
                /* Initialize our offset */
                QueryPerformanceFrequency( &_ldap_pvt_gt_freq );
@@ -232,13 +233,13 @@ ldap_pvt_gettimeusec(int *sec)
                /* 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 ) {
@@ -249,28 +250,28 @@ ldap_pvt_gettimeusec(int *sec)
        }
        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;
@@ -280,11 +281,11 @@ ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
        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;
@@ -294,7 +295,20 @@ ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
        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 )
@@ -305,10 +319,10 @@ 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;
@@ -318,7 +332,7 @@ ldap_pvt_gettime( struct lutil_tm *tm )
        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++;
@@ -357,23 +371,36 @@ ldap_pvt_gettime( struct lutil_tm *tm )
 }
 #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;
@@ -391,7 +418,7 @@ ldap_pvt_gettime( struct lutil_tm *ltm )
        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
 
@@ -406,7 +433,7 @@ ldap_pvt_csnstr(char *buf, size_t len, unsigned int replica, unsigned int mod)
        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;
index df9f7a2e914beca6b8f818ab0225e96e740e07fc..229fa7b502d7a631e9d886ae2844682a2eb21867 100644 (file)
@@ -159,7 +159,7 @@ int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )
                273, 304, 334 };
        int sec;
 
-       tt->tt_usec = tm->tm_usec;
+       tt->tt_nsec = tm->tm_nsec;
 
        /* special case 0000/01/01+00:00:00 is returned as zero */
        if ( tm->tm_year == -1900 && tm->tm_mon == 0 && tm->tm_mday == 1 &&
@@ -226,7 +226,7 @@ int lutil_tm2gtime( struct lutil_tm *tm, struct lutil_timet *tt )
        int sec, year;
        long tmp;
 
-       tt->tt_usec = tm->tm_usec;
+       tt->tt_nsec = tm->tm_nsec;
 
        /* tm->tm_year is years since 1900 */
        /* calculate days from 0000 */
@@ -350,13 +350,13 @@ int lutil_parsetime( char *atm, struct lutil_tm *tm )
                                i*=10; i+= *ptr++ - '0';
                                fracs++;
                        }
-                       tm->tm_usec = i;
+                       tm->tm_nsec = i;
                        if (i) {
-                               for (i = fracs; i<6; i++)
-                                       tm->tm_usec *= 10;
+                               for (i = fracs; i<9; i++)
+                                       tm->tm_nsec *= 10;
                        }
                } else {
-                       tm->tm_usec = 0;
+                       tm->tm_nsec = 0;
                }
                tm->tm_usub = 0;
 
index 98a67247d7eb05960f2a844702d3ace6c555ba3e..d8be4082b91f2672abec0a6627471fca9e188396 100644 (file)
@@ -382,12 +382,21 @@ static BER_logger *ber_logger;
 static void debug_print( const char *data )
 {
        char buf[4136]; /* 4096 + 40 */
+#ifdef HAVE_CLOCK_GETTIME
+       struct timespec tv;
+#define        TS      "%08x"
+#define        Tfrac   tv.tv_nsec
+       clock_gettime( CLOCK_REALTIME, &tv );
+#else
        struct timeval tv;
-
+#define        TS      "%05x"
+#define        Tfrac   tv.tv_usec
        gettimeofday( &tv, NULL );
+#endif
+
        buf[sizeof(buf)-1] = '\0';
-       snprintf( buf, sizeof(buf)-1, "%lx.%05x %p %s",
-               (long)tv.tv_sec, tv.tv_usec, (void *)ldap_pvt_thread_self(), data );
+       snprintf( buf, sizeof(buf)-1, "%lx." TS " %p %s",
+               (long)tv.tv_sec, Tfrac, (void *)ldap_pvt_thread_self(), data );
        ber_logger( buf );
 }
 
index 49863a7c6c0096dd1b8c045c66f835bed9e396ad..6f56752a59897e4c770839a17de80feb3b422761 100644 (file)
@@ -1500,7 +1500,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
        strcpy(nowstr_usec, nowstr);
        timestamp_usec.bv_val = nowstr_usec;
        timestamp_usec.bv_len = timestamp.bv_len;
-       snprintf( timestamp_usec.bv_val + timestamp_usec.bv_len-1, sizeof(".123456Z"), ".%06dZ", now_usec.tt_usec );
+       snprintf( timestamp_usec.bv_val + timestamp_usec.bv_len-1, sizeof(".123456Z"), ".%06dZ", now_usec.tt_nsec / 1000 );
        timestamp_usec.bv_len += STRLENOF(".123456");
 
        if ( rs->sr_err == LDAP_INVALID_CREDENTIALS && ppb->pp.pwdMaxRecordedFailure ) {
index 6dbb6e3be80e3daf74fe2573e2a7413cf6e8068d..3cfc0fe743c7a19960e6412da436f8d0cafc55b0 100644 (file)
@@ -425,7 +425,7 @@ void get_csns(
                if (j < numservers) {
                        ber_bvreplace( &c->vals[j], &bvs[i] );
                        lutil_parsetime(bvs[i].bv_val, &tm);
-                       c->tvs[j].tv_usec = tm.tm_usec;
+                       c->tvs[j].tv_usec = tm.tm_nsec / 1000;
                        lutil_tm2time( &tm, &tt );
                        c->tvs[j].tv_sec = tt.tt_sec;
                }