瀏覽代碼

types: add a monotonic cpu timer to measure delays

Julius Pfrommer 9 年之前
父節點
當前提交
fcc415202e
共有 4 個文件被更改,包括 34 次插入18 次删除
  1. 5 1
      include/ua_types.h
  2. 2 2
      src/server/ua_server_worker.c
  3. 22 14
      src/ua_types.c
  4. 5 1
      src/ua_util.h

+ 5 - 1
include/ua_types.h

@@ -119,7 +119,11 @@ UA_Boolean UA_EXPORT UA_String_equal(const UA_String *s1, const UA_String *s2);
    number of 100 nanosecond intervals since January 1, 1601 (UTC) */
 typedef UA_Int64 UA_DateTime;
 
-UA_DateTime UA_EXPORT UA_DateTime_now(void); ///> The current time
+/* The current time */
+UA_DateTime UA_EXPORT UA_DateTime_now(void);
+
+/* CPU clock invariant to system time changes. Use only for time diffs, not current time */
+UA_DateTime UA_EXPORT UA_DateTime_nowMonotonic(void);
 
 typedef struct UA_DateTimeStruct {
     UA_UInt16 nanoSec;

+ 2 - 2
src/server/ua_server_worker.c

@@ -229,7 +229,7 @@ static UA_StatusCode addRepeatedJob(UA_Server *server, struct AddRepeatedJob * U
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
 
     /* search for matching entry */
-    UA_DateTime firstTime = UA_DateTime_now() + arw->interval;
+    UA_DateTime firstTime = UA_DateTime_nowMonotonic() + arw->interval;
     tempTw = LIST_FIRST(&server->repeatedJobs);
     while(tempTw) {
         if(arw->interval == tempTw->interval) {
@@ -321,7 +321,7 @@ UA_StatusCode UA_Server_addRepeatedJob(UA_Server *server, UA_Job job, UA_UInt32
 
 /* Returns the timeout until the next repeated job in ms */
 static UA_UInt16 processRepeatedJobs(UA_Server *server) {
-    UA_DateTime current = UA_DateTime_now();
+    UA_DateTime current = UA_DateTime_nowMonotonic();
     struct RepeatedJobs *tw = NULL;
 
     while((tw = LIST_FIRST(&server->repeatedJobs)) != NULL) {

+ 22 - 14
src/ua_types.c

@@ -55,39 +55,47 @@ UA_Boolean UA_String_equal(const UA_String *string1, const UA_String *string2) {
 /* DateTime */
 #define UNIX_EPOCH_BIAS_SEC 11644473600LL // Number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
 #define HUNDRED_NANOSEC_PER_USEC 10LL
-#define HUNDRED_NANOSEC_PER_SEC (HUNDRED_NANOSEC_PER_USEC * 1000000LL)
+#define HUNDRED_NANOSEC_PER_MSEC (HUNDRED_NANOSEC_PER_USEC * 1000LL)
+#define HUNDRED_NANOSEC_PER_SEC (HUNDRED_NANOSEC_PER_MSEC * 1000LL)
 
-#if defined(__MINGW32__) && !defined(_TIMEZONE_DEFINED)
-# define _TIMEZONE_DEFINED
+#ifdef _WIN32
+# if defined(__MINGW32__) && !defined(_TIMEZONE_DEFINED)
+#  define _TIMEZONE_DEFINED
 struct timezone {
   int tz_minuteswest;
   int tz_dsttime;
 };
-#endif
-
-#ifdef _WIN32
+# endif
 static const UA_UInt64 epoch = 116444736000000000;
-int gettimeofday(struct timeval *tp, struct timezone *tzp);
 int gettimeofday(struct timeval *tp, struct timezone *tzp) {
-    FILETIME       ft;
-    SYSTEMTIME     st;
+    FILETIME ft;
+    SYSTEMTIME st;
     ULARGE_INTEGER ul;
     GetSystemTime(&st);
     SystemTimeToFileTime(&st, &ft);
-    ul.LowPart  = ft.dwLowDateTime;
+    ul.LowPart = ft.dwLowDateTime;
     ul.HighPart = ft.dwHighDateTime;
-    tp->tv_sec  = (long)((ul.QuadPart - epoch) / 10000000L);
+    tp->tv_sec = (long)((ul.QuadPart - epoch) / 10000000L);
     tp->tv_usec = st.wMilliseconds * 1000;
     return 0;
 }
 #endif
 
 UA_DateTime UA_DateTime_now(void) {
-    UA_DateTime dateTime;
     struct timeval tv;
     gettimeofday(&tv, NULL);
-    dateTime = (tv.tv_sec + UNIX_EPOCH_BIAS_SEC) * HUNDRED_NANOSEC_PER_SEC + tv.tv_usec * HUNDRED_NANOSEC_PER_USEC;
-    return dateTime;
+    return ((tv.tv_sec + UNIX_EPOCH_BIAS_SEC) * HUNDRED_NANOSEC_PER_SEC) +
+           (tv.tv_usec * HUNDRED_NANOSEC_PER_USEC);
+}
+
+UA_DateTime UA_DateTime_nowMonotonic(void) {
+#ifdef _WIN32
+    return GetTickCount64() * HUNDRED_NANOSEC_PER_MSEC;
+#else
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+    return (ts.tv_sec * HUNDRED_NANOSEC_PER_SEC) + (ts.tv_nsec / 100);
+#endif
 }
 
 UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime atime) {

+ 5 - 1
src/ua_util.h

@@ -64,11 +64,15 @@
 /* System Libraries */
 /********************/
 
-#include <time.h>
 #ifdef _WIN32
 # include <winsock2.h> //needed for amalgation
 # include <windows.h>
 # undef SLIST_ENTRY
+#endif
+
+#include <time.h>
+#ifdef _WIN32
+int gettimeofday(struct timeval *tp, struct timezone *tzp);
 #else
 # include <sys/time.h>
 #endif