From de137b53ca0f2376a94eb5bbf0cfddef7605b911 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Fri, 28 Aug 2020 12:24:46 -0700 Subject: [PATCH] MeasureProcess: Remove use of background thread Previously, a background thread woke up to update the process list 250ms. This can be reduced to a function that caches the results and updates them if 250ms has elapsed since the last call. We also now store the process names lowercased in a std::unordered_set to avoid iterating over a std::vector. Both of these optimizations should reduce the amount of work done. --- Library/MeasureProcess.cpp | 108 ++++++++++++------------------------- Library/MeasureProcess.h | 16 +----- 2 files changed, 34 insertions(+), 90 deletions(-) diff --git a/Library/MeasureProcess.cpp b/Library/MeasureProcess.cpp index f8c4ebd2c..72caf1d98 100644 --- a/Library/MeasureProcess.cpp +++ b/Library/MeasureProcess.cpp @@ -9,99 +9,57 @@ #include "MeasureProcess.h" #include "ConfigParser.h" #include "Logger.h" -#include +#include "System.h" #include -std::vector MeasureProcess::c_Processes; -std::thread MeasureProcess::c_ProcessThread; -std::promise MeasureProcess::c_ProcessExitSignal; -std::future MeasureProcess::c_ProcessFuture; -std::mutex MeasureProcess::c_ProcessMutex; -UINT MeasureProcess::c_References = 0; -int MeasureProcess::c_UpdateInterval = 250; // milliseconds +std::unordered_set& GetRunningProcessLowercase() { + static std::unordered_set s_Processes; + static ULONGLONG s_LastUpdateTickCount = 0; + const ULONGLONG updateInterval = 250; // ms -MeasureProcess::MeasureProcess(Skin* skin, const WCHAR* name) : Measure(skin, name) -{ - if (c_References == 0) + ULONGLONG tickCount = System::GetTickCount64(); + if (tickCount >= (s_LastUpdateTickCount + updateInterval)) { - std::lock_guard lock(c_ProcessMutex); - c_ProcessExitSignal = std::promise(); - c_ProcessFuture = c_ProcessExitSignal.get_future(); - std::thread th(MeasureProcess::MonitorProcesses); - c_ProcessThread = std::move(th); - std::this_thread::sleep_for(std::chrono::milliseconds(25)); // Let the thread get an initial list of processes + s_LastUpdateTickCount = tickCount; + + s_Processes = {}; + HANDLE thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (thSnapshot != INVALID_HANDLE_VALUE) + { + PROCESSENTRY32 processEntry = { sizeof(processEntry) }; + if (Process32First(thSnapshot, &processEntry)) + { + do + { + std::wstring name = processEntry.szExeFile; + StringUtil::ToLowerCase(name); + s_Processes.insert(name); + } while (Process32Next(thSnapshot, &processEntry)); + } + CloseHandle(thSnapshot); + } } - ++c_References; + return s_Processes; } -MeasureProcess::~MeasureProcess() +MeasureProcess::MeasureProcess(Skin* skin, const WCHAR* name) : Measure(skin, name) { - --c_References; - if (c_References == 0) - { - std::lock_guard lock(c_ProcessMutex); - c_ProcessExitSignal.set_value(); - if (c_ProcessThread.joinable()) - { - c_ProcessThread.join(); - } +} - c_Processes.clear(); - } +MeasureProcess::~MeasureProcess() +{ } void MeasureProcess::ReadOptions(ConfigParser& parser, const WCHAR* section) { Measure::ReadOptions(parser, section); - m_ProcessName = parser.ReadString(section, L"ProcessName", L""); + m_ProcessNameLowercase = parser.ReadString(section, L"ProcessName", L""); + StringUtil::ToLowerCase(m_ProcessNameLowercase); } void MeasureProcess::UpdateValue() { - std::vector processes; - { - std::lock_guard lock(c_ProcessMutex); - processes = c_Processes; - } - - for (const auto& name : processes) - { - if (_wcsicmp(name.c_str(), m_ProcessName.c_str()) == 0) - { - m_Value = 1.0; - return; - } - } - - m_Value = -1.0; -} - -void MeasureProcess::MonitorProcesses() -{ - while (c_ProcessFuture.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) - { - { - std::lock_guard lock(c_ProcessMutex); - - c_Processes.clear(); - - HANDLE thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (thSnapshot != INVALID_HANDLE_VALUE) - { - PROCESSENTRY32 processEntry = { sizeof(processEntry) }; - if (Process32First(thSnapshot, &processEntry)) - { - do - { - c_Processes.emplace_back(processEntry.szExeFile); - } - while (Process32Next(thSnapshot, &processEntry)); - } - CloseHandle(thSnapshot); - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(c_UpdateInterval)); - } + m_Value = GetRunningProcessLowercase().count(m_ProcessNameLowercase) ? 1.0 : -1.0; } diff --git a/Library/MeasureProcess.h b/Library/MeasureProcess.h index a3e647a01..9866cee63 100644 --- a/Library/MeasureProcess.h +++ b/Library/MeasureProcess.h @@ -9,9 +9,6 @@ #define RM_LIBRARY_MEASUREPROCESS_H_ #include "Measure.h" -#include -#include -#include class MeasureProcess : public Measure { @@ -29,18 +26,7 @@ class MeasureProcess : public Measure void UpdateValue() override; private: - static void MonitorProcesses(); - - std::wstring m_ProcessName; - - static std::vector c_Processes; - static std::thread c_ProcessThread; - static std::promise c_ProcessExitSignal; - static std::future c_ProcessFuture; - static std::mutex c_ProcessMutex; - - static UINT c_References; - static int c_UpdateInterval; + std::wstring m_ProcessNameLowercase; }; #endif