From b259a46ab740710dae2ed592ecf5cf1b6b37da6c Mon Sep 17 00:00:00 2001 From: Nicolas Hillegeer Date: Sat, 13 Sep 2014 17:25:22 +0200 Subject: [PATCH] linux/threads: simplify timer code Possibly also changes the semantics. According to the docs, it should now be equal to the Windows code (up to accuracy issues, of course). v2: done by gregory38 Fix miscalculation of time. Unit must be in 1s/GetThreadTicksPerSeconds(). (now us) Factorize a bit GetCpuTime/GetThreadCpuTime Note: results seems reasonables and mostly equivalent as before. --- common/src/Utilities/Linux/LnxThreads.cpp | 52 +++++++++-------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/common/src/Utilities/Linux/LnxThreads.cpp b/common/src/Utilities/Linux/LnxThreads.cpp index 924d3b20c2..ccd784a333 100644 --- a/common/src/Utilities/Linux/LnxThreads.cpp +++ b/common/src/Utilities/Linux/LnxThreads.cpp @@ -56,38 +56,35 @@ __forceinline void Threading::DisableHiresScheduler() { } +// Unit of time of GetThreadCpuTime/GetCpuTime u64 Threading::GetThreadTicksPerSecond() { - // Note the value is not correct but I'm not sure we can do better because - // most modern system use a tickless system anyway - // Besides x86 architecture always returns 100; - /* A Forum post extract - sysconf(SC_CLK_TCK) does not give the frequency of the timer interrupts in Linux. It gives - the frequency of jiffies which is visible to userspace in things like the counters in various directories in /proc - - The actual frequency is hidden from userspace, deliberately. Indeed, some systems - use dynamic ticks or "tickless" systems, so there aren't really any at all. - */ - u32 hertz = sysconf(_SC_CLK_TCK); - return hertz; + return 1000000; } -u64 Threading::GetThreadCpuTime() +// Helper function to get either either the current cpu usage +// in called thread or in id thread +static u64 get_thread_time(uptr id = 0) { - // Get the cpu time for the current thread. Should be a measure of total time the - // thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(), - // which typically would be an OS-provided scalar or some sort). - clockid_t cid; - int err = pthread_getcpuclockid(pthread_self(), &cid); - if (err) return 0; + if (id) { + int err = pthread_getcpuclockid(id, &cid); + if (err) return 0; + } else { + cid = CLOCK_THREAD_CPUTIME_ID; + } struct timespec ts; - err = clock_gettime(cid, &ts); + int err = clock_gettime(cid, &ts); if (err) return 0; - unsigned long timeJiff = (ts.tv_sec*1e6 + ts.tv_nsec / 1000)/1e6 * GetThreadTicksPerSecond(); - return timeJiff; + return (u64) ts.tv_sec * (u64) 1e6 + (u64) ts.tv_nsec / (u64) 1e3; +} + +// Returns the current timestamp (not relative to a real world clock) +u64 Threading::GetThreadCpuTime() +{ + return get_thread_time(); } u64 Threading::pxThread::GetCpuTime() const @@ -99,16 +96,7 @@ u64 Threading::pxThread::GetCpuTime() const if (!m_native_id) return 0; - clockid_t cid; - int err = pthread_getcpuclockid(m_native_id, &cid); - if (err) return 0; - - struct timespec ts; - err = clock_gettime(cid, &ts); - if (err) return 0; - unsigned long timeJiff = (ts.tv_sec*1e6 + ts.tv_nsec / 1000)/1e6 * GetThreadTicksPerSecond(); - - return timeJiff; + return get_thread_time(m_native_id); } void Threading::pxThread::_platform_specific_OnStartInThread()