diff --git a/IntelPresentMon/CommonUtilities/log/ChannelFlusher.cpp b/IntelPresentMon/CommonUtilities/log/ChannelFlusher.cpp index e95c275a..d2498aae 100644 --- a/IntelPresentMon/CommonUtilities/log/ChannelFlusher.cpp +++ b/IntelPresentMon/CommonUtilities/log/ChannelFlusher.cpp @@ -8,14 +8,46 @@ namespace pmon::util::log { using namespace std::literals; - ChannelFlusher::ChannelFlusher(std::weak_ptr pChan) + ChannelFlusher::ChannelFlusher(std::weak_ptr pChan, bool initiallyEnabled) : - pChan_{ std::move(pChan) } + pChan_{ std::move(pChan) }, + enabled_{ initiallyEnabled }, + stateChangeEvent_{ false, false } { worker_ = mt::Thread{ "log-flush", [this] { try { - while (!win::WaitAnyEventFor(500ms, exitEvent_)) { - pChan_.lock()->Flush(); + auto flush = [this] { + if (auto pChan = pChan_.lock()) { + pChan->Flush(); + return true; + } + return false; + }; + while (true) { + if (!enabled_.load(std::memory_order_acquire)) { + if (flushBeforeSuspend_.exchange(false, std::memory_order_acq_rel)) { + if (!flush()) { + return; + } + } + if (win::WaitAnyEvent(exitEvent_, stateChangeEvent_) == 0) { + return; + } + continue; + } + + if (auto waitResult = win::WaitAnyEventFor(500ms, exitEvent_, stateChangeEvent_)) { + if (*waitResult == 0) { + return; + } + continue; + } + + if (enabled_.load(std::memory_order_acquire)) { + if (!flush()) { + return; + } + } } } catch (...) { @@ -27,4 +59,14 @@ namespace pmon::util::log { pmquell(exitEvent_.Set()); } -} \ No newline at end of file + void ChannelFlusher::SetEnabled(bool enabled) + { + const auto wasEnabled = enabled_.exchange(enabled, std::memory_order_acq_rel); + if (wasEnabled != enabled) { + if (!enabled) { + flushBeforeSuspend_.store(true, std::memory_order_release); + } + stateChangeEvent_.Set(); + } + } +} diff --git a/IntelPresentMon/CommonUtilities/log/ChannelFlusher.h b/IntelPresentMon/CommonUtilities/log/ChannelFlusher.h index 7f28f556..874decd0 100644 --- a/IntelPresentMon/CommonUtilities/log/ChannelFlusher.h +++ b/IntelPresentMon/CommonUtilities/log/ChannelFlusher.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "../mt/Thread.h" #include "../win/Event.h" #include "IChannelObject.h" @@ -11,7 +12,7 @@ namespace pmon::util::log class ChannelFlusher : public IChannelObject { public: - ChannelFlusher(std::weak_ptr pChan); + ChannelFlusher(std::weak_ptr pChan, bool initiallyEnabled = true); ~ChannelFlusher(); ChannelFlusher(const ChannelFlusher&) = delete; @@ -19,10 +20,14 @@ namespace pmon::util::log ChannelFlusher(ChannelFlusher&&) = delete; ChannelFlusher & operator=(ChannelFlusher&&) = delete; + void SetEnabled(bool enabled); + private: std::weak_ptr pChan_; + std::atomic enabled_; + std::atomic flushBeforeSuspend_ = false; mt::Thread worker_; win::Event exitEvent_; + win::Event stateChangeEvent_; }; } - diff --git a/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp b/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp index 9b82758c..a04ff45f 100644 --- a/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp +++ b/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp @@ -2,6 +2,7 @@ #include #include #include "../Interprocess/source/act/ActionHelper.h" +#include "LogSetup.h" #include #include @@ -24,6 +25,7 @@ namespace pmon::svc::acts // tracked pids cleanup stx.trackedPids.clear(); pPmon->UpdateTracking(GetTrackedPidSet()); + UpdatePeriodicLogFlushing(); // telemetry period cleanup stx.requestedTelemetryPeriodMs.reset(); UpdateTelemetryPeriod(); @@ -71,6 +73,21 @@ namespace pmon::svc::acts } } pPmon->SetDeviceMetricUsage(std::move(deviceMetricUsage)); + UpdatePeriodicLogFlushing(); + } + void ActionExecutionContext::UpdatePeriodicLogFlushing() const + { + bool active = false; + if (pSessionMap != nullptr) { + for (const auto& sessionEntry : *pSessionMap) { + const auto& session = sessionEntry.second; + if (!session.trackedPids.empty() || !session.metricUsage.empty()) { + active = true; + break; + } + } + } + logsetup::SetPeriodicLogFlushingEnabled(active); } std::unordered_set ActionExecutionContext::GetTrackedPidSet() const diff --git a/IntelPresentMon/PresentMonService/ActionExecutionContext.h b/IntelPresentMon/PresentMonService/ActionExecutionContext.h index b0fd405d..61839594 100644 --- a/IntelPresentMon/PresentMonService/ActionExecutionContext.h +++ b/IntelPresentMon/PresentMonService/ActionExecutionContext.h @@ -68,6 +68,7 @@ namespace pmon::svc::acts void UpdateTelemetryPeriod() const; void UpdateEtwFlushPeriod() const; void UpdateMetricUsage() const; + void UpdatePeriodicLogFlushing() const; std::unordered_set GetTrackedPidSet() const; void ReleaseBackpressure(uint32_t pid) const; }; diff --git a/IntelPresentMon/PresentMonService/LogSetup.cpp b/IntelPresentMon/PresentMonService/LogSetup.cpp index 7f0fd92c..1566ba0a 100644 --- a/IntelPresentMon/PresentMonService/LogSetup.cpp +++ b/IntelPresentMon/PresentMonService/LogSetup.cpp @@ -47,7 +47,7 @@ namespace pmon::util::log pChannel->AttachComponent(std::make_shared(pFormatter), "drv:dbg"); pChannel->AttachComponent(std::make_shared(pFormatter), "drv:std"); // flusher - pChannel->AttachComponent(std::make_shared(pChannel), "obj:fsh"); + pChannel->AttachComponent(std::make_shared(pChannel, false), "obj:fsh"); return pChannel; } @@ -130,6 +130,21 @@ namespace logsetup pmlog_panic_("Failed configuring log in server"); } } + void SetPeriodicLogFlushingEnabled(bool enabled) noexcept + { + try { + if (auto pChannel = GetDefaultChannel()) { + if (auto pComponent = pChannel->GetComponent("obj:fsh")) { + if (auto pFlusher = std::dynamic_pointer_cast(pComponent)) { + pFlusher->SetEnabled(enabled); + } + } + } + } + catch (...) { + pmlog_panic_("Failed setting periodic log flushing state in server"); + } + } LogChannelManager::LogChannelManager() noexcept { diff --git a/IntelPresentMon/PresentMonService/LogSetup.h b/IntelPresentMon/PresentMonService/LogSetup.h index 9ef973b1..054604a6 100644 --- a/IntelPresentMon/PresentMonService/LogSetup.h +++ b/IntelPresentMon/PresentMonService/LogSetup.h @@ -14,4 +14,5 @@ namespace logsetup }; // call after command line arguments have been parsed void ConfigureLogging(bool asApp) noexcept; -} \ No newline at end of file + void SetPeriodicLogFlushingEnabled(bool enabled) noexcept; +} diff --git a/IntelPresentMon/PresentMonService/acts/StartTracking.h b/IntelPresentMon/PresentMonService/acts/StartTracking.h index 628431f6..4f0f7538 100644 --- a/IntelPresentMon/PresentMonService/acts/StartTracking.h +++ b/IntelPresentMon/PresentMonService/acts/StartTracking.h @@ -98,6 +98,7 @@ namespace pmon::svc::acts } target.pSegment = std::move(pSegment); stx.trackedPids.emplace(in.targetPid, std::move(target)); + ctx.UpdatePeriodicLogFlushing(); pmlog_info(std::format("StartTracking action from [{}] targeting [{}]", stx.remotePid, in.targetPid)); return {}; diff --git a/IntelPresentMon/PresentMonService/acts/StopTracking.h b/IntelPresentMon/PresentMonService/acts/StopTracking.h index 5d53cf34..3b4d393c 100644 --- a/IntelPresentMon/PresentMonService/acts/StopTracking.h +++ b/IntelPresentMon/PresentMonService/acts/StopTracking.h @@ -40,6 +40,7 @@ namespace pmon::svc::acts } stx.trackedPids.erase(tpidIt); ctx.pPmon->UpdateTracking(ctx.GetTrackedPidSet()); + ctx.UpdatePeriodicLogFlushing(); pmlog_info(std::format("StopTracking action from [{}] un-targeting [{}]", stx.remotePid, in.targetPid)); return {}; }