Windows NowNanos() overflows
Open
- Dominant language
- C++
- Stars
- 32.1k
- Forks
- 6.9k
- Avg merge
- 32m
- Merged PRs (30d)
- 1
Description
> Note: Please use Issues only for bug reports. For questions, discussions, feature requests, etc. post to dev group: https://www.facebook.com/groups/rocksdb.dev
### Expected behavior
NowNanos() in port/win/env_win.cc is expected to provide an ever increasing clock.
### Actual behavior
This line causes an int64_t overflow: https://github.com/facebook/rocksdb/blame/master/port/win/env_win.cc#L970
### Steps to reproduce the behavior
int main()
{
// 10000000 is value from QueryPerformanceFrequency()
unsigned __int64 a = 1413478673602; // sample QueryPerformanceCounter() value
a *= (std::nano::den/10000000);
std::cout << "expected " << a << "\n";
a = 1413478673602;
a *= (std::nano::den);
a /= 10000000;
std::cout << "overflow " << a << "\n";
}
output:
expected 141347867360200
overflow 1152612400007
### suggested fix
uint64_t WinEnvIO::NowNanos() {
// all std::chrono clocks on windows have the same resolution that is only
// good enough for microseconds but not nanoseconds
// On Windows 8 and Windows 2012 Server
// GetSystemTimePreciseAsFileTime(¤t_time) can be used
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
// Convert to nanoseconds first to avoid loss of precision
// and divide by frequency
if (perf_counter_frequency_ < std::nano::den) {
li.QuadPart *= (std::nano::den / perf_counter_frequency_);
} else {
li.QuadPart /= (perf_counter_frequency_ / std::nano::den);
} // else
return li.QuadPart;
}
Contributor guide
Assessment
This issue has not been assessed yet.