mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:37:36 +00:00
UserspaceEmulator+LibC: Add support for Region-of-Interest profiling
This commit is contained in:
parent
18b2484985
commit
64ccf2196c
6 changed files with 51 additions and 1 deletions
|
@ -30,6 +30,7 @@
|
||||||
extern bool g_dump_profile;
|
extern bool g_dump_profile;
|
||||||
extern unsigned g_profile_instruction_interval;
|
extern unsigned g_profile_instruction_interval;
|
||||||
extern Optional<OutputFileStream> g_profile_stream;
|
extern Optional<OutputFileStream> g_profile_stream;
|
||||||
|
extern bool g_in_region_of_interest;
|
||||||
|
|
||||||
namespace UserspaceEmulator {
|
namespace UserspaceEmulator {
|
||||||
|
|
||||||
|
@ -473,6 +474,8 @@ void Emulator::dump_backtrace()
|
||||||
|
|
||||||
void Emulator::emit_profile_sample(AK::OutputStream& output)
|
void Emulator::emit_profile_sample(AK::OutputStream& output)
|
||||||
{
|
{
|
||||||
|
if (!g_in_region_of_interest)
|
||||||
|
return;
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
timeval tv {};
|
timeval tv {};
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
|
|
25
Userland/DevTools/UserspaceEmulator/EmulatorControl.h
Normal file
25
Userland/DevTools/UserspaceEmulator/EmulatorControl.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Assertions.h>
|
||||||
|
#include <AK/StdLibExtras.h>
|
||||||
|
#include <serenity.h>
|
||||||
|
|
||||||
|
namespace UserspaceEmulator {
|
||||||
|
|
||||||
|
enum class Command {
|
||||||
|
MarkROIStart = 5,
|
||||||
|
MarkROIEnd = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void control(Command command)
|
||||||
|
{
|
||||||
|
emuctl(to_underlying(command), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
extern bool g_dump_profile;
|
extern bool g_dump_profile;
|
||||||
extern Optional<OutputFileStream> g_profile_stream;
|
extern Optional<OutputFileStream> g_profile_stream;
|
||||||
|
extern bool g_in_region_of_interest;
|
||||||
|
|
||||||
namespace UserspaceEmulator {
|
namespace UserspaceEmulator {
|
||||||
|
|
||||||
|
@ -1118,7 +1119,7 @@ int Emulator::virt$ioctl([[maybe_unused]] int fd, unsigned request, [[maybe_unus
|
||||||
int Emulator::virt$emuctl(FlatPtr arg1, FlatPtr arg2, FlatPtr arg3)
|
int Emulator::virt$emuctl(FlatPtr arg1, FlatPtr arg2, FlatPtr arg3)
|
||||||
{
|
{
|
||||||
auto* tracer = malloc_tracer();
|
auto* tracer = malloc_tracer();
|
||||||
if (!tracer)
|
if (arg1 <= 4 && !tracer)
|
||||||
return 0;
|
return 0;
|
||||||
switch (arg1) {
|
switch (arg1) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -1133,6 +1134,14 @@ int Emulator::virt$emuctl(FlatPtr arg1, FlatPtr arg2, FlatPtr arg3)
|
||||||
case 4:
|
case 4:
|
||||||
tracer->target_did_change_chunk_size({}, arg3, arg2);
|
tracer->target_did_change_chunk_size({}, arg3, arg2);
|
||||||
return 0;
|
return 0;
|
||||||
|
case 5: // mark ROI start
|
||||||
|
if (g_in_region_of_interest)
|
||||||
|
return -EINVAL;
|
||||||
|
g_in_region_of_interest = true;
|
||||||
|
return 0;
|
||||||
|
case 6: // mark ROI end
|
||||||
|
g_in_region_of_interest = false;
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
bool g_report_to_debug = false;
|
bool g_report_to_debug = false;
|
||||||
|
bool g_in_region_of_interest = true;
|
||||||
bool g_dump_profile = false;
|
bool g_dump_profile = false;
|
||||||
unsigned g_profile_instruction_interval = 0;
|
unsigned g_profile_instruction_interval = 0;
|
||||||
Optional<OutputFileStream> g_profile_stream;
|
Optional<OutputFileStream> g_profile_stream;
|
||||||
|
@ -28,6 +29,7 @@ int main(int argc, char** argv, char** env)
|
||||||
bool pause_on_startup { false };
|
bool pause_on_startup { false };
|
||||||
String profile_dump_path;
|
String profile_dump_path;
|
||||||
FILE* profile_output_file { nullptr };
|
FILE* profile_output_file { nullptr };
|
||||||
|
bool enable_roi_mode { false };
|
||||||
|
|
||||||
Core::ArgsParser parser;
|
Core::ArgsParser parser;
|
||||||
parser.set_stop_on_first_non_option(true);
|
parser.set_stop_on_first_non_option(true);
|
||||||
|
@ -36,6 +38,7 @@ int main(int argc, char** argv, char** env)
|
||||||
parser.add_option(g_dump_profile, "Generate a ProfileViewer-compatible profile", "profile", 0);
|
parser.add_option(g_dump_profile, "Generate a ProfileViewer-compatible profile", "profile", 0);
|
||||||
parser.add_option(g_profile_instruction_interval, "Set the profile instruction capture interval, 128 by default", "profile-interval", 'i', "#instructions");
|
parser.add_option(g_profile_instruction_interval, "Set the profile instruction capture interval, 128 by default", "profile-interval", 'i', "#instructions");
|
||||||
parser.add_option(profile_dump_path, "File path for profile dump", "profile-file", 0, "path");
|
parser.add_option(profile_dump_path, "File path for profile dump", "profile-file", 0, "path");
|
||||||
|
parser.add_option(enable_roi_mode, "Enable Region-of-Interest mode for profiling", "roi", 0);
|
||||||
|
|
||||||
parser.add_positional_argument(arguments, "Command to emulate", "command");
|
parser.add_positional_argument(arguments, "Command to emulate", "command");
|
||||||
|
|
||||||
|
@ -44,6 +47,9 @@ int main(int argc, char** argv, char** env)
|
||||||
if (g_dump_profile && g_profile_instruction_interval == 0)
|
if (g_dump_profile && g_profile_instruction_interval == 0)
|
||||||
g_profile_instruction_interval = 128;
|
g_profile_instruction_interval = 128;
|
||||||
|
|
||||||
|
if (enable_roi_mode)
|
||||||
|
g_in_region_of_interest = false;
|
||||||
|
|
||||||
String executable_path;
|
String executable_path;
|
||||||
if (arguments[0].contains("/"sv))
|
if (arguments[0].contains("/"sv))
|
||||||
executable_path = Core::File::real_path_for(arguments[0]);
|
executable_path = Core::File::real_path_for(arguments[0]);
|
||||||
|
|
|
@ -151,4 +151,9 @@ u16 internet_checksum(const void* ptr, size_t count)
|
||||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||||
return htons(~checksum);
|
return htons(~checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int emuctl(uintptr_t command, uintptr_t arg0, uintptr_t arg1)
|
||||||
|
{
|
||||||
|
return syscall(SC_emuctl, command, arg0, arg1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,4 +129,6 @@ int setkeymap(const char* name, const uint32_t* map, uint32_t* const shift_map,
|
||||||
|
|
||||||
uint16_t internet_checksum(const void* ptr, size_t count);
|
uint16_t internet_checksum(const void* ptr, size_t count);
|
||||||
|
|
||||||
|
int emuctl(uintptr_t command, uintptr_t arg0, uintptr_t arg1);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue