[winpr,sysinfo] unify time function use
* Add new function winpr_GetTickCount64NS for high resolution tick count with (up to) nanosecond resolution * Add new function winpr_GetUnixTimeNS for high resolution system time as nanoseconds since 1.1.1970 * Replace use of clock_gettime and gettimeofday in whole project with these new functions * Add new macros WINPR_TIME_NS_TO_* and WINPR_TIME_NS_REM_* to convert the nano second count to less resolution or get the remainder in the desired resolution
This commit is contained in:
parent
b5713c46a7
commit
4732f379d4
@ -29,6 +29,7 @@
|
||||
|
||||
#include <time.h>
|
||||
#include <winpr/string.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/param.h>
|
||||
@ -69,28 +70,24 @@
|
||||
#define PROFILER_STOP
|
||||
#endif // GOOGLE_PROFILER
|
||||
|
||||
extern float _delta_time(const struct timespec* t0, const struct timespec* t1);
|
||||
extern void _floatprint(float t, char* output);
|
||||
extern float measure_delta_time(UINT64 t0, UINT64 t1);
|
||||
extern void measure_floatprint(float t, char* output);
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW 4
|
||||
#endif // !CLOCK_MONOTONIC_RAW
|
||||
|
||||
#define MEASURE_LOOP_START(_prefix_, _count_) \
|
||||
{ \
|
||||
struct timespec _start, _stop; \
|
||||
char* _prefix; \
|
||||
int _count = (_count_); \
|
||||
int _loop; \
|
||||
float _delta; \
|
||||
char _str1[32], _str2[32]; \
|
||||
_prefix = _strdup(_prefix_); \
|
||||
_str1[0] = '\0'; \
|
||||
_str2[0] = '\0'; \
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &_start); \
|
||||
PROFILER_START(_prefix); \
|
||||
_loop = (_count); \
|
||||
do \
|
||||
#define MEASURE_LOOP_START(_prefix_, _count_) \
|
||||
{ \
|
||||
UINT64 _start, _stop; \
|
||||
char* _prefix; \
|
||||
int _count = (_count_); \
|
||||
int _loop; \
|
||||
float _delta; \
|
||||
char _str1[32], _str2[32]; \
|
||||
_prefix = _strdup(_prefix_); \
|
||||
_str1[0] = '\0'; \
|
||||
_str2[0] = '\0'; \
|
||||
_start = winpr_GetTickCount64NS(); \
|
||||
PROFILER_START(_prefix); \
|
||||
_loop = (_count); \
|
||||
do \
|
||||
{
|
||||
|
||||
#define MEASURE_LOOP_STOP \
|
||||
@ -100,28 +97,28 @@ extern void _floatprint(float t, char* output);
|
||||
|
||||
#define MEASURE_GET_RESULTS(_result_) \
|
||||
PROFILER_STOP; \
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \
|
||||
_delta = _delta_time(&_start, &_stop); \
|
||||
_stop = winpr_GetTickCount64NS(); \
|
||||
_delta = measure_delta_time(_start, _stop); \
|
||||
(_result_) = (float)_count / _delta; \
|
||||
free(_prefix); \
|
||||
}
|
||||
|
||||
#define MEASURE_SHOW_RESULTS(_result_) \
|
||||
PROFILER_STOP; \
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \
|
||||
_delta = _delta_time(&_start, &_stop); \
|
||||
_stop = winpr_GetTickCount64NS(); \
|
||||
_delta = measure_delta_time(_start, _stop); \
|
||||
(_result_) = (float)_count / _delta; \
|
||||
_floatprint((float)_count / _delta, _str1); \
|
||||
measure_floatprint((float)_count / _delta, _str1); \
|
||||
printf("%s: %9d iterations in %5.1f seconds = %s/s \n", _prefix, _count, _delta, _str1); \
|
||||
free(_prefix); \
|
||||
}
|
||||
|
||||
#define MEASURE_SHOW_RESULTS_SCALED(_scale_, _label_) \
|
||||
PROFILER_STOP; \
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &_stop); \
|
||||
_delta = _delta_time(&_start, &_stop); \
|
||||
_floatprint((float)_count / _delta, _str1); \
|
||||
_floatprint((float)_count / _delta * (_scale_), _str2); \
|
||||
_stop = winpr_GetTickCount64NS(); \
|
||||
_delta = measure_delta_time(_start, _stop); \
|
||||
measure_floatprint((float)_count / _delta, _str1); \
|
||||
measure_floatprint((float)_count / _delta * (_scale_), _str2); \
|
||||
printf("%s: %9d iterations in %5.1f seconds = %s/s = %s%s \n", _prefix, _count, _delta, _str1, \
|
||||
_str2, _label_); \
|
||||
free(_prefix); \
|
||||
|
@ -36,31 +36,15 @@ int test_sizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef _WIN32
|
||||
float _delta_time(const struct timespec* t0, const struct timespec* t1)
|
||||
float measure_delta_time(UINT64 t0, UINT64 t1)
|
||||
{
|
||||
return 0.0f;
|
||||
INT64 diff = (INT64)(t1 - t0);
|
||||
double retval = diff / 1000000000.0;
|
||||
return (retval < 0.0) ? 0.0f : (float)retval;
|
||||
}
|
||||
#else
|
||||
float _delta_time(const struct timespec* t0, const struct timespec* t1)
|
||||
{
|
||||
INT64 secs = (INT64)(t1->tv_sec) - (INT64)(t0->tv_sec);
|
||||
long nsecs = t1->tv_nsec - t0->tv_nsec;
|
||||
double retval = NAN;
|
||||
|
||||
if (nsecs < 0)
|
||||
{
|
||||
--secs;
|
||||
nsecs += 1000000000;
|
||||
}
|
||||
|
||||
retval = (double)secs + (double)nsecs / (double)1000000000.0;
|
||||
return (retval < 0.0) ? 0.0 : (float)retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void _floatprint(float t, char* output)
|
||||
void measure_floatprint(float t, char* output)
|
||||
{
|
||||
/* I don't want to link against -lm, so avoid log,exp,... */
|
||||
float f = 10.0;
|
||||
|
@ -27,27 +27,11 @@
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#define TAG FREERDP_TAG("utils")
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
int gettimeofday(struct timeval* tp, void* tz)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
tp->tv_sec = (long)timebuffer.time;
|
||||
tp->tv_usec = timebuffer.millitm * 1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/pcap.h>
|
||||
|
||||
@ -131,14 +115,11 @@ static BOOL pcap_write_record(rdpPcap* pcap, const pcap_record* record)
|
||||
|
||||
BOOL pcap_add_record(rdpPcap* pcap, const void* data, size_t length)
|
||||
{
|
||||
pcap_record* record = NULL;
|
||||
struct timeval tp;
|
||||
|
||||
WINPR_ASSERT(pcap);
|
||||
WINPR_ASSERT(data || (length == 0));
|
||||
WINPR_ASSERT(length <= UINT32_MAX);
|
||||
|
||||
record = (pcap_record*)calloc(1, sizeof(pcap_record));
|
||||
pcap_record* record = (pcap_record*)calloc(1, sizeof(pcap_record));
|
||||
if (!record)
|
||||
return FALSE;
|
||||
|
||||
@ -147,9 +128,10 @@ BOOL pcap_add_record(rdpPcap* pcap, const void* data, size_t length)
|
||||
record->header.incl_len = (UINT32)length;
|
||||
record->header.orig_len = (UINT32)length;
|
||||
|
||||
gettimeofday(&tp, 0);
|
||||
record->header.ts_sec = (UINT32)tp.tv_sec;
|
||||
record->header.ts_usec = (UINT32)tp.tv_usec;
|
||||
const UINT64 ns = winpr_GetUnixTimeNS();
|
||||
|
||||
record->header.ts_sec = WINPR_TIME_NS_TO_S(ns);
|
||||
record->header.ts_usec = WINPR_TIME_NS_REM_US(ns);
|
||||
|
||||
if (pcap->tail == NULL)
|
||||
{
|
||||
|
@ -22,38 +22,18 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <freerdp/utils/stopwatch.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER stopwatch_freq = { 0 };
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
static void stopwatch_set_time(UINT64* usecs)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER perfcount;
|
||||
QueryPerformanceCounter(&perfcount);
|
||||
*usecs = (perfcount.QuadPart * 1000000) / stopwatch_freq.QuadPart;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
*usecs = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
#endif
|
||||
const UINT64 ns = winpr_GetTickCount64NS();
|
||||
*usecs = WINPR_TIME_NS_TO_US(ns);
|
||||
}
|
||||
|
||||
STOPWATCH* stopwatch_create(void)
|
||||
{
|
||||
STOPWATCH* sw = NULL;
|
||||
#ifdef _WIN32
|
||||
if (stopwatch_freq.QuadPart == 0)
|
||||
{
|
||||
QueryPerformanceFrequency(&stopwatch_freq);
|
||||
}
|
||||
#endif
|
||||
|
||||
sw = (STOPWATCH*)malloc(sizeof(STOPWATCH));
|
||||
STOPWATCH* sw = (STOPWATCH*)calloc(1, sizeof(STOPWATCH));
|
||||
if (!sw)
|
||||
return NULL;
|
||||
stopwatch_reset(sw);
|
||||
|
@ -322,6 +322,17 @@ extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
#define WINPR_TIME_NS_TO_S(ns) ((ns) / 1000000000ull)
|
||||
#define WINPR_TIME_NS_TO_MS(ns) ((ns) / 1000000ull)
|
||||
#define WINPR_TIME_NS_TO_US(ns) ((ns) / 1000ull)
|
||||
|
||||
#define WINPR_TIME_NS_REM_NS(ns) ((ns) % 1000000000ull)
|
||||
#define WINPR_TIME_NS_REM_US(ns) (WINPR_TIME_NS_REM_NS(ns) / 1000ull)
|
||||
#define WINPR_TIME_NS_REM_MS(ns) (WINPR_TIME_NS_REM_US(ns) / 1000ull)
|
||||
|
||||
WINPR_API UINT64 winpr_GetTickCount64NS(void);
|
||||
WINPR_API UINT64 winpr_GetUnixTimeNS(void);
|
||||
|
||||
WINPR_API DWORD GetTickCountPrecise(void);
|
||||
|
||||
WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature);
|
||||
|
@ -248,15 +248,12 @@ BOOL ntlm_write_ntlm_v2_response(wStream* s, const NTLMv2_RESPONSE* response)
|
||||
|
||||
void ntlm_current_time(BYTE* timestamp)
|
||||
{
|
||||
FILETIME filetime = { 0 };
|
||||
ULARGE_INTEGER time64 = { 0 };
|
||||
FILETIME ft = { 0 };
|
||||
|
||||
WINPR_ASSERT(timestamp);
|
||||
|
||||
GetSystemTimeAsFileTime(&filetime);
|
||||
time64.u.LowPart = filetime.dwLowDateTime;
|
||||
time64.u.HighPart = filetime.dwHighDateTime;
|
||||
CopyMemory(timestamp, &(time64.QuadPart), 8);
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
CopyMemory(timestamp, &(ft), sizeof(ft));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -707,11 +707,11 @@ static void timespec_add_ms(struct timespec* tspec, UINT32 ms)
|
||||
|
||||
static void timespec_gettimeofday(struct timespec* tspec)
|
||||
{
|
||||
struct timeval tval;
|
||||
WINPR_ASSERT(tspec);
|
||||
gettimeofday(&tval, NULL);
|
||||
tspec->tv_sec = tval.tv_sec;
|
||||
tspec->tv_nsec = tval.tv_usec * 1000;
|
||||
|
||||
const UINT64 ns = winpr_GetUnixTimeNS();
|
||||
tspec->tv_sec = WINPR_TIME_NS_TO_S(ns);
|
||||
tspec->tv_nsec = WINPR_TIME_NS_REM_NS(ns);
|
||||
}
|
||||
|
||||
static INT64 timespec_compare(const struct timespec* tspec1, const struct timespec* tspec2)
|
||||
|
@ -59,60 +59,16 @@
|
||||
|
||||
#include "../pipe/pipe.h"
|
||||
|
||||
/* clock_gettime is not implemented on OSX prior to 10.12 */
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC 0
|
||||
#endif
|
||||
|
||||
/* clock_gettime is not implemented on OSX prior to 10.12 */
|
||||
int _mach_clock_gettime(int clk_id, struct timespec* t);
|
||||
|
||||
int _mach_clock_gettime(int clk_id, struct timespec* t)
|
||||
static struct timespec ts_from_ns(void)
|
||||
{
|
||||
UINT64 time = 0;
|
||||
double seconds = 0.0;
|
||||
double nseconds = 0.0;
|
||||
mach_timebase_info_data_t timebase = { 0 };
|
||||
mach_timebase_info(&timebase);
|
||||
time = mach_absolute_time();
|
||||
nseconds = ((double)time * (double)timebase.numer) / ((double)timebase.denom);
|
||||
seconds = ((double)time * (double)timebase.numer) / ((double)timebase.denom * 1e9);
|
||||
t->tv_sec = seconds;
|
||||
t->tv_nsec = nseconds;
|
||||
return 0;
|
||||
const UINT64 ns = winpr_GetUnixTimeNS();
|
||||
struct timespec timeout = { 0 };
|
||||
timeout.tv_sec = WINPR_TIME_NS_TO_S(ns);
|
||||
timeout.tv_nsec = WINPR_TIME_NS_REM_NS(ns);
|
||||
;
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */
|
||||
#ifdef __CLOCK_AVAILABILITY
|
||||
/* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be declared
|
||||
* * but it may be NULL at runtime. So we need to check before using it. */
|
||||
int _mach_safe_clock_gettime(int clk_id, struct timespec* t);
|
||||
|
||||
int _mach_safe_clock_gettime(int clk_id, struct timespec* t)
|
||||
{
|
||||
if (clock_gettime)
|
||||
{
|
||||
return clock_gettime(clk_id, t);
|
||||
}
|
||||
|
||||
return _mach_clock_gettime(clk_id, t);
|
||||
}
|
||||
|
||||
#define clock_gettime _mach_safe_clock_gettime
|
||||
#else
|
||||
#define clock_gettime _mach_clock_gettime
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Drop in replacement for pthread_mutex_timedlock
|
||||
* http://code.google.com/p/android/issues/detail?id=7807
|
||||
@ -148,14 +104,14 @@ STATIC_NEEDED int pthread_mutex_timedlock(pthread_mutex_t* mutex,
|
||||
unsigned long long diff = 0;
|
||||
int retcode = -1;
|
||||
/* This is just to avoid a completely busy wait */
|
||||
clock_gettime(CLOCK_MONOTONIC, &timenow);
|
||||
timenow = ts_from_ns();
|
||||
diff = ts_difftime(&timenow, timeout);
|
||||
sleepytime.tv_sec = diff / 1000000000LL;
|
||||
sleepytime.tv_nsec = diff % 1000000000LL;
|
||||
|
||||
while ((retcode = pthread_mutex_trylock(mutex)) == EBUSY)
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, &timenow);
|
||||
timenow = ts_from_ns();
|
||||
|
||||
if (ts_difftime(timeout, &timenow) >= 0)
|
||||
{
|
||||
@ -237,8 +193,8 @@ DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertabl
|
||||
if (dwMilliseconds != INFINITE)
|
||||
{
|
||||
int status = 0;
|
||||
struct timespec timeout = { 0 };
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeout);
|
||||
struct timespec timeout = ts_from_ns();
|
||||
|
||||
ts_add_ms(&timeout, dwMilliseconds);
|
||||
status = pthread_mutex_timedlock(&mutex->mutex, &timeout);
|
||||
|
||||
|
@ -33,9 +33,43 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#if defined(_POSIX_SOURCE) && (_POSIX_C_SOURCE >= 200112L)
|
||||
#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 >= 200112L)
|
||||
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 = { 0 };
|
||||
|
||||
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)
|
||||
*/
|
||||
struct timeval tv;
|
||||
|
||||
if (!gettimeofday(&tv, NULL))
|
||||
ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
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 _POSIX_C_SOURCE >= 200112L
|
||||
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
|
||||
|
@ -29,27 +29,11 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
|
||||
#include "../../log.h"
|
||||
#define TAG WINPR_TAG("utils.wlog")
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
static int gettimeofday(struct timeval* tp, void* tz)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
tp->tv_sec = (long)timebuffer.time;
|
||||
tp->tv_usec = timebuffer.millitm * 1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOL Pcap_Read_Header(wPcap* pcap, wPcapHeader* header)
|
||||
{
|
||||
if (pcap && pcap->fp && fread((void*)header, sizeof(wPcapHeader), 1, pcap->fp) == 1)
|
||||
@ -89,8 +73,7 @@ static BOOL Pcap_Read_Record(wPcap* pcap, wPcapRecord* record)
|
||||
|
||||
static BOOL Pcap_Add_Record(wPcap* pcap, void* data, UINT32 length)
|
||||
{
|
||||
wPcapRecord* record;
|
||||
struct timeval tp;
|
||||
wPcapRecord* record = NULL;
|
||||
|
||||
if (!pcap->tail)
|
||||
{
|
||||
@ -117,9 +100,10 @@ static BOOL Pcap_Add_Record(wPcap* pcap, void* data, UINT32 length)
|
||||
record->length = length;
|
||||
record->header.incl_len = length;
|
||||
record->header.orig_len = length;
|
||||
gettimeofday(&tp, 0);
|
||||
record->header.ts_sec = tp.tv_sec;
|
||||
record->header.ts_usec = tp.tv_usec;
|
||||
|
||||
UINT64 ns = winpr_GetUnixTimeNS();
|
||||
record->header.ts_sec = WINPR_TIME_NS_TO_S(ns);
|
||||
record->header.ts_usec = WINPR_TIME_NS_REM_US(ns);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -380,7 +364,6 @@ BOOL WLog_PacketMessage_Write(wPcap* pcap, void* data, size_t length, DWORD flag
|
||||
{
|
||||
wTcpHeader tcp;
|
||||
wIPv4Header ipv4;
|
||||
struct timeval tp;
|
||||
wPcapRecord record;
|
||||
wEthernetHeader ethernet;
|
||||
ethernet.Type = 0x0800;
|
||||
@ -474,9 +457,11 @@ BOOL WLog_PacketMessage_Write(wPcap* pcap, void* data, size_t length, DWORD flag
|
||||
record.header.incl_len = (UINT32)record.length + offset;
|
||||
record.header.orig_len = (UINT32)record.length + offset;
|
||||
record.next = NULL;
|
||||
gettimeofday(&tp, 0);
|
||||
record.header.ts_sec = tp.tv_sec;
|
||||
record.header.ts_usec = tp.tv_usec;
|
||||
|
||||
UINT64 ns = winpr_GetUnixTimeNS();
|
||||
record.header.ts_sec = WINPR_TIME_NS_TO_S(ns);
|
||||
record.header.ts_usec = WINPR_TIME_NS_REM_US(ns);
|
||||
|
||||
if (!Pcap_Write_RecordHeader(pcap, &record.header) ||
|
||||
!WLog_PacketMessage_Write_EthernetHeader(pcap, ðernet) ||
|
||||
!WLog_PacketMessage_Write_IPv4Header(pcap, &ipv4) ||
|
||||
|
Loading…
Reference in New Issue
Block a user