mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-13 18:55:10 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c4f09953d8
@ -22,6 +22,7 @@
|
||||
#include "likely.hpp"
|
||||
#include "config.hpp"
|
||||
#include "err.hpp"
|
||||
#include "mutex.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@ -41,9 +42,47 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
typedef ULONGLONG (*f_compatible_get_tick_count64)();
|
||||
|
||||
static zmq::mutex_t compatible_get_tick_count64_mutex;
|
||||
|
||||
ULONGLONG compatible_get_tick_count64()
|
||||
{
|
||||
compatible_get_tick_count64_mutex.lock();
|
||||
static DWORD s_wrap = 0;
|
||||
static DWORD s_last_tick = 0;
|
||||
const DWORD current_tick = ::GetTickCount();
|
||||
if (current_tick < s_last_tick)
|
||||
++s_wrap;
|
||||
|
||||
s_last_tick = current_tick;
|
||||
const ULONGLONG result = (static_cast<ULONGLONG>(s_wrap) << 32) + static_cast<ULONGLONG>(current_tick);
|
||||
compatible_get_tick_count64_mutex.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
f_compatible_get_tick_count64 init_compatible_get_tick_count64()
|
||||
{
|
||||
f_compatible_get_tick_count64 func = NULL;
|
||||
HMODULE module = ::LoadLibraryA("Kernel32.dll");
|
||||
if (module != NULL)
|
||||
func = reinterpret_cast<f_compatible_get_tick_count64>(::GetProcAddress(module, "GetTickCount64"));
|
||||
|
||||
if (func == NULL)
|
||||
func = compatible_get_tick_count64;
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
static f_compatible_get_tick_count64 my_get_tick_count64 = init_compatible_get_tick_count64();
|
||||
|
||||
zmq::clock_t::clock_t () :
|
||||
last_tsc (rdtsc ()),
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
last_time (static_cast<uint64_t>((*my_get_tick_count64)()))
|
||||
#else
|
||||
last_time (now_us () / 1000)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -65,7 +104,7 @@ uint64_t zmq::clock_t::now_us ()
|
||||
|
||||
// Convert the tick number into the number of seconds
|
||||
// since the system was started.
|
||||
double ticks_div = ticksPerSecond.QuadPart / 1000000.0;
|
||||
double ticks_div = ticksPerSecond.QuadPart / 1000000.0;
|
||||
return (uint64_t) (tick.QuadPart / ticks_div);
|
||||
|
||||
#elif defined HAVE_CLOCK_GETTIME && defined CLOCK_MONOTONIC
|
||||
@ -74,7 +113,7 @@ uint64_t zmq::clock_t::now_us ()
|
||||
struct timespec tv;
|
||||
int rc = clock_gettime (CLOCK_MONOTONIC, &tv);
|
||||
// Fix case where system has clock_gettime but CLOCK_MONOTONIC is not supported.
|
||||
// This should be a configuration check, but I looked into it and writing an
|
||||
// This should be a configuration check, but I looked into it and writing an
|
||||
// AC_FUNC_CLOCK_MONOTONIC seems beyond my powers.
|
||||
if( rc != 0) {
|
||||
// Use POSIX gettimeofday function to get precise time.
|
||||
@ -106,7 +145,18 @@ uint64_t zmq::clock_t::now_ms ()
|
||||
|
||||
// If TSC is not supported, get precise time and chop off the microseconds.
|
||||
if (!tsc)
|
||||
{
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
// Under Windows, now_us is not so reliable since QueryPerformanceCounter
|
||||
// does not guarantee that it will use a hardware that offers a monotonic timer.
|
||||
// So, lets use GetTickCount when GetTickCount64 is not available with an workaround
|
||||
// to its 32 bit limitation.
|
||||
static_assert(sizeof(uint64_t) >= sizeof(ULONGLONG), "Loosing timer information");
|
||||
return static_cast<uint64_t>((*my_get_tick_count64)());
|
||||
#else
|
||||
return now_us () / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
// If TSC haven't jumped back (in case of migration to a different
|
||||
// CPU core) and if not too much time elapsed since last measurement,
|
||||
@ -115,7 +165,11 @@ uint64_t zmq::clock_t::now_ms ()
|
||||
return last_time;
|
||||
|
||||
last_tsc = tsc;
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
last_time = static_cast<uint64_t>((*my_get_tick_count64)());
|
||||
#else
|
||||
last_time = now_us () / 1000;
|
||||
#endif
|
||||
return last_time;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user