summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/sysinfo
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c1
-rw-r--r--winpr/libwinpr/sysinfo/sysinfo.c150
2 files changed, 107 insertions, 44 deletions
diff --git a/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c b/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c
index d43b588..854c93a 100644
--- a/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c
+++ b/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c
@@ -73,6 +73,7 @@
#include <sys/system_properties.h>
#include <unistd.h>
#include <winpr/wtypes.h>
+#include <winpr/debug.h>
static pthread_once_t g_once;
static int g_inited;
diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c
index f12f4eb..bf81b8b 100644
--- a/winpr/libwinpr/sysinfo/sysinfo.c
+++ b/winpr/libwinpr/sysinfo/sysinfo.c
@@ -33,9 +33,43 @@
#include <fcntl.h>
#endif
+#if !defined(_WIN32)
+#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
+#include <time.h>
+#elif !defined(__APPLE__)
+#include <sys/time.h>
+#include <sys/sysinfo.h>
+#endif
+#endif
+
#include "../log.h"
#define TAG WINPR_TAG("sysinfo")
+#define FILETIME_TO_UNIX_OFFSET_S 11644473600UL
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#include <mach/mach_time.h>
+
+static UINT64 scaleHighPrecision(UINT64 i, UINT32 numer, UINT32 denom)
+{
+ UINT64 high = (i >> 32) * numer;
+ UINT64 low = (i & 0xffffffffull) * numer / denom;
+ UINT64 highRem = ((high % denom) << 32) / denom;
+ high /= denom;
+ return (high << 32) + highRem + low;
+}
+
+static UINT64 mac_get_time_ns(void)
+{
+ mach_timebase_info_data_t timebase = { 0 };
+ mach_timebase_info(&timebase);
+ UINT64 t = mach_absolute_time();
+ return scaleHighPrecision(t, timebase.numer, timebase.denom);
+}
+
+#endif
+
/**
* api-ms-win-core-sysinfo-l1-1-1.dll:
*
@@ -272,13 +306,14 @@ BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime)
VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
- ULARGE_INTEGER time64;
- time64.u.HighPart = 0;
- /* time represented in tenths of microseconds since midnight of January 1, 1601 */
- time64.QuadPart = time(NULL) + 11644473600LL; /* Seconds since January 1, 1601 */
- time64.QuadPart *= 10000000; /* Convert timestamp to tenths of a microsecond */
- lpSystemTimeAsFileTime->dwLowDateTime = time64.u.LowPart;
- lpSystemTimeAsFileTime->dwHighDateTime = time64.u.HighPart;
+ union
+ {
+ UINT64 u64;
+ FILETIME ft;
+ } t;
+
+ t.u64 = (winpr_GetUnixTimeNS() / 100ull) + FILETIME_TO_UNIX_OFFSET_S * 10000000ull;
+ *lpSystemTimeAsFileTime = t.ft;
}
BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement,
@@ -294,25 +329,7 @@ BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement,
DWORD GetTickCount(void)
{
- DWORD ticks = 0;
-#ifdef __linux__
- struct timespec ts;
-
- if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts))
- ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
-
-#else
- /**
- * FIXME: this is relative to the Epoch time, and we
- * need to return a value relative to the system uptime.
- */
- struct timeval tv;
-
- if (!gettimeofday(&tv, NULL))
- ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
-#endif
- return ticks;
+ return GetTickCount64();
}
#endif // _WIN32
@@ -553,35 +570,80 @@ DWORD GetTickCount(void)
ULONGLONG winpr_GetTickCount64(void)
{
- ULONGLONG ticks = 0;
-#if defined(__linux__)
- struct timespec ts;
+ const UINT64 ns = winpr_GetTickCount64NS();
+ return WINPR_TIME_NS_TO_MS(ns);
+}
- if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts))
- ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
+#endif
+UINT64 winpr_GetTickCount64NS(void)
+{
+ UINT64 ticks = 0;
+#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
+ struct timespec ts = { 0 };
+
+ if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) == 0)
+ ticks = (ts.tv_sec * 1000000000ull) + ts.tv_nsec;
+#elif defined(__MACH__) && defined(__APPLE__)
+ ticks = mac_get_time_ns();
#elif defined(_WIN32)
- FILETIME ft;
- ULARGE_INTEGER ul;
- GetSystemTimeAsFileTime(&ft);
- ul.LowPart = ft.dwLowDateTime;
- ul.HighPart = ft.dwHighDateTime;
- ticks = ul.QuadPart;
+ LARGE_INTEGER li = { 0 };
+ LARGE_INTEGER freq = { 0 };
+ if (QueryPerformanceFrequency(&freq) && QueryPerformanceCounter(&li))
+ ticks = li.QuadPart * 1000000000ull / freq.QuadPart;
#else
- /**
- * FIXME: this is relative to the Epoch time, and we
- * need to return a value relative to the system uptime.
- */
- struct timeval tv;
+ struct timeval tv = { 0 };
- if (!gettimeofday(&tv, NULL))
- ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ if (gettimeofday(&tv, NULL) == 0)
+ ticks = (tv.tv_sec * 1000000000ull) + (tv.tv_usec * 1000ull);
+
+ /* We need to trick here:
+ * this function should return the system uptime, but we need higher resolution.
+ * so on first call get the actual timestamp along with the system uptime.
+ *
+ * return the uptime measured from now on (e.g. current measure - first measure + uptime at
+ * first measure)
+ */
+ static UINT64 first = 0;
+ static UINT64 uptime = 0;
+ if (first == 0)
+ {
+ struct sysinfo info = { 0 };
+ if (sysinfo(&info) == 0)
+ {
+ first = ticks;
+ uptime = 1000000000ull * info.uptime;
+ }
+ }
+ ticks = ticks - first + uptime;
#endif
return ticks;
}
+UINT64 winpr_GetUnixTimeNS(void)
+{
+#if defined(_WIN32)
+
+ union
+ {
+ UINT64 u64;
+ FILETIME ft;
+ } t = { 0 };
+ GetSystemTimeAsFileTime(&t.ft);
+ return (t.u64 - FILETIME_TO_UNIX_OFFSET_S * 10000000ull) * 100ull;
+#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
+ struct timespec ts = { 0 };
+ if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
+ return 0;
+ return ts.tv_sec * 1000000000ull + ts.tv_nsec;
+#else
+ struct timeval tv = { 0 };
+ if (gettimeofday(&tv, NULL) != 0)
+ return 0;
+ return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ull;
#endif
+}
/* If x86 */
#ifdef _M_IX86_AMD64