Skip to content

Commit 176347c

Browse files
Merge branch 'main' into feature/pc-latency-diagnostics
2 parents e00d256 + 206e8de commit 176347c

File tree

88 files changed

+1495
-662
lines changed

Some content is hidden

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

88 files changed

+1495
-662
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
@@ -364,7 +380,7 @@ int main(int argc, const char** argv)
364380
}
365381

366382
auto pCallbackProcessor = std::make_unique<EventCallback>(!opt.outputFile,
367-
pFilter, (bool)opt.trimState, (bool)opt.event);
383+
pFilter, (bool)opt.trimState, (bool)opt.event, (bool)opt.listProcesses);
368384
if (auto hr = pRelogger->RegisterCallback(pCallbackProcessor.get()); FAILED(hr)) {
369385
std::cout << "Failed to register callback" << std::endl;
370386
}
@@ -398,8 +414,37 @@ int main(int argc, const char** argv)
398414
pCallbackProcessor->GetEventCount() - pCallbackProcessor->GetKeepCount());
399415
std::cout << std::format("Count of persisted events: {:L}\n", pCallbackProcessor->GetKeepCount());
400416

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

IntelPresentMon/AppCef/AppCef.rc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ IDI_ICON1 ICON "flask.ico"
6161
//
6262

6363
VS_VERSION_INFO VERSIONINFO
64-
FILEVERSION 1,0,3,0
65-
PRODUCTVERSION 2,3,0,0
64+
FILEVERSION 1,0,4,0
65+
PRODUCTVERSION 2,3,1,0
6666
FILEFLAGSMASK 0x3fL
6767
#ifdef _DEBUG
6868
FILEFLAGS 0x1L
@@ -79,12 +79,12 @@ BEGIN
7979
BEGIN
8080
VALUE "CompanyName", "Intel(R) Corporation"
8181
VALUE "FileDescription", "Intel(R) PresentMon application"
82-
VALUE "FileVersion", "1.0.3.0"
82+
VALUE "FileVersion", "1.0.4.0"
8383
VALUE "InternalName", "CefNano.exe"
84-
VALUE "LegalCopyright", "Copyright (C) 2017-2024"
84+
VALUE "LegalCopyright", "Copyright (C) 2017-2025"
8585
VALUE "OriginalFilename", "CefNano.exe"
8686
VALUE "ProductName", "Intel(R) PresentMon"
87-
VALUE "ProductVersion", "2.3.0.0"
87+
VALUE "ProductVersion", "2.3.1.0"
8888
END
8989
END
9090
BLOCK "VarFileInfo"

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
<ClCompile Include="Math.cpp">
390399
<Filter>Source Files</Filter>
391400
</ClCompile>

0 commit comments

Comments
 (0)