Skip to content

Commit 206e8de

Browse files
Merge pull request #475 from GameTechDev/feature/virt-pm-sesh
Feature/virt pm sesh
2 parents 9c2310b + 7313e86 commit 206e8de

File tree

68 files changed

+1368
-579
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1368
-579
lines changed

ETLTrimmer/CliOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace clio
1717
Flag provider{ this, "--provider,-p", "Enable pruning by provider (uses same provider set as PresentMon)" };
1818
Flag event{ this, "--event,-e", "Enable pruning by event (uses same event set as PresentMon)" };
1919
Flag trimState{ this, "--trim-state,-s", "Override default behavior that avoids discarding stateful events like process and DC start/stop when trimming by timestamp range" };
20+
Flag listProcesses{ this, "--list-processes", "Generate a report of all processes ranked by event count" };
2021
Option<std::pair<uint64_t, uint64_t>> trimRangeQpc{ this, "--trim-range-qpc", {}, "Range of QPC timestamps outside of which to trim", RemoveCommas };
2122
Option<std::pair<uint64_t, uint64_t>> trimRangeNs{ this, "--trim-range-ns", {}, "Range of nanosecond times outside of which to trim", RemoveCommas };
2223
Option<std::pair<double, double>> trimRangeMs{ this, "--trim-range-ms", {}, "Range of millisecond times outside of which to trim" };

ETLTrimmer/ETLTrimmer.args.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
"Id": "0f02ddbd-6110-43dd-982a-900bffd8549c",
77
"Command": "--input-file original.etl"
88
},
9+
{
10+
"Id": "f3106862-df2c-4138-802c-c0fd1bed132d",
11+
"Command": "--input-file hea-win.etl"
12+
},
913
{
1014
"Id": "ca527fdf-cf0c-4bc6-a5e5-362394a8487d",
1115
"Command": "--output-file output-trim-start.etl"
@@ -30,6 +34,10 @@
3034
"Id": "72aa3f3a-db72-48e5-93ec-11ef00ccf00e",
3135
"Command": "--trim-state"
3236
},
37+
{
38+
"Id": "57780d91-1c4e-41e3-be08-af75d87aa4f5",
39+
"Command": "--list-processes"
40+
},
3341
{
3442
"Id": "ee3aa6c6-1568-4347-8847-ad556ceedbdd",
3543
"Command": "--help"

ETLTrimmer/main.cpp

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <memory>
1515
#include <unordered_map>
1616
#include <unordered_set>
17+
#include <ranges>
1718
#include "CliOptions.h"
1819
#include "../PresentData/PresentMonTraceSession.hpp"
1920
#include "../PresentData/PresentMonTraceConsumer.hpp"
@@ -22,6 +23,9 @@
2223
#include "../PresentData/ETW/Microsoft_Windows_Kernel_Process.h"
2324
#include "../PresentData/ETW/Microsoft_Windows_DxgKrnl.h"
2425

26+
namespace rn = std::ranges;
27+
namespace vi = rn::views;
28+
2529
DEFINE_GUID(IID_ITraceRelogger, 0xF754AD43, 0x3BCC, 0x4286, 0x80, 0x09, 0x9C, 0x5D, 0xA2, 0x14, 0xE8, 0x4E); // {F754AD43-3BCC-4286-8009-9C5DA214E84E}
2630
DEFINE_GUID(IID_ITraceEventCallback, 0x3ED25501, 0x593F, 0x43E9, 0x8F, 0x38, 0x3A, 0xB4, 0x6F, 0x5A, 0x4A, 0x52); // {3ED25501-593F-43E9-8F38-3AB46F5A4A52}
2731

@@ -116,6 +120,7 @@ class EventCallback : public ITraceEventCallback
116120
DWORD ref_count_ = 0;
117121
// operation mode
118122
Mode mode_;
123+
bool listProcesses_ = false;
119124
// trim region
120125
std::optional<std::pair<uint64_t, uint64_t>> trimRangeQpc_;
121126
std::optional<std::pair<double, double>> trimRangeMs_;
@@ -129,14 +134,16 @@ class EventCallback : public ITraceEventCallback
129134
int keepCount_ = 0;
130135
std::optional<uint64_t> firstTimestamp_;
131136
uint64_t lastTimestamp_ = 0;
137+
std::unordered_map<uint32_t, uint64_t> eventCountByProcess_;
132138

133139
public:
134-
EventCallback(bool infoOnly, std::shared_ptr<Filter> pFilter, bool trimState, bool byId)
140+
EventCallback(bool infoOnly, std::shared_ptr<Filter> pFilter, bool trimState, bool byId, bool listProcesses)
135141
:
136142
mode_{ infoOnly ? Mode::Analysis : Mode::Trim },
137143
pFilter_{ std::move(pFilter) },
138144
trimState_{ trimState },
139-
byId_{ byId }
145+
byId_{ byId },
146+
listProcesses_{ listProcesses }
140147
{
141148
// when trimming by timestamp, we must take care not to remove the state data psuedo-events generated
142149
// at the beginning of the trace (also true state events coming before the trim region)
@@ -244,6 +251,9 @@ class EventCallback : public ITraceEventCallback
244251
if (mode_ == Mode::Trim) {
245252
pRelogger->Inject(pEvent);
246253
}
254+
if (listProcesses_) {
255+
eventCountByProcess_[hdr.ProcessId]++;
256+
}
247257
return S_OK;
248258
}
249259
HRESULT STDMETHODCALLTYPE OnFinalizeProcessTrace(ITraceRelogger* pRelogger)
@@ -270,6 +280,12 @@ class EventCallback : public ITraceEventCallback
270280
{
271281
return keepCount_;
272282
}
283+
auto GetProcessList() const
284+
{
285+
return eventCountByProcess_
286+
| vi::transform([](auto const& kv) {return std::pair{ kv.first, kv.second };})
287+
| rn::to<std::vector>();
288+
}
273289
};
274290

275291
class TempFile
@@ -362,7 +378,7 @@ int main(int argc, const char** argv)
362378
}
363379

364380
auto pCallbackProcessor = std::make_unique<EventCallback>(!opt.outputFile,
365-
pFilter, (bool)opt.trimState, (bool)opt.event);
381+
pFilter, (bool)opt.trimState, (bool)opt.event, (bool)opt.listProcesses);
366382
if (auto hr = pRelogger->RegisterCallback(pCallbackProcessor.get()); FAILED(hr)) {
367383
std::cout << "Failed to register callback" << std::endl;
368384
}
@@ -396,8 +412,37 @@ int main(int argc, const char** argv)
396412
pCallbackProcessor->GetEventCount() - pCallbackProcessor->GetKeepCount());
397413
std::cout << std::format("Count of persisted events: {:L}\n", pCallbackProcessor->GetKeepCount());
398414

415+
if (opt.listProcesses) {
416+
std::cout << "\n ======== Processes ========\n\n";
417+
auto procs = pCallbackProcessor->GetProcessList();
418+
std::erase_if(procs, [](auto& p) { return p.first == 0xFFFF'FFFF; });
419+
rn::sort(procs, std::greater{}, &decltype(procs)::value_type::second);
420+
421+
// figure out how wide each column must be (based on the values)
422+
size_t pidW = 0, cntW = 0;
423+
for (auto& [pid, cnt] : procs) {
424+
pidW = std::max(pidW, std::to_string(pid).size());
425+
cntW = std::max(cntW, std::to_string(cnt).size());
426+
}
427+
428+
// print header
429+
std::cout
430+
<< std::format("{:>{}} {:>{}}\n", "PID", pidW, "EVTs", cntW)
431+
<< std::string(pidW + 2 + cntW, '-') << "\n";
432+
433+
// print each row, right-aligned into those widths
434+
for (auto& [pid, cnt] : procs) {
435+
std::cout << std::format("{:>{}} {:>{}}\n",
436+
pid, pidW,
437+
cnt, cntW);
438+
}
439+
440+
std::cout << std::endl;
441+
}
442+
443+
399444
if (!opt.outputFile) {
400-
std::cout << "No output specified; running in analysis mode\n";
445+
std::cout << "No output specified; ran in analysis mode\n";
401446
}
402447
else {
403448
std::cout << "Output written to: " << *opt.outputFile << std::endl;

IntelPresentMon/AppCef/CefNano.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<ClInclude Include="source\util\cact\PresentmonInitFailedAction.h" />
4949
<ClInclude Include="source\util\cact\StalePidAction.h" />
5050
<ClInclude Include="source\util\cact\TargetLostAction.h" />
51+
<ClInclude Include="source\util\CefLog.h" />
5152
<ClInclude Include="source\util\CliOptions.h" />
5253
<ClInclude Include="source\util\IpcInvocationManager.h" />
5354
<ClInclude Include="source\util\AsyncEndpoint.h" />

IntelPresentMon/AppCef/source/NanoCefBrowserClient.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ namespace p2c::client::cef
3737
int line) override;
3838

3939
protected:
40-
// this semaphore protects from race condition between normal shutdown ack sequence and timeout fallback sequence
41-
std::binary_semaphore shutdownSemaphore{ 1 };
42-
// indicates whether ack was received from render process (or timeout fired)
43-
std::atomic<bool> shutdownAcknowledgementFlag = false;
44-
bool shutdownRequestFlag = false;
45-
4640
CefRefPtr<CefContextMenuHandler> pContextMenuHandler;
4741
CefRefPtr<CefBrowser> pBrowser;
4842
util::AsyncEndpointCollection endpoints;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
#include <include/internal/cef_types.h>
3+
#include "Logging.h"
4+
5+
constexpr cef_log_severity_t ToCefLogLevel(::pmon::util::log::Level level)
6+
{
7+
using ::pmon::util::log::Level;
8+
switch (level) {
9+
case Level::Verbose: return cef_log_severity_t::LOGSEVERITY_VERBOSE;
10+
case Level::Debug: // in CEF, debug and verbose are the same, so we use cef.info for debug
11+
case Level::Performance:
12+
case Level::Info: return cef_log_severity_t::LOGSEVERITY_INFO;
13+
case Level::Warning: return cef_log_severity_t::LOGSEVERITY_WARNING;
14+
case Level::Error: return cef_log_severity_t::LOGSEVERITY_ERROR;
15+
case Level::Fatal: return cef_log_severity_t::LOGSEVERITY_FATAL;
16+
default: return cef_log_severity_t::LOGSEVERITY_DEFAULT;
17+
}
18+
}

IntelPresentMon/AppCef/source/winmain.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <Shobjidl.h>
1616
#include <ShellScalingApi.h>
1717
#include <include/cef_version.h>
18+
#include "util/CefLog.h"
1819

1920

2021
#pragma comment(lib, "Dwmapi.lib")
@@ -72,14 +73,10 @@ LRESULT CALLBACK BrowserWindowWndProc(HWND window_handle, UINT message, WPARAM w
7273
&& (pBrowserClient->GetBrowser()))
7374
{
7475
CefWindowHandle hwnd(pBrowserClient->GetBrowser()->GetHost()->GetWindowHandle());
75-
if (hwnd)
76-
{
77-
RECT rect = { 0 };
76+
if (hwnd) {
77+
RECT rect{};
7878
GetClientRect(window_handle, &rect);
79-
HDWP hdwp = BeginDeferWindowPos(1);
80-
hdwp = DeferWindowPos(hdwp, hwnd, NULL, rect.left,
81-
rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
82-
EndDeferWindowPos(hdwp);
79+
SetWindowPos(hwnd, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
8380
}
8481
}
8582
break;
@@ -92,14 +89,12 @@ LRESULT CALLBACK BrowserWindowWndProc(HWND window_handle, UINT message, WPARAM w
9289
}
9390
break;
9491
case WM_ENTERMENULOOP:
95-
if (!w_param)
96-
{
92+
if (!w_param) {
9793
CefSetOSModalLoop(true);
9894
}
9995
break;
10096
case WM_EXITMENULOOP:
101-
if (!w_param)
102-
{
97+
if (!w_param) {
10398
CefSetOSModalLoop(false);
10499
}
105100
break;
@@ -112,8 +107,7 @@ LRESULT CALLBACK MessageWindowWndProc(HWND window_handle, UINT message, WPARAM w
112107
switch (message)
113108
{
114109
case WM_COMMAND:
115-
if (w_param == quitCefCode)
116-
{
110+
if (w_param == quitCefCode) {
117111
PostQuitMessage(0);
118112
}
119113
break;
@@ -129,7 +123,7 @@ HWND CreateBrowserWindow(HINSTANCE instance_handle, int show_minimize_or_maximiz
129123
wcex.lpfnWndProc = BrowserWindowWndProc;
130124
wcex.hInstance = instance_handle;
131125
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
132-
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
126+
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
133127
wcex.lpszClassName = BrowserWindowClassName;
134128
wcex.hIcon = static_cast<HICON>(LoadImage(
135129
instance_handle, MAKEINTRESOURCE(IDI_ICON1),
@@ -233,15 +227,15 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
233227
settings.multi_threaded_message_loop = true;
234228
settings.no_sandbox = true;
235229
settings.remote_debugging_port = is_debug || opt.enableChromiumDebug ? 9009 : 0;
236-
settings.background_color = { 0x000000 };
230+
settings.background_color = CefColorSetARGB(255, 0, 0, 0);
237231
CefString(&settings.cache_path).FromWString(folderResolver.Resolve(infra::util::FolderResolver::Folder::App, L"cef-cache"));
238232
if (opt.logFolder) {
239233
CefString(&settings.log_file).FromString(*opt.logFolder + "\\cef-debug.log");
240234
}
241235
else {
242236
CefString(&settings.log_file).FromWString(folderResolver.Resolve(infra::util::FolderResolver::Folder::App, L"logs\\cef-debug.log"));
243237
}
244-
settings.log_severity = is_debug ? cef_log_severity_t::LOGSEVERITY_DEFAULT : cef_log_severity_t::LOGSEVERITY_ERROR;
238+
settings.log_severity = ToCefLogLevel(util::log::GlobalPolicy::Get().GetLogLevel());
245239
CefInitialize(main_args, settings, app.get(), nullptr);
246240
}
247241
auto hwndBrowser = CreateBrowserWindow(hInstance, nCmdShow);

IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
<ClInclude Include="win\MessageBox.h" />
9595
<ClInclude Include="win\Overlapped.h" />
9696
<ClInclude Include="win\Privileges.h" />
97+
<ClInclude Include="win\Process.h" />
98+
<ClInclude Include="win\ProcessMapBuilder.h" />
9799
<ClInclude Include="win\Utilities.h" />
98100
<ClInclude Include="win\WinAPI.h" />
99101
</ItemGroup>
@@ -143,6 +145,7 @@
143145
<ClCompile Include="win\HrError.cpp" />
144146
<ClCompile Include="win\MessageBox.cpp" />
145147
<ClCompile Include="win\Privileges.cpp" />
148+
<ClCompile Include="win\ProcessMapBuilder.cpp" />
146149
<ClCompile Include="win\Utilities.cpp" />
147150
</ItemGroup>
148151
<ItemGroup>

IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj.filters

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,12 @@
246246
<ClInclude Include="win\Privileges.h">
247247
<Filter>Header Files</Filter>
248248
</ClInclude>
249+
<ClInclude Include="win\ProcessMapBuilder.h">
250+
<Filter>Header Files</Filter>
251+
</ClInclude>
252+
<ClInclude Include="win\Process.h">
253+
<Filter>Header Files</Filter>
254+
</ClInclude>
249255
</ItemGroup>
250256
<ItemGroup>
251257
<ClCompile Include="cli\CliFramework.cpp">
@@ -386,6 +392,9 @@
386392
<ClCompile Include="win\Privileges.cpp">
387393
<Filter>Source Files</Filter>
388394
</ClCompile>
395+
<ClCompile Include="win\ProcessMapBuilder.cpp">
396+
<Filter>Source Files</Filter>
397+
</ClCompile>
389398
</ItemGroup>
390399
<ItemGroup>
391400
<None Include="vcpkg.json" />

IntelPresentMon/CommonUtilities/Qpc.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
namespace pmon::util
88
{
9-
uint64_t GetCurrentTimestamp() noexcept
9+
int64_t GetCurrentTimestamp() noexcept
1010
{
1111
LARGE_INTEGER timestamp;
1212
if (!QueryPerformanceCounter(&timestamp)) {
1313
pmlog_error("qpc failed").hr().every(50);
1414
}
15-
return (uint64_t)timestamp.QuadPart;
15+
return (int64_t)timestamp.QuadPart;
1616
}
1717
double GetTimestampPeriodSeconds() noexcept
1818
{
@@ -22,13 +22,13 @@ namespace pmon::util
2222
}
2323
return 1.0 / double(freq.QuadPart);
2424
}
25-
void SpinWaitUntilTimestamp(uint64_t timestamp) noexcept
25+
void SpinWaitUntilTimestamp(int64_t timestamp) noexcept
2626
{
2727
while (GetCurrentTimestamp() < timestamp) {
2828
std::this_thread::yield();
2929
}
3030
}
31-
double TimestampDeltaToSeconds(uint64_t start, uint64_t end, double period) noexcept
31+
double TimestampDeltaToSeconds(int64_t start, int64_t end, double period) noexcept
3232
{
3333
return double(end - start) * period;
3434
}
@@ -52,7 +52,7 @@ namespace pmon::util
5252
const auto delta = TimestampDeltaToSeconds(startTimestamp_, newTimestamp, performanceCounterPeriod_);
5353
return delta;
5454
}
55-
uint64_t QpcTimer::GetStartTimestamp() const noexcept
55+
int64_t QpcTimer::GetStartTimestamp() const noexcept
5656
{
5757
return startTimestamp_;
5858
}

0 commit comments

Comments
 (0)