TEST(DurationTest, OutputFormat) { EXPECT_EQ("1ns", stringify(Nanoseconds(1))); EXPECT_EQ("2ns", stringify(Nanoseconds(2))); // Truncated. Seconds in 15 digits of precision, max of double // type's precise digits. EXPECT_EQ("3.141592653secs", stringify(Duration::create(3.14159265358979).get())); EXPECT_EQ("3140ms", stringify(Duration::create(3.14).get())); EXPECT_EQ("10hrs", stringify(Hours(10))); EXPECT_EQ("-10hrs", stringify(Hours(-10))); // "10days" reads better than "1.42857142857143weeks" so it is // printed out in the lower unit. EXPECT_EQ("10days", stringify(Days(10))); // We go one-level down and it is still not a whole number so we // print it out using the higher unit. EXPECT_EQ("1.1875days", stringify(Days(1) + Hours(4) + Minutes(30))); // "2weeks" reads better than "14days" so we use the higher unit // here. EXPECT_EQ("2weeks", stringify(Days(14))); // Boundary cases. EXPECT_EQ("0ns", stringify(Duration::zero())); EXPECT_EQ("15250.2844524715weeks", stringify(Duration::max())); EXPECT_EQ("-15250.2844524715weeks", stringify(Duration::min())); }
Nanoseconds elapsed() { if (!running) { return Nanoseconds(diff(stopped, started)); } return Nanoseconds(diff(now(), started)); }
// static TimePoint Clock::Now() { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { return Nanoseconds(0); } int64_t ns = static_cast<int64_t>(ts.tv_sec) * 1000000000L + ts.tv_nsec; return Nanoseconds(ns); }
void Nanoseconds_ut::test() { const unsigned int NSEC_PER_SECOND = 1000000000; Nanoseconds n(1); Seconds s(1.0 / NSEC_PER_SECOND); CPPUNIT_ASSERT_EQUAL(Nanoseconds(s), n); n = Nanoseconds(2 * 3); int64_t ex = 6; CPPUNIT_ASSERT_EQUAL(ex, int64_t(n)); }
inline Try<Duration> Duration::create(double seconds) { if (seconds * SECONDS > LLONG_MAX || seconds * SECONDS < LLONG_MIN) { return Error("Argument out of the range that a Duration can represent due " "to int64_t's size limit"); } return Nanoseconds(static_cast<int64_t>(seconds * SECONDS)); }
inline Try<Duration> Duration::create(double seconds) { if (seconds * SECONDS > std::numeric_limits<int64_t>::max() || seconds * SECONDS < std::numeric_limits<int64_t>::min()) { return Error("Argument out of the range that a Duration can represent due " "to int64_t's size limit"); } return Nanoseconds(static_cast<int64_t>(seconds * SECONDS)); }
TEST(DurationTest, ParseAndTry) { EXPECT_SOME_EQ(Hours(3), Duration::parse("3hrs")); EXPECT_SOME_EQ(Hours(3) + Minutes(30), Duration::parse("3.5hrs")); EXPECT_SOME_EQ(Nanoseconds(3141592653), Duration::create(3.141592653)); // Duration can hold only 9.22337e9 seconds. EXPECT_ERROR(Duration::create(10 * 1e9)); EXPECT_ERROR(Duration::create(-10 * 1e9)); }
TEST(DurationTest, Comparison) { EXPECT_EQ(Duration::zero(), Seconds(0)); EXPECT_EQ(Minutes(180), Hours(3)); EXPECT_EQ(Seconds(10800), Hours(3)); EXPECT_EQ(Milliseconds(10800000), Hours(3)); EXPECT_EQ(Milliseconds(1), Microseconds(1000)); EXPECT_EQ(Milliseconds(1000), Seconds(1)); EXPECT_GT(Weeks(1), Days(6)); EXPECT_LT(Hours(23), Days(1)); EXPECT_LE(Hours(24), Days(1)); EXPECT_GE(Hours(24), Days(1)); EXPECT_NE(Minutes(59), Hours(1)); // Maintains precision for a 100 year duration. EXPECT_GT(Weeks(5217) + Nanoseconds(1), Weeks(5217)); EXPECT_LT(Weeks(5217) - Nanoseconds(1), Weeks(5217)); }
// static TimePoint Clock::Now() { LARGE_INTEGER freq; if (QueryPerformanceFrequency(&freq) == 0) { throw SystemError("QueryPerformanceFrequency"); } double ns_per_tick = 1E+9 / freq.QuadPart; LARGE_INTEGER count; if (QueryPerformanceCounter(&count) == 0) { throw SystemError("QueryPerformanceCounter"); } return Nanoseconds(ns_per_tick * count.QuadPart); }
// Generate a `Process` object for the process associated with `pid`. If // process is not found, we return `None`; error is reserved for the case where // something went wrong. inline Result<Process> process(pid_t pid) { // Find process with pid. Result<PROCESSENTRY32> entry = process_entry(pid); if (entry.isError()) { return WindowsError(entry.error()); } else if (entry.isNone()) { return None(); } HANDLE process_handle = ::OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, false, pid); if (process_handle == INVALID_HANDLE_VALUE) { return WindowsError("os::process: Call to `OpenProcess` failed"); } SharedHandle safe_process_handle(process_handle, ::CloseHandle); // Get Windows Working set size (Resident set size in linux). PROCESS_MEMORY_COUNTERS proc_mem_counters; BOOL get_process_memory_info = ::GetProcessMemoryInfo( safe_process_handle.get(), &proc_mem_counters, sizeof(proc_mem_counters)); if (!get_process_memory_info) { return WindowsError("os::process: Call to `GetProcessMemoryInfo` failed"); } // Get session Id. pid_t session_id; BOOL process_id_to_session_id = ::ProcessIdToSessionId(pid, &session_id); if (!process_id_to_session_id) { return WindowsError("os::process: Call to `ProcessIdToSessionId` failed"); } // Get Process CPU time. FILETIME create_filetime, exit_filetime, kernel_filetime, user_filetime; BOOL get_process_times = ::GetProcessTimes( safe_process_handle.get(), &create_filetime, &exit_filetime, &kernel_filetime, &user_filetime); if (!get_process_times) { return WindowsError("os::process: Call to `GetProcessTimes` failed"); } // Get utime and stime. ULARGE_INTEGER lKernelTime, lUserTime; // In 100 nanoseconds. lKernelTime.HighPart = kernel_filetime.dwHighDateTime; lKernelTime.LowPart = kernel_filetime.dwLowDateTime; lUserTime.HighPart = user_filetime.dwHighDateTime; lUserTime.LowPart = user_filetime.dwLowDateTime; Try<Duration> utime = Nanoseconds(lKernelTime.QuadPart * 100); Try<Duration> stime = Nanoseconds(lUserTime.QuadPart * 100); return Process( pid, entry.get().th32ParentProcessID, // Parent process id. 0, // Group id. session_id, Bytes(proc_mem_counters.WorkingSetSize), utime.isSome() ? utime.get() : Option<Duration>::none(), stime.isSome() ? stime.get() : Option<Duration>::none(), entry.get().szExeFile, // Executable filename. false); // Is not zombie process. }
inline constexpr Duration Duration::min() { return Nanoseconds(std::numeric_limits<int64_t>::min()); }
inline Duration Duration::min() { return Nanoseconds(LLONG_MIN); }
inline Duration Duration::max() { return Nanoseconds(LLONG_MAX); }