diff --git a/power_overwhelming/include/power_overwhelming/timestamp_resolution.h b/power_overwhelming/include/power_overwhelming/timestamp_resolution.h
index 69645e70..520b49f8 100644
--- a/power_overwhelming/include/power_overwhelming/timestamp_resolution.h
+++ b/power_overwhelming/include/power_overwhelming/timestamp_resolution.h
@@ -29,6 +29,12 @@ namespace power_overwhelming {
///
microseconds,
+ ///
+ /// Timestamp is specified in units of hundred nanoseconds (the native
+ /// quantity of many Windows APIs).
+ ///
+ hundred_nanoseconds,
+
///
/// Timestamp is specified in nanoseconds (Billionth of a second).
///
diff --git a/power_overwhelming/src/timestamp.cpp b/power_overwhelming/src/timestamp.cpp
index f0a3806b..7e7df618 100644
--- a/power_overwhelming/src/timestamp.cpp
+++ b/power_overwhelming/src/timestamp.cpp
@@ -11,10 +11,10 @@
*/
visus::power_overwhelming::timestamp_type
visus::power_overwhelming::detail::convert(
- const timestamp_type fileTime,
+ const timestamp_type file_time,
const timestamp_resolution resolution) {
using namespace std::chrono;
- duration ft(fileTime);
+ duration ft(file_time);
switch (resolution) {
case timestamp_resolution::microseconds:
@@ -26,11 +26,14 @@ visus::power_overwhelming::detail::convert(
case timestamp_resolution::nanoseconds:
return duration_cast(ft).count();
+ case timestamp_resolution::hundred_nanoseconds:
+ return file_time;
+
case timestamp_resolution::seconds:
return duration_cast(ft).count();
default:
- return fileTime;
+ return file_time;
}
}
diff --git a/power_overwhelming/src/timestamp.h b/power_overwhelming/src/timestamp.h
index 75ac365a..9411784f 100644
--- a/power_overwhelming/src/timestamp.h
+++ b/power_overwhelming/src/timestamp.h
@@ -41,11 +41,12 @@ namespace detail {
/// This API is only exposed for unit tests and should not be accessed by
/// any other clients.
///
- /// The file time value in 100ns units.
+ /// The file time value in 100ns units.
/// The desired resolution of the timestamp.
///
/// The timestamp in the requested resolution.
- timestamp_type POWER_OVERWHELMING_API convert(const timestamp_type fileTime,
+ timestamp_type POWER_OVERWHELMING_API convert(
+ const timestamp_type file_time,
const timestamp_resolution resolution);
#if defined(_WIN32)
@@ -53,14 +54,14 @@ namespace detail {
/// Convert the given raw to a timestamp of the
/// specified resolution.
///
- /// The file time value in 100ns units.
+ /// The file time value in 100ns units.
/// The desired resolution of the timestamp.
///
/// The timestamp in the requested resolution.
inline POWER_OVERWHELMING_API decltype(LARGE_INTEGER::QuadPart) convert(
- const LARGE_INTEGER& fileTime,
+ const LARGE_INTEGER& file_time,
const timestamp_resolution resolution) {
- return convert(fileTime.QuadPart, resolution);
+ return convert(file_time.QuadPart, resolution);
}
#endif /* defined(_WIN32) */
diff --git a/power_overwhelming/src/timestamp.inl b/power_overwhelming/src/timestamp.inl
index 9f255dae..680c6657 100644
--- a/power_overwhelming/src/timestamp.inl
+++ b/power_overwhelming/src/timestamp.inl
@@ -58,10 +58,11 @@ visus::power_overwhelming::detail::convert(
TDuration>& timestamp,
_In_ const timestamp_resolution resolution) {
using namespace std::chrono;
+ typedef duration filetime_dur;
// The offset of the FILETIME epoch to the UNIX epoch.
const auto dz = duration(11644473600000LL);
+ detail::filetime_period>(116444736000000000LL);
// Find out what the difference between the time point and the UNIX
// epoch is. Because we cannot rely on the epoch of the STL clock being the
@@ -72,6 +73,9 @@ visus::power_overwhelming::detail::convert(
// Transform the origin of the timestamp clock to the origin of FILETIME.
switch (resolution) {
+ case timestamp_resolution::hundred_nanoseconds:
+ return duration_cast(dt + dz).count();
+
case timestamp_resolution::microseconds:
return duration_cast(dt + dz).count();
diff --git a/test/timestamp_test.cpp b/test/timestamp_test.cpp
index 057a3091..59fd8f9b 100644
--- a/test/timestamp_test.cpp
+++ b/test/timestamp_test.cpp
@@ -38,36 +38,69 @@ namespace test {
this->_system_zero = std::chrono::system_clock::from_time_t(0);
}
+ TEST_METHOD(test_convert) {
+ auto a = detail::convert(std::chrono::system_clock::from_time_t(0), timestamp_resolution::hundred_nanoseconds);
+ Assert::AreEqual(this->_filetime_zero, a, L"Unix epoch as FILETIME", LINE_INFO());
+ }
+
TEST_METHOD(test_microseconds) {
+ typedef std::chrono::microseconds unit;
+ static const auto resolution = timestamp_resolution::microseconds;
+ const auto max_dt = std::chrono::duration_cast(std::chrono::milliseconds(100)).count();
+
auto n = std::chrono::system_clock::now();
- auto t = detail::create_timestamp(timestamp_resolution::microseconds);
- auto s = std::chrono::duration_cast(n - this->_system_zero).count();
- auto z = detail::convert(this->_filetime_zero, timestamp_resolution::microseconds);
- Assert::IsTrue(s - z - t < 1000000, L"timestamp microsecond", LINE_INFO());
+ auto t = detail::create_timestamp(resolution);
+ auto s = std::chrono::duration_cast(n - this->_system_zero).count();
+ auto z = detail::convert(this->_filetime_zero, resolution);
+ Assert::IsTrue(s - z - t < max_dt, L"timestamp microsecond", LINE_INFO());
}
TEST_METHOD(test_milliseconds) {
+ typedef std::chrono::milliseconds unit;
+ static const auto resolution = timestamp_resolution::milliseconds;
+ const auto max_dt = std::chrono::duration_cast(std::chrono::milliseconds(100)).count();
+
auto n = std::chrono::system_clock::now();
auto t = detail::create_timestamp(timestamp_resolution::milliseconds);
auto s = std::chrono::duration_cast(n - this->_system_zero).count();
auto z = detail::convert(this->_filetime_zero, timestamp_resolution::milliseconds);
- Assert::IsTrue(t - z - s < 1000, L"timestamp millisecond", LINE_INFO());
+ Assert::IsTrue(t - z - s < max_dt, L"timestamp millisecond", LINE_INFO());
+ }
+
+ TEST_METHOD(test_hundred_nanoseconds) {
+ typedef std::chrono::duration unit;
+ static const auto resolution = timestamp_resolution::milliseconds;
+ const auto max_dt = std::chrono::duration_cast(std::chrono::milliseconds(100)).count();
+
+ auto n = std::chrono::system_clock::now();
+ auto t = detail::create_timestamp(resolution);
+ auto s = std::chrono::duration_cast(n - this->_system_zero).count();
+ auto z = detail::convert(this->_filetime_zero, resolution);
+ Assert::IsTrue(t - z - s < max_dt, L"timestamp 100 nanoseconds", LINE_INFO());
}
TEST_METHOD(test_nanoseconds) {
+ typedef std::chrono::milliseconds unit;
+ static const auto resolution = timestamp_resolution::milliseconds;
+ const auto max_dt = std::chrono::duration_cast(std::chrono::milliseconds(100)).count();
+
auto n = std::chrono::system_clock::now();
- auto t = detail::create_timestamp(timestamp_resolution::nanoseconds);
- auto s = std::chrono::duration_cast(n - this->_system_zero).count();
- auto z = detail::convert(this->_filetime_zero, timestamp_resolution::nanoseconds);
- Assert::IsTrue(t - z - s < 1000000000, L"timestamp nanosecond", LINE_INFO());
+ auto t = detail::create_timestamp(resolution);
+ auto s = std::chrono::duration_cast(n - this->_system_zero).count();
+ auto z = detail::convert(this->_filetime_zero, resolution);
+ Assert::IsTrue(t - z - s < max_dt, L"timestamp nanosecond", LINE_INFO());
}
TEST_METHOD(test_seconds) {
+ typedef std::chrono::seconds unit;
+ static const auto resolution = timestamp_resolution::seconds;
+ const auto max_dt = std::chrono::duration_cast(std::chrono::milliseconds(100)).count();
+
auto n = std::chrono::system_clock::now();
- auto t = detail::create_timestamp(timestamp_resolution::seconds);
- auto s = std::chrono::duration_cast(n - this->_system_zero).count();
- auto z = detail::convert(this->_filetime_zero, timestamp_resolution::seconds);
- Assert::IsTrue(s - z - t < 1, L"timestamp second", LINE_INFO());
+ auto t = detail::create_timestamp(resolution);
+ auto s = std::chrono::duration_cast(n - this->_system_zero).count();
+ auto z = detail::convert(this->_filetime_zero, resolution);
+ Assert::IsTrue(s - z - t < max_dt, L"timestamp second", LINE_INFO());
}
private: