blob: 585854f57acf6bb2a40b6eb2075e8de4b88b7148 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BEAM_CROSSPLATFORM_TIME_H
#define BEAM_CROSSPLATFORM_TIME_H
#include <time.h>
#ifdef _WIN32
#include <windows.h>
/**
* Alternative to POSIX clock_gettime that may be run on Windows platform. The clk_id parameter is
* ignored and function act as for CLOCK_MONOTONIC. On Windows XP or later Performance Counter is used.
* On older platforms, where there's no Performance Counter, SystemTime will be used as a failover.
*/
int clock_gettime(int clk_id, struct timespec *tv) {
static LARGE_INTEGER counterFrequency = {0};
static BOOL performanceCounterAvailable = TRUE;
LARGE_INTEGER counterValue = {0};
//initialization
if (0 == counterFrequency.QuadPart) {
if (0 == QueryPerformanceFrequency(&counterFrequency)) {
performanceCounterAvailable = FALSE;
counterFrequency.QuadPart = 10000000; // failover SystemTime is provided in 100-nanosecond intervals
}
}
if (performanceCounterAvailable) {
QueryPerformanceCounter(&counterValue);
}
else {
FILETIME filetime = {0};
GetSystemTimeAsFileTime(&filetime);
counterValue.QuadPart = filetime.dwHighDateTime;
counterValue.QuadPart <<= 32;
counterValue.QuadPart |= filetime.dwLowDateTime;
}
tv->tv_sec = counterValue.QuadPart / counterFrequency.QuadPart;
#pragma warning( suppress : 4244 ) // nanoseconds may not exceed billion, therefore it's safe to cast
tv->tv_nsec = ((counterValue.QuadPart % counterFrequency.QuadPart) * 1000000000) / counterFrequency.QuadPart;
return 0;
}
#endif
#endif //BEAM_CROSSPLATFORM_TIME_H