Ticket #11660: stable_get_last_bootup_time.hpp

File stable_get_last_bootup_time.hpp, 1.7 KB (added by bmccart@…, 7 years ago)

Alternate implementation

Line 
1inline ULONGLONG stable_precision(ULONGLONG value)
2{
3 static const ULONGLONG precision = 64;
4 ULONGLONG remainder = value % precision;
5 ULONGLONG truncated = value - remainder;
6 ULONGLONG offset = (remainder >= (precision / 2)) ? precision : 0;
7 ULONGLONG stable = truncated + offset;
8 return stable;
9}
10
11inline bool get_last_bootup_time(std::string &stamp)
12{
13 ULONGLONG t0 = 0;
14 ULONGLONG t1 = 1;
15 SYSTEMTIME st;
16 ZeroMemory(&st, sizeof(st));
17
18 static const size_t max_attempts = 113; // Limit number of retries to arbitrary number (not infanite) but suficiently large enough to acomplish timing except in pedantic cases...
19 for (size_t i = 0; (i != max_attempts) && (t0 != t1); ++i)
20 {
21 t0 = GetTickCount64();
22 GetSystemTime(&st);
23 t1 = GetTickCount64();
24 }
25 if (t0 != t1)
26 return false; // Presume this is *very* unlikely.
27
28 // Convert system time (Y/M/D h/m/s/millisec) to file time (100 nanosecond intervals).
29 FILETIME ft;
30 if (SystemTimeToFileTime(&st, &ft) == FALSE)
31 return false; // Presume this will never fail since system time is expected to be valid.
32
33 ULARGE_INTEGER uli;
34 uli.LowPart = ft.dwLowDateTime;
35 uli.HighPart = ft.dwHighDateTime;
36
37 // Convert file time to milliseconds.
38 ULONGLONG ft_millisec = uli.QuadPart / 10000;
39
40 // Round milliseconds to the nearest stable precision (inconsistency/imprecision between system clock & tick count).
41 ULONGLONG time = stable_precision(ft_millisec);
42 ULONGLONG ticks = stable_precision(t0);
43 ULONGLONG boot_time = time - ticks;
44 std::ostringstream oss;
45 oss << boot_time;
46 stamp = oss.str();
47
48 return true;
49}