diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp index 85b0d84234..3be16183ed 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator.cpp @@ -30,6 +30,7 @@ extern bool g_dump_profile; extern unsigned g_profile_instruction_interval; extern Optional g_profile_stream; +extern bool g_in_region_of_interest; namespace UserspaceEmulator { @@ -473,6 +474,8 @@ void Emulator::dump_backtrace() void Emulator::emit_profile_sample(AK::OutputStream& output) { + if (!g_in_region_of_interest) + return; StringBuilder builder; timeval tv {}; gettimeofday(&tv, nullptr); diff --git a/Userland/DevTools/UserspaceEmulator/EmulatorControl.h b/Userland/DevTools/UserspaceEmulator/EmulatorControl.h new file mode 100644 index 0000000000..38f038707d --- /dev/null +++ b/Userland/DevTools/UserspaceEmulator/EmulatorControl.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace UserspaceEmulator { + +enum class Command { + MarkROIStart = 5, + MarkROIEnd = 6, +}; + +inline void control(Command command) +{ + emuctl(to_underlying(command), 0, 0); +} + +} diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp index 6c8f2b6064..e99082112d 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp @@ -30,6 +30,7 @@ extern bool g_dump_profile; extern Optional g_profile_stream; +extern bool g_in_region_of_interest; 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) { auto* tracer = malloc_tracer(); - if (!tracer) + if (arg1 <= 4 && !tracer) return 0; switch (arg1) { case 1: @@ -1133,6 +1134,14 @@ int Emulator::virt$emuctl(FlatPtr arg1, FlatPtr arg2, FlatPtr arg3) case 4: tracer->target_did_change_chunk_size({}, arg3, arg2); 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: return -EINVAL; } diff --git a/Userland/DevTools/UserspaceEmulator/main.cpp b/Userland/DevTools/UserspaceEmulator/main.cpp index 07d067c7d8..38f348c8a7 100644 --- a/Userland/DevTools/UserspaceEmulator/main.cpp +++ b/Userland/DevTools/UserspaceEmulator/main.cpp @@ -18,6 +18,7 @@ #include bool g_report_to_debug = false; +bool g_in_region_of_interest = true; bool g_dump_profile = false; unsigned g_profile_instruction_interval = 0; Optional g_profile_stream; @@ -28,6 +29,7 @@ int main(int argc, char** argv, char** env) bool pause_on_startup { false }; String profile_dump_path; FILE* profile_output_file { nullptr }; + bool enable_roi_mode { false }; Core::ArgsParser parser; 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_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(enable_roi_mode, "Enable Region-of-Interest mode for profiling", "roi", 0); 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) g_profile_instruction_interval = 128; + if (enable_roi_mode) + g_in_region_of_interest = false; + String executable_path; if (arguments[0].contains("/"sv)) executable_path = Core::File::real_path_for(arguments[0]); diff --git a/Userland/Libraries/LibC/serenity.cpp b/Userland/Libraries/LibC/serenity.cpp index 0f112ca0ae..7a8d8f69be 100644 --- a/Userland/Libraries/LibC/serenity.cpp +++ b/Userland/Libraries/LibC/serenity.cpp @@ -151,4 +151,9 @@ u16 internet_checksum(const void* ptr, size_t count) checksum = (checksum & 0xffff) + (checksum >> 16); return htons(~checksum); } + +int emuctl(uintptr_t command, uintptr_t arg0, uintptr_t arg1) +{ + return syscall(SC_emuctl, command, arg0, arg1); +} } diff --git a/Userland/Libraries/LibC/serenity.h b/Userland/Libraries/LibC/serenity.h index a844d866d3..649c0914eb 100644 --- a/Userland/Libraries/LibC/serenity.h +++ b/Userland/Libraries/LibC/serenity.h @@ -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); +int emuctl(uintptr_t command, uintptr_t arg0, uintptr_t arg1); + __END_DECLS