Skip to content

shims: use the precise Windows time functions #498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ if(WIN32)
target_sources(dispatch
PRIVATE
shims/generic_sys_queue.h
shims/generic_win_stubs.c
shims/generic_win_stubs.h
shims/getprogname.c)
endif()
Expand Down
44 changes: 30 additions & 14 deletions src/shims/generic_win_stubs.c
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
#include "internal.h"

/*
* This file contains stubbed out functions we are using during
* the initial Windows port. When the port is complete, this file
* should be empty (and thus removed).
*/
typedef void (WINAPI *_precise_time_fn_t)(PULONGLONG);

void
_dispatch_runloop_queue_dispose(dispatch_queue_t dq DISPATCH_UNUSED,
bool *allow_free DISPATCH_UNUSED)
DISPATCH_STATIC_GLOBAL(dispatch_once_t _dispatch_precise_time_pred);
DISPATCH_STATIC_GLOBAL(_precise_time_fn_t _dispatch_QueryInterruptTimePrecise_ptr);
DISPATCH_STATIC_GLOBAL(_precise_time_fn_t _dispatch_QueryUnbiasedInterruptTimePrecise_ptr);

static void
_dispatch_init_precise_time(void *context DISPATCH_UNUSED)
{
WIN_PORT_ERROR();
HMODULE kernelbase = LoadLibraryW(L"KernelBase.dll");
if (!kernelbase) {
DISPATCH_INTERNAL_CRASH(0, "failed to load KernelBase.dll");
}
_dispatch_QueryInterruptTimePrecise_ptr = (_precise_time_fn_t)
GetProcAddress(kernelbase, "QueryInterruptTimePrecise");
_dispatch_QueryUnbiasedInterruptTimePrecise_ptr = (_precise_time_fn_t)
GetProcAddress(kernelbase, "QueryUnbiasedInterruptTimePrecise");
if (!_dispatch_QueryInterruptTimePrecise_ptr) {
DISPATCH_INTERNAL_CRASH(0, "could not locate QueryInterruptTimePrecise");
}
if (!_dispatch_QueryUnbiasedInterruptTimePrecise_ptr) {
DISPATCH_INTERNAL_CRASH(0, "could not locate QueryUnbiasedInterruptTimePrecise");
}
}

void
_dispatch_runloop_queue_xref_dispose(dispatch_queue_t dq DISPATCH_UNUSED)
_dispatch_QueryInterruptTimePrecise(PULONGLONG lpInterruptTimePrecise)
{
WIN_PORT_ERROR();
dispatch_once_f(&_dispatch_precise_time_pred, NULL, _dispatch_init_precise_time);
return _dispatch_QueryInterruptTimePrecise_ptr(lpInterruptTimePrecise);
}

/*
* Stubbed out static data
*/
void
_dispatch_QueryUnbiasedInterruptTimePrecise(PULONGLONG lpUnbiasedInterruptTimePrecise)
{
dispatch_once_f(&_dispatch_precise_time_pred, NULL, _dispatch_init_precise_time);
return _dispatch_QueryUnbiasedInterruptTimePrecise_ptr(lpUnbiasedInterruptTimePrecise);
}
6 changes: 6 additions & 0 deletions src/shims/generic_win_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ typedef __typeof__(_Generic((__SIZE_TYPE__)0, \

#define strcasecmp _stricmp

/*
* Wrappers for dynamically loaded Windows APIs
*/
void _dispatch_QueryInterruptTimePrecise(PULONGLONG lpInterruptTimePrecise);
void _dispatch_QueryUnbiasedInterruptTimePrecise(PULONGLONG lpUnbiasedInterruptTimePrecise);

#endif
6 changes: 2 additions & 4 deletions src/shims/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ _dispatch_uptime(void)
return _dispatch_timespec_to_nano(ts);
#elif defined(_WIN32)
ULONGLONG ullUnbiasedTime;
QueryUnbiasedInterruptTime(&ullUnbiasedTime);
_dispatch_QueryUnbiasedInterruptTimePrecise(&ullUnbiasedTime);
return ullUnbiasedTime * 100;
#else
#error platform needs to implement _dispatch_uptime()
Expand All @@ -173,9 +173,7 @@ _dispatch_monotonic_time(void)
return _dispatch_timespec_to_nano(ts);
#elif defined(_WIN32)
ULONGLONG ullTime;
if (!QueryUnbiasedInterruptTime(&ullTime))
return 0;

_dispatch_QueryInterruptTimePrecise(&ullTime);
return ullTime * 100ull;
#else
#error platform needs to implement _dispatch_monotonic_time()
Expand Down