Commit baaec11b authored by Orvid King's avatar Orvid King Committed by facebook-github-bot-1

Implement clock_getres for Windows

Summary: Because the windows version of pthread very definitely does not implement the clock. The Cygwin and MinGW headers might, so let them still fall back to the pthread includes.
Closes https://github.com/facebook/folly/pull/280

Reviewed By: @yfeldblum

Differential Revision: D2419067

Pulled By: @JoelMarcey
parent 589b6f75
......@@ -48,7 +48,136 @@ int clock_getres(clockid_t clk_id, struct timespec* ts) {
return 0;
}
#elif _MSC_VER
#elif defined(_MSC_VER)
// The MSVC version has been extracted from the pthreads implemenation here:
// https://github.com/songdongsheng/libpthread
// Copyright(c) 2011, Dongsheng Song <songdongsheng@live.cn>
//
// It is under the Apache License Version 2.0, just as the rest of the file is.
// It has been mostly stripped down to what we have.
#include <WinSock2.h>
#define DELTA_EPOCH_IN_100NS INT64_C(116444736000000000)
#define POW10_7 INT64_C(10000000)
#define POW10_9 INT64_C(1000000000)
int clock_getres(clockid_t clock_id, struct timespec *res)
{
switch (clock_id) {
case CLOCK_MONOTONIC:
{
LARGE_INTEGER pf;
if (QueryPerformanceFrequency(&pf) == 0)
return -1;
res->tv_sec = 0;
res->tv_nsec = (int)((POW10_9 + (pf.QuadPart >> 1)) / pf.QuadPart);
if (res->tv_nsec < 1)
res->tv_nsec = 1;
return 0;
}
case CLOCK_REALTIME:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_THREAD_CPUTIME_ID:
{
DWORD timeAdjustment, timeIncrement;
BOOL isTimeAdjustmentDisabled;
(void)GetSystemTimeAdjustment(
&timeAdjustment,
&timeIncrement,
&isTimeAdjustmentDisabled
);
res->tv_sec = 0;
res->tv_nsec = timeIncrement * 100;
return 0;
}
default:
break;
}
return -1;
}
int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
unsigned __int64 t;
LARGE_INTEGER pf, pc;
union {
unsigned __int64 u64;
FILETIME ft;
} ct, et, kt, ut;
switch (clock_id) {
case CLOCK_REALTIME:
{
GetSystemTimeAsFileTime(&ct.ft);
t = ct.u64 - DELTA_EPOCH_IN_100NS;
tp->tv_sec = t / POW10_7;
tp->tv_nsec = ((int)(t % POW10_7)) * 100;
return 0;
}
case CLOCK_MONOTONIC:
{
if (QueryPerformanceFrequency(&pf) == 0)
return -1;
if (QueryPerformanceCounter(&pc) == 0)
return -1;
tp->tv_sec = pc.QuadPart / pf.QuadPart;
tp->tv_nsec = (int)(
((pc.QuadPart % pf.QuadPart) * POW10_9 + (pf.QuadPart >> 1)) /
pf.QuadPart
);
if (tp->tv_nsec >= POW10_9) {
tp->tv_sec++;
tp->tv_nsec -= POW10_9;
}
return 0;
}
case CLOCK_PROCESS_CPUTIME_ID:
{
if (0 == GetProcessTimes(GetCurrentProcess(),
&ct.ft, &et.ft, &kt.ft, &ut.ft)) {
return -1;
}
t = kt.u64 + ut.u64;
tp->tv_sec = t / POW10_7;
tp->tv_nsec = ((int)(t % POW10_7)) * 100;
return 0;
}
case CLOCK_THREAD_CPUTIME_ID:
{
if (0 == GetThreadTimes(GetCurrentThread(),
&ct.ft, &et.ft, &kt.ft, &ut.ft)) {
return -1;
}
t = kt.u64 + ut.u64;
tp->tv_sec = t / POW10_7;
tp->tv_nsec = ((int)(t % POW10_7)) * 100;
return 0;
}
default:
break;
}
return -1;
}
#elif defined(__CYGWIN__) || defined(__MINGW__)
// using winpthreads from mingw-w64
// <pthreads_time.h> has clock_gettime and friends
// make sure to include <pthread.h> as well for typedefs of timespec/etc
......
......@@ -28,12 +28,17 @@
#endif
/* For windows, we'll use pthread's time implementations */
#ifdef _MSC_VER
#if defined(__CYGWIN__) || defined(__MINGW__)
#include <pthread.h>
#include <pthread_time.h>
#else
typedef uint8_t clockid_t;
#define CLOCK_REALTIME 0
#ifdef _MSC_VER
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#endif
int clock_gettime(clockid_t clk_id, struct timespec* ts);
int clock_getres(clockid_t clk_id, struct timespec* ts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment