diff options
Diffstat (limited to 'src/runtime/q3dsprofiler.cpp')
-rw-r--r-- | src/runtime/q3dsprofiler.cpp | 91 |
1 files changed, 86 insertions, 5 deletions
diff --git a/src/runtime/q3dsprofiler.cpp b/src/runtime/q3dsprofiler.cpp index 8303498..727229a 100644 --- a/src/runtime/q3dsprofiler.cpp +++ b/src/runtime/q3dsprofiler.cpp @@ -45,6 +45,7 @@ #ifdef Q_OS_MACOS #include <mach/mach_types.h> #include <mach/mach.h> +#include <sys/sysctl.h> #endif QT_BEGIN_NAMESPACE @@ -263,8 +264,6 @@ float Q3DSProfiler::cpuLoadForCurrentProcess() m_lastUserTimeSys = userTimeSys; m_lastKernelTimeProc = kernelTimeProc; m_lastUserTimeProc = userTimeProc; - - return m_lastCpuLoad; #elif defined(Q_OS_LINUX) if (!m_numCpus) { QFile f(QLatin1String("/proc/cpuinfo")); @@ -291,10 +290,81 @@ float Q3DSProfiler::cpuLoadForCurrentProcess() m_lastTimestamp = timestamp; m_lastKernel = processTimes.tms_stime; m_lastUser = processTimes.tms_utime; - return m_lastCpuLoad; -#else - return m_lastCpuLoad; +#elif defined(Q_OS_MACOS) + // Get thread times + mach_port_t task = mach_task_self(); + task_thread_times_info threadTimes = {}; + mach_msg_type_number_t outCount = TASK_THREAD_TIMES_INFO_COUNT; + + kern_return_t retVal = task_info(task, TASK_THREAD_TIMES_INFO, + task_info_t(&threadTimes), &outCount); + if (retVal != KERN_SUCCESS) + return m_lastCpuLoad; + + // Get task info + mach_task_basic_info_data_t taskInfo = {}; + outCount = MACH_TASK_BASIC_INFO_COUNT; + retVal = task_info(task, MACH_TASK_BASIC_INFO, + task_info_t(&taskInfo), &outCount); + + if (retVal != KERN_SUCCESS) + return m_lastCpuLoad; + + struct timeval userTimeVal, systemTimeVal, totalTimeVal; + + // Thread info contains alive time + userTimeVal.tv_sec = threadTimes.user_time.seconds; + userTimeVal.tv_usec = threadTimes.user_time.microseconds; + systemTimeVal.tv_sec = threadTimes.system_time.seconds; + systemTimeVal.tv_usec = threadTimes.system_time.microseconds; + + // Add user time and system time to total time + timeradd(&userTimeVal, &systemTimeVal, &totalTimeVal); + + // Task info has terminated time + userTimeVal.tv_sec = taskInfo.user_time.seconds; + userTimeVal.tv_usec = taskInfo.user_time.microseconds; + systemTimeVal.tv_sec = taskInfo.system_time.seconds; + systemTimeVal.tv_usec = taskInfo.system_time.microseconds; + + // Add user time and system time to total time + timeradd(&userTimeVal, &totalTimeVal, &totalTimeVal); + timeradd(&systemTimeVal, &totalTimeVal, &totalTimeVal); + + // Get current time + struct timeval now; + int error = gettimeofday(&now, nullptr); + if (error) + return m_lastCpuLoad; + + // Convert everything to microseconds + qint64 timestamp = timeValToMicroseconds(now); + qint64 totalTaskTime = timeValToMicroseconds(totalTimeVal); + + // On first execution just store the current values + if (m_lastTimestamp == 0) { + m_lastTimestamp = timestamp; + m_lastTaskTime = totalTaskTime; + return m_lastCpuLoad; + } + + // Calculate percentage of CPU time this task used over delta time + qint64 taskDeltaTime = totalTaskTime - m_lastTaskTime; + qint64 totalDeltaTime = timestamp - m_lastTimestamp; + + if (totalDeltaTime == 0) + return m_lastCpuLoad; + + m_lastTimestamp = timestamp; + m_lastTaskTime = totalTaskTime; + + m_lastCpuLoad = (taskDeltaTime * 100.f) + / float(totalDeltaTime) + / float(m_macOSProfiler.numActiveProcessors()); + #endif + + return m_lastCpuLoad; } QPair<qint64, qint64> Q3DSProfiler::memUsageForCurrentProcess() @@ -358,4 +428,15 @@ QPair<qint64, qint64> Q3DSProfiler::memUsageForCurrentProcess() return m_lastMemUsage; } +#if defined(Q_OS_MACOS) +qint64 Q3DSProfiler::timeValToMicroseconds(const struct timeval& timeVal) +{ + static const int microsecondsPerSecond = 1000000; + qint64 retVal = timeVal.tv_sec; + retVal *= microsecondsPerSecond; + retVal += timeVal.tv_usec; + return retVal; +} +#endif + QT_END_NAMESPACE |