Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1e7a356
remove unused functionality from Core pm wrapper (offset)
planetchili Aug 14, 2024
d67d3be
Merge branch 'main' into feature/true-realtime
planetchili Aug 15, 2024
3615623
enabling etw settings in UI and marshalling to Kernel
planetchili Aug 15, 2024
47f218e
moving utilities out of Core and testing timing utils
planetchili Aug 16, 2024
dd5fc4d
replace pm sleep
planetchili Aug 16, 2024
2276e84
prep for coordinated present consumption
planetchili Aug 16, 2024
5ad04d6
fix race condition
planetchili Aug 16, 2024
f0d8499
removing unnecessary lock-unlock sequence and reducing data race risk
planetchili Aug 16, 2024
2641332
flush events basic behavior
planetchili Aug 16, 2024
20dc1f7
verbose instrumentation of frame latency + fixing etw flush
planetchili Aug 18, 2024
ccab376
allow configuration of etw flush period and expose up to CAPI
planetchili Aug 18, 2024
14f1848
presentmon wrapper and appcef support for etw flush setting
planetchili Aug 18, 2024
453f47f
logger garbage data events for dynamic queries
planetchili Aug 20, 2024
113c777
adding additional manual flush logging and fix time unit mismatch
planetchili Aug 20, 2024
d2f2747
bump prefs version and add migration
planetchili Aug 25, 2024
cda1aa5
fix service cli flags
planetchili Aug 26, 2024
1c5e57b
ipc log connection for svc as child
planetchili Aug 26, 2024
a09bd18
detach pipe server threads and increase timeouts
planetchili Aug 27, 2024
428441d
controlling svc logpipe connection on appcef side
planetchili Aug 28, 2024
c0d646f
fix log pipe disconnection handling at service side
planetchili Aug 28, 2024
71f6994
setting non-colliding svc logpipe name by default
planetchili Aug 28, 2024
ca78481
downgrade flatline log message to dbg level
planetchili Aug 28, 2024
0cc8164
logging improvements
planetchili Aug 29, 2024
0acd0d1
remove extraneous constructs
planetchili Aug 29, 2024
ebc4b2b
fix the manual overlapped operation in DuplexPipe Accept logic
planetchili Aug 29, 2024
f0d0f6d
enabling log pipe connection to service
planetchili Aug 29, 2024
525c7a3
cleaning up asio build warnings
planetchili Aug 29, 2024
55e3207
simplifying / hardcoding ETW manual flush behavior / configuration
planetchili Aug 29, 2024
61bb0da
Merge branch 'main' into feature/true-realtime
planetchili Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions IntelPresentMon/AppCef/Web/src/core/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export interface Preferences {
metricPollRate: number;
overlayDrawRate: number;
telemetrySamplingPeriodMs: number;
etwFlushPeriod: number;
manualEtwFlush: boolean;
metricsOffset: number;
metricsWindow: number;
overlayPosition: OverlayPosition;
Expand Down Expand Up @@ -65,8 +67,10 @@ export function makeDefaultPreferences(): Preferences {
independentWindow: false,
metricPollRate: 40,
overlayDrawRate: 10,
telemetrySamplingPeriodMs: 100,
metricsOffset: 1020,
telemetrySamplingPeriodMs: 100,
etwFlushPeriod: 8,
manualEtwFlush: true,
metricsOffset: 32,
metricsWindow: 1000,
overlayPosition: 0,
timeRange: 10,
Expand Down Expand Up @@ -104,7 +108,7 @@ export function makeDefaultPreferences(): Preferences {

export const signature: Signature = {
code: "p2c-cap-pref",
version: "0.17.0",
version: "0.18.0",
};

export interface PreferenceFile {
Expand Down Expand Up @@ -138,6 +142,15 @@ const migrations: Migration[] = [
prefs.overlayDrawRate = drawRate;
}
},
{
version: '0.18.0',
migrate: (prefs: Preferences) => {
console.info('Migrating preferences to 0.18.0 (manualEtwFlush enable/rate)');
const def = makeDefaultPreferences();
prefs.manualEtwFlush = def.manualEtwFlush;
prefs.etwFlushPeriod = def.etwFlushPeriod;
}
},
];

migrations.sort((a, b) => compareVersions(a.version, b.version));
Expand Down
12 changes: 12 additions & 0 deletions IntelPresentMon/AppCef/Web/src/views/MetricProcessingView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ export default Vue.extend({
Preferences.writeAttribute({ attr: 'metricsWindow', val: metricsWindow });
},
},
etwFlushPeriod: {
get(): number { return Preferences.preferences.etwFlushPeriod; },
set(etwFlushPeriod: number) {
Preferences.writeAttribute({ attr: 'etwFlushPeriod', val: etwFlushPeriod });
},
},
manualEtwFlush: {
get(): boolean { return Preferences.preferences.manualEtwFlush; },
set(manualEtwFlush: boolean) {
Preferences.writeAttribute({ attr: 'manualEtwFlush', val: manualEtwFlush });
},
},
adapters(): Adapter[] {
return Adapters.adapters;
},
Expand Down
32 changes: 2 additions & 30 deletions IntelPresentMon/AppCef/source/NanoCefProcessHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
#include "SchemeHandlerFactory.h"
#include "DataBindAccessor.h"
#include <Core/source/infra/Logging.h>
#include <Core/source/infra/LogSetup.h>
#include "include/wrapper/cef_closure_task.h"
#include <include/cef_task.h>
#include "include/base/cef_callback.h"
#include "util/AsyncEndpointManager.h"
#include "util/CefValues.h"
#include <Core/source/cli/CliOptions.h>
#include <CommonUtilities/mt/Thread.h>
#include <CommonUtilities/log/NamedPipeMarshallReceiver.h>
#include <CommonUtilities/log/EntryMarshallInjector.h>
#include <include/cef_parser.h>

using namespace pmon::util;
Expand Down Expand Up @@ -94,33 +92,7 @@ namespace p2c::client::cef
std::string pipePrefix = std::format("p2c-logpipe-{}-{}", GetCurrentProcessId(), ++count);
pChildCommandLine->AppendSwitchWithValue(opt.logPipeName.GetName(), pipePrefix);
// launch connector thread
mt::Thread{ "logconn", count, [pipePrefix] {
try {
// wait maximum 1.5sec for pipe to be created
if (!pipe::DuplexPipe::WaitForAvailability(R"(\\.\pipe\)" + pipePrefix, 1500)) {
pmlog_warn(std::format("Failed to connect to logging source server {} after waiting 1.5s", pipePrefix));
return;
}
// retry connection maximum 3 times, every 16ms
const int nAttempts = 3;
for (int i = 0; i < nAttempts; i++) {
try {
auto pChan = log::GetDefaultChannel();
auto pReceiver = std::make_shared<log::NamedPipeMarshallReceiver>(pipePrefix, log::IdentificationTable::GetPtr());
auto pInjector = std::make_shared<log::EntryMarshallInjector>(pChan, std::move(pReceiver));
pChan->AttachComponent(std::move(pInjector));
return;
}
catch (const pipe::PipeError&) {
std::this_thread::sleep_for(16ms);
}
}
pmlog_warn(std::format("Failed to connect to logging source server {} after {} attempts", pipePrefix, nAttempts));
}
catch (...) {
pmlog_error(ReportException());
}
} }.detach();
ConnectToLoggingSourcePipe(pipePrefix, count);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: MIT
#include "AsyncEndpointManager.h"
#include <Core/source/infra/Logging.h>
#include <Core/source/infra/util/Util.h>
#include <algorithm>
#include "CefValues.h"
#include <include/cef_task.h>
Expand Down
2 changes: 2 additions & 0 deletions IntelPresentMon/AppCef/source/util/MakeOverlaySpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace p2c::client::util
.graphDataWindowSize = traversedPref["timeRange"],
.averagingWindowSize = traversedPref["metricsWindow"],
.metricsOffset = traversedPref["metricsOffset"],
.etwFlushPeriod = traversedPref["etwFlushPeriod"],
.manualEtwFlush = traversedPref["manualEtwFlush"],
.overlayPosition = (kern::OverlaySpec::OverlayPosition)traversedPref["overlayPosition"],
.overlayWidth = traversedPref["overlayWidth"],
.upscale = traversedPref["upscale"],
Expand Down
4 changes: 2 additions & 2 deletions IntelPresentMon/AppCef/source/util/async/GetTopGpuProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <ranges>
#include <Core/source/win/GpuUtilization.h>
#include <Core/source/win/ProcessMapBuilder.h>
#include <Core/source/infra/util/Util.h>
#include <CommonUtilities/str/String.h>

namespace p2c::client::util::async
{
Expand Down Expand Up @@ -40,7 +40,7 @@ namespace p2c::client::util::async
std::unordered_set<std::string> blacklistSet(blacklist.begin(), blacklist.end());
// remove candidate target processes that match blacklist (lower case compare)
std::erase_if(procList, [&](const win::Process& proc) {
auto narrowName = infra::util::ToNarrow(proc.name);
auto narrowName = ::pmon::util::str::ToNarrow(proc.name);
for (auto& c : narrowName) {
c = std::tolower(c);
}
Expand Down
11 changes: 10 additions & 1 deletion IntelPresentMon/AppCef/source/winmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,24 +232,33 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi

try {
// service-as-child handling
std::optional<std::string> logSvcPipe;
std::optional<boost::process::child> childSvc;
if (!opt.cefType && opt.svcAsChild) {
using namespace std::literals;
namespace bp = boost::process;

logSvcPipe = opt.logSvcPipe.AsOptional().value_or(
std::format("pm2-child-svc-log-{}", GetCurrentProcessId()));
childSvc.emplace("PresentMonService.exe"s,
"--control-pipe"s, *opt.controlPipe,
"--nsm-prefix"s, "pm-frame-nsm"s,
"--intro-nsm"s, *opt.shmName,
"--etw-session-name"s, *opt.etwSessionName,
"--log-level"s, std::to_string((int)log::GlobalPolicy::Get().GetLogLevel()));
"--log-level"s, std::to_string((int)log::GlobalPolicy::Get().GetLogLevel()),
"--log-pipe-name"s, *logSvcPipe);

if (!pmon::util::win::WaitForNamedPipe(*opt.controlPipe, 1500)) {
pmlog_error("timeout waiting for child service control pipe to go online");
return -1;
}
}

if (!opt.cefType && opt.logSvcPipeEnable) {
// connect to service's log pipe (best effort)
ConnectToLoggingSourcePipe(logSvcPipe.value_or(*opt.logSvcPipe), 0);
}

using namespace client;
// cef process constellation fork control
CefMainArgs main_args{ hInstance };
Expand Down
9 changes: 9 additions & 0 deletions IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<ClInclude Include="BuildId.h" />
<ClInclude Include="cli\CliFramework.h" />
<ClInclude Include="Exception.h" />
<ClInclude Include="IntervalWaiter.h" />
<ClInclude Include="log\ChannelFlusher.h" />
<ClInclude Include="log\CopyDriver.h" />
<ClInclude Include="log\DiagnosticDriver.h" />
Expand Down Expand Up @@ -75,6 +76,10 @@
<ClInclude Include="mt\Thread.h" />
<ClInclude Include="pipe\CoroMutex.h" />
<ClInclude Include="pipe\Pipe.h" />
<ClInclude Include="pipe\SecurityMode.h" />
<ClInclude Include="PrecisionWaiter.h" />
<ClInclude Include="Qpc.h" />
<ClInclude Include="rng\PairToRange.h" />
<ClInclude Include="str\String.h" />
<ClInclude Include="third\reflect.hpp" />
<ClInclude Include="win\Event.h" />
Expand All @@ -83,11 +88,13 @@
<ClInclude Include="win\Overlapped.h" />
<ClInclude Include="win\Utilities.h" />
<ClInclude Include="win\WinAPI.h" />
<ClInclude Include="pipe\WrapAsio.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BuildId.cpp" />
<ClCompile Include="cli\CliFramework.cpp" />
<ClCompile Include="Exception.cpp" />
<ClCompile Include="IntervalWaiter.cpp" />
<ClCompile Include="log\ChannelFlusher.cpp" />
<ClCompile Include="log\CopyDriver.cpp" />
<ClCompile Include="log\DiagnosticDriver.cpp" />
Expand Down Expand Up @@ -120,6 +127,8 @@
<ClCompile Include="mt\Thread.cpp" />
<ClCompile Include="pipe\CoroMutex.cpp" />
<ClCompile Include="pipe\Pipe.cpp" />
<ClCompile Include="PrecisionWaiter.cpp" />
<ClCompile Include="Qpc.cpp" />
<ClCompile Include="str\String.cpp" />
<ClCompile Include="win\Event.cpp" />
<ClCompile Include="win\Handle.cpp" />
Expand Down
27 changes: 27 additions & 0 deletions IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@
<ClInclude Include="BuildId.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PrecisionWaiter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Qpc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IntervalWaiter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="rng\PairToRange.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pipe\SecurityMode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pipe\WrapAsio.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cli\CliFramework.cpp">
Expand Down Expand Up @@ -329,6 +347,15 @@
<ClCompile Include="BuildId.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PrecisionWaiter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Qpc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IntervalWaiter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="vcpkg.json" />
Expand Down
16 changes: 12 additions & 4 deletions IntelPresentMon/CommonUtilities/Exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,32 @@ namespace pmon::util
}
}

std::string ReportException(std::exception_ptr pEx) noexcept
std::string ReportException(std::string note, std::exception_ptr pEx) noexcept
{
if (!pEx) {
pEx = std::current_exception();
}
const auto concat = [&](std::string what) {
if (!note.empty()) {
return note + "\n" + what;
}
else {
return what;
}
};
if (pEx) {
try {
std::rethrow_exception(pEx);
}
catch (const std::exception& e) {
try { return std::format("[{}] {}", typeid(e).name(), e.what()); }
try { return concat(std::format("[{}] {}", typeid(e).name(), e.what())); }
catch (...) { return {}; }
}
catch (...) {
return "Unrecognized exception";
return concat("Unrecognized exception");
}
}
return "No exception in flight";
return concat("No exception in flight");
}

PM_STATUS GeneratePmStatus(std::exception_ptr pEx) noexcept
Expand Down
2 changes: 1 addition & 1 deletion IntelPresentMon/CommonUtilities/Exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace pmon::util
return exception;
}

std::string ReportException(std::exception_ptr pEx = {}) noexcept;
std::string ReportException(std::string note = {}, std::exception_ptr pEx = {}) noexcept;

PM_STATUS GeneratePmStatus(std::exception_ptr pEx = {}) noexcept;

Expand Down
40 changes: 40 additions & 0 deletions IntelPresentMon/CommonUtilities/IntervalWaiter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "IntervalWaiter.h"
#include <thread>

namespace pmon::util
{
IntervalWaiter::IntervalWaiter(double intervalSeconds, double waitBuffer)
:
intervalSeconds_{ intervalSeconds },
waiter_{ waitBuffer }
{}

void IntervalWaiter::SetInterval(double intervalSeconds)
{
intervalSeconds_ = intervalSeconds;
}

void IntervalWaiter::SetInterval(std::chrono::nanoseconds interval)
{
intervalSeconds_ = double(interval.count()) / 1'000'000'000.;
}

void IntervalWaiter::Wait()
{
const auto waitTimeSeconds = [=, this] {
const auto t = timer_.Peek();
auto targetCandidate = lastTargetTime_ + intervalSeconds_;
// if we are on-time
if (t <= targetCandidate) {
lastTargetTime_ = targetCandidate;
return targetCandidate - t;
}
// if we are late, reset target to NOW and do not wait
lastTargetTime_ = t;
return 0.;
}();
if (waitTimeSeconds > 0.) {
waiter_.Wait(waitTimeSeconds);
}
}
}
28 changes: 28 additions & 0 deletions IntelPresentMon/CommonUtilities/IntervalWaiter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2022 Intel Corporation
// SPDX-License-Identifier: MIT
#pragma once
#include "Qpc.h"
#include "PrecisionWaiter.h"
#include <chrono>

namespace pmon::util
{
class IntervalWaiter
{
public:
IntervalWaiter(double intervalSeconds, double waitBuffer = PrecisionWaiter::standardWaitBuffer);
IntervalWaiter(const IntervalWaiter&) = delete;
IntervalWaiter & operator=(const IntervalWaiter&) = delete;
IntervalWaiter(IntervalWaiter&&) = delete;
IntervalWaiter & operator=(IntervalWaiter&&) = delete;
~IntervalWaiter() = default;
void SetInterval(double intervalSeconds);
void SetInterval(std::chrono::nanoseconds interval);
void Wait();
private:
double intervalSeconds_;
double lastTargetTime_ = 0.;
PrecisionWaiter waiter_;
QpcTimer timer_;
};
}
Loading