]> git.sur5r.net Git - openldap/blobdiff - libraries/liblutil/utils.c
ITS#5129 fix alock_close with Quick mode
[openldap] / libraries / liblutil / utils.c
index ee69a1baf06b5409d144dd258d5ce3eeebd49d30..2cd105ed92cf6dd4ddbb4f1c6ea1a7713b24a0dc 100644 (file)
@@ -272,7 +272,9 @@ int lutil_parsetime( char *atm, struct lutil_tm *tm )
        return -1;
 }
 
-/* return a broken out time, with microseconds */
+/* return a broken out time, with microseconds
+ * Must be mutex-protected.
+ */
 #ifdef _WIN32
 /* Windows SYSTEMTIME only has 10 millisecond resolution, so we
  * also need to use a high resolution timer to get microseconds.
@@ -282,6 +284,8 @@ void
 lutil_gettime( struct lutil_tm *tm )
 {
        static LARGE_INTEGER cFreq;
+       static LARGE_INTEGER prevCount;
+       static int subs;
        static int offset;
        LARGE_INTEGER count;
        SYSTEMTIME st;
@@ -306,13 +310,24 @@ lutil_gettime( struct lutil_tm *tm )
                offset = ( usec - st.wMilliseconds ) * 1000;
        }
 
+       /* It shouldn't ever go backwards, but multiple CPUs might
+        * be able to hit in the same tick.
+        */
+       if ( count.QuadPart <= prevCount.QuadPart ) {
+               subs++;
+       } else {
+               subs = 0;
+               prevCount = count;
+       }
+
+       tm->tm_usub = subs;
+
        /* convert to microseconds */
        count.QuadPart *= 1000000;
        count.QuadPart /= cFreq.QuadPart;
        count.QuadPart -= offset;
 
        tm->tm_usec = count.QuadPart % 1000000;
-       printf("tm_usec %d, msec %d\n", tm->tm_usec, st.wMilliseconds);
 
        /* any difference larger than microseconds is
         * already reflected in st
@@ -330,6 +345,9 @@ void
 lutil_gettime( struct lutil_tm *ltm )
 {
        struct timeval tv;
+       static struct timeval prevTv;
+       static int subs;
+
 #ifdef HAVE_GMTIME_R
        struct tm tm_buf;
 #endif
@@ -339,6 +357,16 @@ lutil_gettime( struct lutil_tm *ltm )
        gettimeofday( &tv, NULL );
        t = tv.tv_sec;
 
+       if ( tv.tv_sec < prevTv.tv_sec
+               || ( tv.tv_sec == prevTv.tv_sec && tv.tv_usec == prevTv.tv_usec )) {
+               subs++;
+       } else {
+               subs = 0;
+               prevTv = tv;
+       }
+
+       ltm->tm_usub = subs;
+
 #ifdef HAVE_GMTIME_R
        tm = gmtime_r( &t, &tm_buf );
 #else