LibWebView+Browser: Collect memory and cpu usage for helpers on Serenity

This commit is contained in:
Andrew Kaster authored and Andreas Kling committed 2024-04-03 20:56:33 +02:00
1 parent d6c8218089
commit d1fdfead54
9 files changed
+152 -24

No files matched your search

@@ -146,4 +146,13 @@ shared_library("LibWebView") {
} else {
defines = [ "ENABLE_PUBLIC_SUFFIX=0" ]
}
if (current_os == "serenity") {
sources += [
"OutOfProcessWebView.cpp",
"Platform/ProcessStatisticsSerenity.cpp",
]
} else {
sources += [ "Platform/ProcessStatisticsNoop.cpp" ]
}
}
+1
View File
@@ -135,6 +135,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::unveil("/etc/passwd", "r"));
TRY(Core::System::unveil("/etc/timezone", "r"));
TRY(Core::System::unveil("/etc/FileIconProvider.ini", "r"));
TRY(Core::System::unveil("/sys/kernel/processes", "r"));
TRY(Core::System::unveil("/bin/BrowserSettings", "x"));
TRY(Core::System::unveil("/bin/Browser", "x"));
TRY(Core::System::unveil(nullptr, nullptr));
+8 -1
View File
@@ -23,7 +23,14 @@ set(SOURCES
set(GENERATED_SOURCES ${CURRENT_LIB_GENERATED})
if (SERENITYOS)
list(APPEND SOURCES OutOfProcessWebView.cpp)
list(APPEND SOURCES
OutOfProcessWebView.cpp
Platform/ProcessStatisticsSerenity.cpp
)
else()
list(APPEND SOURCES
Platform/ProcessStatisticsNoop.cpp
)
endif()
embed_as_string_view(
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024, Andrew Kaster <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
namespace WebView {
enum class ProcessType {
Chrome,
WebContent,
WebWorker,
SQLServer,
RequestServer,
ImageDecoder,
};
struct ProcessInfo {
ProcessType type;
pid_t pid;
u64 memory_usage_bytes = 0;
float cpu_percent = 0.0f;
u64 time_spent_in_process = 0;
};
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2024, Andrew Kaster <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Error.h>
#include <AK/Vector.h>
#include <LibWebView/Platform/ProcessInfo.h>
namespace WebView {
struct ProcessStatistics {
u64 total_time_scheduled = 0;
Vector<ProcessInfo> processes;
};
ErrorOr<void> update_process_statistics(ProcessStatistics&);
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2024, Andrew Kaster <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWebView/Platform/ProcessStatistics.h>
namespace WebView {
ErrorOr<void> update_process_statistics(ProcessStatistics&)
{
return {};
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024, Andrew Kaster <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Platform.h>
#if !defined(AK_OS_SERENITY)
# error "This file is for Serenity OS only"
#endif
#include <LibCore/File.h>
#include <LibCore/ProcessStatisticsReader.h>
#include <LibWebView/Platform/ProcessInfo.h>
#include <LibWebView/Platform/ProcessStatistics.h>
namespace WebView {
ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
{
static auto proc_all_file = TRY(Core::File::open("/sys/kernel/processes"sv, Core::File::OpenMode::Read));
auto const all_processes = TRY(Core::ProcessStatisticsReader::get_all(*proc_all_file, false));
auto const total_time_scheduled = all_processes.total_time_scheduled;
auto const total_time_scheduled_diff = total_time_scheduled - statistics.total_time_scheduled;
statistics.total_time_scheduled = total_time_scheduled;
for (auto& process : statistics.processes) {
auto it = all_processes.processes.find_if([&](auto& entry) { return entry.pid == process.pid; });
if (!it.is_end()) {
process.memory_usage_bytes = it->amount_resident;
u64 time_process = 0;
for (auto& thread : it->threads) {
time_process += thread.time_user + thread.time_kernel;
}
u64 time_scheduled_diff = time_process - process.time_spent_in_process;
process.time_spent_in_process = time_process;
process.cpu_percent = 0.0;
if (total_time_scheduled_diff > 0) {
process.cpu_percent = static_cast<float>((time_scheduled_diff * 1000) / total_time_scheduled_diff) / 10.0f;
}
} else {
process.memory_usage_bytes = 0;
process.cpu_percent = 0.0;
process.time_spent_in_process = 0;
}
}
return {};
}
}
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/NumberFormat.h>
#include <AK/String.h>
#include <LibCore/EventLoop.h>
#include <LibCore/System.h>
@@ -84,12 +85,12 @@ void ProcessManager::initialize()
void ProcessManager::add_process(ProcessType type, pid_t pid)
{
dbgln("ProcessManager::add_process({}, {})", process_name_from_type(type), pid);
m_processes.append({ type, pid, 0, 0 });
m_statistics.processes.append({ type, pid, 0, 0 });
}
void ProcessManager::remove_process(pid_t pid)
{
m_processes.remove_first_matching([&](auto& info) {
m_statistics.processes.remove_first_matching([&](auto& info) {
if (info.pid == pid) {
dbgln("ProcessManager: Remove process {} ({})", process_name_from_type(info.type), pid);
return true;
@@ -112,13 +113,13 @@ void ProcessManager::update_all_processes()
}
}
// FIXME: Actually gather stats in a platform-specific way
(void)update_process_statistics(m_statistics);
}
String ProcessManager::generate_html()
{
StringBuilder builder;
auto processes = m_processes;
auto processes = m_statistics.processes;
builder.append(R"(
<html>
@@ -163,7 +164,7 @@ String ProcessManager::generate_html()
builder.append(MUST(String::number(process.pid)));
builder.append("</td>"sv);
builder.append("<td>"sv);
builder.append(MUST(String::formatted("{} KB", process.memory_usage_kib)));
builder.append(human_readable_size(process.memory_usage_bytes));
builder.append("</td>"sv);
builder.append("<td>"sv);
builder.append(MUST(String::formatted("{:.1f}", process.cpu_percent)));
+3 -18
View File
@@ -8,27 +8,12 @@
#include <AK/Vector.h>
#include <LibCore/EventReceiver.h>
#include <LibWebView/Forward.h>
#include <LibWebView/Platform/ProcessStatistics.h>
#pragma once
namespace WebView {
enum class ProcessType {
Chrome,
WebContent,
WebWorker,
SQLServer,
RequestServer,
ImageDecoder,
};
struct ProcessInfo {
ProcessType type;
pid_t pid;
u64 memory_usage_kib = 0;
float cpu_percent = 0.0f;
};
ProcessType process_type_from_name(StringView);
StringView process_name_from_type(ProcessType type);
@@ -41,7 +26,7 @@ public:
void remove_process(pid_t);
void update_all_processes();
Vector<ProcessInfo> processes() const { return m_processes; }
Vector<ProcessInfo> processes() const { return m_statistics.processes; }
String generate_html();
@@ -49,7 +34,7 @@ private:
ProcessManager();
~ProcessManager();
Vector<ProcessInfo> m_processes;
ProcessStatistics m_statistics;
};
}