How do I get system up time in milliseconds in c++?

user3426112 picture user3426112 · May 7, 2015 · Viewed 15.4k times · Source

How do I get system up time since the start of the system? All I found was time since epoch and nothing else.

For example, something like time() in ctime library, but it only gives me a value of seconds since epoch. I want something like time() but since the start of the system.

Answer

Pixelchemist picture Pixelchemist · May 7, 2015

It is OS dependant and already answered for several systems on stackoverflow.

#include<chrono> // for all examples :)

Windows ...

using GetTickCount64() (resolution usually 10-16 millisecond)

#include <windows>
// ...
auto uptime = std::chrono::milliseconds(GetTickCount64());

Linux ...

... using /proc/uptime

#include <fstream>
// ...
std::chrono::milliseconds uptime(0u);
double uptime_seconds;
if (std::ifstream("/proc/uptime", std::ios::in) >> uptime_seconds)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(uptime_seconds*1000.0)
  );
}

... using sysinfo (resolution 1 second)

#include <sys/sysinfo.h>
// ...
std::chrono::milliseconds uptime(0u);
struct sysinfo x;
if (sysinfo(&x) == 0)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(x.uptime)*1000ULL
  );
}

OS X ...

... using sysctl

#include <time.h>
#include <errno.h>
#include <sys/sysctl.h>
// ...
std::chrono::milliseconds uptime(0u);
struct timeval ts;
std::size_t len = sizeof(ts);
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
if (sysctl(mib, 2, &ts, &len, NULL, 0) == 0)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(ts.tv_sec)*1000ULL + 
    static_cast<unsigned long long>(ts.tv_usec)/1000ULL
  );
}

BSD-like systems (or systems supporting CLOCK_UPTIME or CLOCK_UPTIME_PRECISE respectively) ...

... using clock_gettime (resolution see clock_getres)

#include <time.h>
// ... 
std::chrono::milliseconds uptime(0u);
struct timespec ts;
if (clock_gettime(CLOCK_UPTIME_PRECISE, &ts) == 0)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(ts.tv_sec)*1000ULL + 
    static_cast<unsigned long long>(ts.tv_nsec)/1000000ULL
   );
}