facebook / facebook/rocksdb

Windows NowNanos() overflows

Open
#4,983 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.