diff --git a/include/system.hpp b/include/system.hpp index 63d5761a..5f01d76b 100644 --- a/include/system.hpp +++ b/include/system.hpp @@ -162,6 +162,7 @@ double getTime(); /** Returns time since 1970-01-01 00:00:00 UTC in seconds. */ double getUnixTime(); +double getThreadTime(); std::string getOperatingSystemInfo(); // Applications diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index 6aaddc02..31ce740c 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -808,6 +808,9 @@ struct MeterLabel : ui::Label { int frameIndex = 0; double frameDurationTotal = 0.0; double frameDurationAvg = 0.0; + double uiLastTime = 0.0; + double uiLastThreadTime = 0.0; + double uiFrac = 0.0; void step() override { // Compute frame rate @@ -820,9 +823,19 @@ struct MeterLabel : ui::Label { frameIndex = 0; } + // Compute UI thread CPU + double time = system::getTime(); + double uiDuration = time - uiLastTime; + if (uiDuration >= 1.0) { + double threadTime = system::getThreadTime(); + uiFrac = (threadTime - uiLastThreadTime) / uiDuration; + uiLastThreadTime = threadTime; + uiLastTime = time; + } + double meterAverage = APP->engine->getMeterAverage(); double meterMax = APP->engine->getMeterMax(); - text = string::f("%.1f fps %.1f%% avg %.1f%% max", 1.0 / frameDurationAvg, meterAverage * 100, meterMax * 100); + text = string::f("%.1f fps %.1f%% avg %.1f%% max %.1f%% UI", 1.0 / frameDurationAvg, meterAverage * 100, meterMax * 100, uiFrac * 100); Label::step(); } }; diff --git a/src/system.cpp b/src/system.cpp index e79d5e3d..dd00b517 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -695,6 +695,27 @@ double getUnixTime() { } +double getThreadTime() { +#if defined ARCH_LIN + struct timespec ts; + clockid_t cid; + pthread_getcpuclockid(pthread_self(), &cid); + clock_gettime(cid, &ts); + return ts.tv_sec + ts.tv_nsec * 1e-9; +#elif defined ARCH_MAC + mach_port_t thread = mach_thread_self(); + mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; + thread_basic_info_data_t info; + kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count); + if (kr != KERN_SUCCESS || (info.flags & TH_FLAGS_IDLE) != 0) + return 0.0; + return info.user_time.seconds + info.user_time.microseconds * 1e-6; +#elif defined ARCH_WIN + return 0.0; +#endif +} + + std::string getOperatingSystemInfo() { #if defined ARCH_LIN || defined ARCH_MAC struct utsname u;