diff --git a/vrs/os/Time.cpp b/vrs/os/Time.cpp index 1a8a3455..eb2d8d43 100644 --- a/vrs/os/Time.cpp +++ b/vrs/os/Time.cpp @@ -20,6 +20,12 @@ #include +#if IS_MAC_PLATFORM() || IS_LINUX_PLATFORM() +#include +#elif IS_WINDOWS_PLATFORM() +#include +#endif + namespace vrs { namespace os { @@ -40,5 +46,52 @@ int64_t getTimestampMs() { return duration_cast(steady_clock::now().time_since_epoch()).count(); } +bool getProcessCpuTimes(double& outUserCpuTime, double& outSystemCpuTime) { +#if IS_MAC_PLATFORM() || IS_LINUX_PLATFORM() + struct rusage r_usage; + getrusage(RUSAGE_SELF, &r_usage); + const double cMicroseconds = 1e-6; + outUserCpuTime = r_usage.ru_utime.tv_sec + r_usage.ru_utime.tv_usec * cMicroseconds; + outSystemCpuTime = r_usage.ru_stime.tv_sec + r_usage.ru_stime.tv_usec * cMicroseconds; + return true; + +#elif IS_WINDOWS_PLATFORM() + FILETIME start; + FILETIME exit; + ULARGE_INTEGER kernelTime; + ULARGE_INTEGER userTime; + + if (GetProcessTimes( + GetCurrentProcess(), + &start, + &exit, + reinterpret_cast(&kernelTime), + reinterpret_cast(&userTime)) == 0) { + outUserCpuTime = 0; + outSystemCpuTime = 0; + return false; + } + + const double cSecFactor = 1e-7; // source is a count of 0.1us + outUserCpuTime = userTime.QuadPart * cSecFactor; + outSystemCpuTime = kernelTime.QuadPart * cSecFactor; + return true; + +#else + outUserCpuTime = 0; + outSystemCpuTime = 0; + return false; +#endif +} + +double getTotalProcessCpuTime() { + double user = 0; + double kernel = 0; + if (!getProcessCpuTimes(user, kernel)) { + return 0; + } + return user + kernel; +} + } // namespace os } // namespace vrs diff --git a/vrs/os/Time.h b/vrs/os/Time.h index aa714421..6e066b1d 100644 --- a/vrs/os/Time.h +++ b/vrs/os/Time.h @@ -41,5 +41,13 @@ int64_t getTimestampMs(); /// Therefore, using double is misleading & dangerous. int64_t getCurrentTimeSecSinceEpoch(); +/// Get process usage time, splitting User CPU time and System CPU time +/// Returns false if not implemented on that platform. +bool getProcessCpuTimes(double& outUserCpuTime, double& outSystemCpuTime); + +/// Get User and System CPU time as one +/// Returns 0 if not supported. +double getTotalProcessCpuTime(); + } // namespace os } // namespace vrs diff --git a/vrs/os/Utils.h b/vrs/os/Utils.h index c6cce653..df9f8782 100644 --- a/vrs/os/Utils.h +++ b/vrs/os/Utils.h @@ -43,6 +43,10 @@ int64_t fileTell(std::FILE* file); int fileSeek(std::FILE* file, int64_t offset, int origin); int fileSetSize(std::FILE* file, int64_t size); +inline bool fileWriteString(FILE* f, const std::string& str) { + return os::fileWrite(str.c_str(), 1, str.size(), f) == str.size(); +} + /// Misc helpers int remove(const std::string& path); // file or folder int rename(const std::string& originalName, const std::string& newName); // file or folder