Use monotonic clock source for Windows in oic_time
authorDavid Antler <david.a.antler@intel.com>
Tue, 21 Jun 2016 22:29:43 +0000 (15:29 -0700)
committerJon A. Cruz <jon@joncruz.org>
Thu, 21 Jul 2016 19:44:48 +0000 (19:44 +0000)
Amend documentation of OICGetCurrentTime() function.

We must replace our GetSystemTimeAsFileTime API call because system
time updates should not impact our calculations. We should assume that
system time can change during the runtime of our programs.

Change-Id: I49246a243435f8b0b2bf7a77fcb31378dc921daf
Signed-off-by: David Antler <david.a.antler@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9333
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jon@joncruz.org>
resource/c_common/SConscript
resource/c_common/oic_time/include/oic_time.h
resource/c_common/oic_time/src/oic_time.c

index 2b46f5c..f412655 100644 (file)
@@ -44,14 +44,16 @@ else:
 if target_os in ['tizen', 'linux']:
        env.ParseConfig("pkg-config --cflags --libs uuid")
 
-env.PrependUnique(LIBS = ['c_common'])
-
 common_env = env.Clone()
 common_env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource')])
 
 ######################################################################
 # Build flags
 ######################################################################
+common_conf = Configure(common_env)
+if common_conf.CheckFunc('QueryPerformanceFrequency'):
+       common_env.AppendUnique(CPPDEFINES = ['HAVE_QUERYPERFORMANCEFREQUENCY'])
+common_env = common_conf.Finish()
 
 ######################################################################
 # Source files and Targets
@@ -67,3 +69,5 @@ commonlib = common_env.StaticLibrary('c_common', common_src)
 common_env.InstallTarget(commonlib, 'c_common')
 common_env.UserInstallTargetLib(commonlib, 'c_common')
 common_env.UserInstallTargetHeader('platform_features.h', 'resource', 'platform_features.h')
+
+env.PrependUnique(LIBS = ['c_common'])
index 0deba60..6ca9e3e 100644 (file)
@@ -53,6 +53,8 @@ typedef enum
  * @param     precision   based on this parameter, current time is returned in milliseconds or
  *                        microseconds
  *
+ * @warning   This function may be sensitive to system time changes on some platforms.
+ *
  * @note
  *            On Arduino platform:
  *            if the time precision is in milliseconds then the function will overflow
index 0cf2388..0b094f5 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <stddef.h>        // For NULL
 
-#if defined(_WIN32)
+#if defined(HAVE_WINDOWS_H)
 # include <windows.h>
 #elif !defined(WITH_ARDUINO)
 # if _POSIX_TIMERS > 0
@@ -52,21 +52,21 @@ uint64_t OICGetCurrentTime(OICTimePrecision precision)
 
 #ifdef WITH_ARDUINO
     currentTime = (TIME_IN_MS == precision) ? millis() : micros();
-#elif defined(_WIN32)
-    FILETIME fileTime;
+#elif defined(HAVE_QUERYPERFORMANCEFREQUENCY)
+    static LARGE_INTEGER frequency = {0};
 
-    GetSystemTimePreciseAsFileTime(&fileTime);
-
-    // fileTime should now be a QWORD hundred-nanoseconds time since 1601
+    if (!frequency.QuadPart)
+    {
+        QueryPerformanceFrequency(&frequency);
+    }
 
-    // MSDN recommends using ULARGE_INTEGER as an intermediate representation for math.
-    ULARGE_INTEGER time = { .LowPart  = fileTime.dwLowDateTime,
-                            .HighPart = fileTime.dwHighDateTime };
+    LARGE_INTEGER count = {0};
+    QueryPerformanceCounter(&count);
 
     currentTime =
     (TIME_IN_MS == precision)
-        ? time.QuadPart / (HNS_PER_US * US_PER_MS)
-        : time.QuadPart / (HNS_PER_US);
+        ? count.QuadPart / (frequency.QuadPart / MS_PER_SEC)
+        : count.QuadPart / (frequency.QuadPart / US_PER_SEC);
 #else
 # if _POSIX_TIMERS > 0
 #   if defined(CLOCK_MONOTONIC_COARSE)