summaryrefslogtreecommitdiffstats
path: root/src/runtime/q3dsprofiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/q3dsprofiler.cpp')
-rw-r--r--src/runtime/q3dsprofiler.cpp91
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