waf: pure cosmetic reformatting of the two samba-util object lists (to ease comparing).
[nivanova/samba-autobuild/.git] / lib / util / time.c
index a001e5f66e0682c8caa93b2c95c65085b2222db7..770ebc43745101a181d4a6464c309242f8dd6969 100644 (file)
  * @brief time handling functions
  */
 
-#ifndef TIME_T_MIN
-/* we use 0 here, because (time_t)-1 means error */
-#define TIME_T_MIN 0
-#endif
-
 #if (SIZEOF_LONG == 8)
 #define TIME_FIXUP_CONSTANT_INT 11644473600L
 #elif (SIZEOF_LONG_LONG == 8)
 
 
 
-/*
- * we use the INT32_MAX here as on 64 bit systems,
- * gmtime() fails with INT64_MAX
- */
-
-#ifndef TIME_T_MAX
-#define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t))
-#endif
-
 /**
  External access to time_t_min and time_t_max.
 **/
@@ -69,13 +55,51 @@ _PUBLIC_ void GetTimeOfDay(struct timeval *tval)
 #endif
 }
 
+/**
+a wrapper to preferably get the monotonic time
+**/
+_PUBLIC_ void clock_gettime_mono(struct timespec *tp)
+{
+       if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) != 0) {
+               clock_gettime(CLOCK_REALTIME,tp);
+       }
+}
+
+/**
+a wrapper to preferably get the monotonic time in seconds
+as this is only second resolution we can use the cached
+(and much faster) COARSE clock variant
+**/
+_PUBLIC_ time_t time_mono(time_t *t)
+{
+       struct timespec tp;
+       int rc = -1;
+#ifdef CLOCK_MONOTONIC_COARSE
+       rc = clock_gettime(CLOCK_MONOTONIC_COARSE,&tp);
+#endif
+       if (rc != 0) {
+               clock_gettime_mono(&tp);
+       }
+       if (t != NULL) {
+               *t = tp.tv_sec;
+       }
+       return tp.tv_sec;
+}
+
 
 #define TIME_FIXUP_CONSTANT 11644473600LL
 
 time_t convert_timespec_to_time_t(struct timespec ts)
 {
+       /* Ensure tv_nsec is less than 1sec. */
+       while (ts.tv_nsec > 1000000000) {
+               ts.tv_sec += 1;
+               ts.tv_nsec -= 1000000000;
+       }
+
        /* 1 ns == 1,000,000,000 - one thousand millionths of a second.
           increment if it's greater than 500 millionth of a second. */
+
        if (ts.tv_nsec > 500000000) {
                return ts.tv_sec + 1;
        }
@@ -360,11 +384,10 @@ _PUBLIC_ char *timestring(TALLOC_CTX *mem_ctx, time_t t)
        }
 
 #ifdef HAVE_STRFTIME
-       /* some versions of gcc complain about using %c. This is a bug
-          in the gcc warning, not a bug in this code. See a recent
-          strftime() manual page for details.
-        */
-       strftime(tempTime,sizeof(tempTime)-1,"%c %Z",tm);
+       /* Some versions of gcc complain about using some special format
+        * specifiers. This is a bug in gcc, not a bug in this code. See a
+        * recent strftime() manual page for details. */
+       strftime(tempTime,sizeof(tempTime)-1,"%a %b %e %X %Y %Z",tm);
        TimeBuf = talloc_strdup(mem_ctx, tempTime);
 #else
        TimeBuf = talloc_strdup(mem_ctx, asctime(tm));
@@ -413,6 +436,15 @@ _PUBLIC_ int64_t usec_time_diff(const struct timeval *tv1, const struct timeval
        return (sec_diff * 1000000) + (int64_t)(tv1->tv_usec - tv2->tv_usec);
 }
 
+/**
+  return (tp1 - tp2) in microseconds
+*/
+_PUBLIC_ int64_t nsec_time_diff(const struct timespec *tp1, const struct timespec *tp2)
+{
+       int64_t sec_diff = tp1->tv_sec - tp2->tv_sec;
+       return (sec_diff * 1000000000) + (int64_t)(tp1->tv_nsec - tp2->tv_nsec);
+}
+
 
 /**
   return a zero timeval
@@ -628,6 +660,9 @@ static int tm_diff(struct tm *a, struct tm *b)
        return seconds;
 }
 
+
+int extra_time_offset=0;
+
 /**
   return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
  */
@@ -641,7 +676,7 @@ _PUBLIC_ int get_time_zone(time_t t)
        tm = localtime(&t);
        if (!tm)
                return 0;
-       return tm_diff(&tm_utc,tm);
+       return tm_diff(&tm_utc,tm)+60*extra_time_offset;
 }
 
 struct timespec nt_time_to_unix_timespec(NTTIME *nt)