Extend Perfetto Tracing

Add Tracing for SVCs, Services, NVDRV, and Synchronization Primitives. In addition, fix `TRACE_EVENT_END("guest")` being emitted when a signal is received while being in the guest rather than host which would cause an exception. This commit also disables warnings for the Perfetto library as we do not control fixing them.
This commit is contained in:
PixelyIon 2021-03-20 22:22:08 +05:30
parent c452cd2bf2
commit b0e53d4aad
20 changed files with 100 additions and 53 deletions

View File

@ -171,7 +171,7 @@
</inspection_tool> </inspection_tool>
<inspection_tool class="CheckedExceptionClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CheckedExceptionClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ClangTidy" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="ClangTidy" enabled="true" level="WARNING" enabled_by_default="true">
<option name="clangTidyChecks" value="-*,bugprone-argument-comment,bugprone-assert-side-effect,bugprone-bad-signal-to-kill-thread,bugprone-branch-clone,bugprone-copy-constructor-init,bugprone-dangling-handle,bugprone-dynamic-static-initializers,bugprone-fold-init-type,bugprone-forward-declaration-namespace,bugprone-forwarding-reference-overload,bugprone-inaccurate-erase,bugprone-incorrect-roundings,bugprone-integer-division,bugprone-lambda-function-name,bugprone-macro-parentheses,bugprone-macro-repeated-side-effects,bugprone-misplaced-operator-in-strlen-in-alloc,bugprone-misplaced-pointer-arithmetic-in-alloc,bugprone-misplaced-widening-cast,bugprone-move-forwarding-reference,bugprone-multiple-statement-macro,bugprone-no-escape,bugprone-not-null-terminated-result,bugprone-parent-virtual-call,bugprone-posix-return,bugprone-reserved-identifier,bugprone-sizeof-container,bugprone-sizeof-expression,bugprone-spuriously-wake-up-functions,bugprone-string-constructor,bugprone-string-integer-assignment,bugprone-string-literal-with-embedded-nul,bugprone-suspicious-enum-usage,bugprone-suspicious-include,bugprone-suspicious-memset-usage,bugprone-suspicious-missing-comma,bugprone-suspicious-semicolon,bugprone-suspicious-string-compare,bugprone-swapped-arguments,bugprone-terminating-continue,bugprone-throw-keyword-missing,bugprone-too-small-loop-variable,bugprone-undefined-memory-manipulation,bugprone-undelegated-constructor,bugprone-unhandled-self-assignment,bugprone-unused-raii,bugprone-unused-return-value,bugprone-use-after-move,bugprone-virtual-near-miss,cert-dcl21-cpp,cert-dcl58-cpp,cert-err34-c,cert-err58-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cert-str34-c,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-static-cast-downcast,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,misc-misplaced-const,misc-new-delete-overloads,misc-no-recursion,misc-non-copyable-objects,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,readability-avoid-const-params-in-decls,readability-const-return-type,readability-container-size-empty,readability-convert-member-functions-to-static,readability-delete-null-pointer,readability-deleted-default,readability-inconsistent-declaration-parameter-name,readability-make-member-function-const,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-use-anyofallof" /> <option name="clangTidyChecks" value="-*,bugprone-argument-comment,bugprone-assert-side-effect,bugprone-bad-signal-to-kill-thread,bugprone-branch-clone,bugprone-copy-constructor-init,bugprone-dangling-handle,bugprone-dynamic-static-initializers,bugprone-fold-init-type,bugprone-forward-declaration-namespace,bugprone-forwarding-reference-overload,bugprone-inaccurate-erase,bugprone-incorrect-roundings,bugprone-integer-division,bugprone-lambda-function-name,bugprone-macro-parentheses,bugprone-macro-repeated-side-effects,bugprone-misplaced-operator-in-strlen-in-alloc,bugprone-misplaced-pointer-arithmetic-in-alloc,bugprone-misplaced-widening-cast,bugprone-move-forwarding-reference,bugprone-multiple-statement-macro,bugprone-no-escape,bugprone-not-null-terminated-result,bugprone-parent-virtual-call,bugprone-posix-return,bugprone-reserved-identifier,bugprone-sizeof-container,bugprone-sizeof-expression,bugprone-spuriously-wake-up-functions,bugprone-string-constructor,bugprone-string-integer-assignment,bugprone-string-literal-with-embedded-nul,bugprone-suspicious-enum-usage,bugprone-suspicious-include,bugprone-suspicious-memset-usage,bugprone-suspicious-missing-comma,bugprone-suspicious-semicolon,bugprone-suspicious-string-compare,bugprone-swapped-arguments,bugprone-terminating-continue,bugprone-throw-keyword-missing,bugprone-too-small-loop-variable,bugprone-undefined-memory-manipulation,bugprone-undelegated-constructor,bugprone-unhandled-self-assignment,bugprone-unused-raii,bugprone-unused-return-value,bugprone-use-after-move,bugprone-virtual-near-miss,cert-dcl21-cpp,cert-dcl58-cpp,cert-err34-c,cert-err52-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cert-str34-c,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-static-cast-downcast,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,misc-misplaced-const,misc-new-delete-overloads,misc-no-recursion,misc-non-copyable-objects,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,readability-avoid-const-params-in-decls,readability-const-return-type,readability-container-size-empty,readability-convert-member-functions-to-static,readability-delete-null-pointer,readability-deleted-default,readability-inconsistent-declaration-parameter-name,readability-make-member-function-const,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-use-anyofallof" />
</inspection_tool> </inspection_tool>
<inspection_tool class="ClassComplexity" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="ClassComplexity" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_limit" value="80" /> <option name="m_limit" value="80" />

View File

@ -6,6 +6,7 @@
<mapping directory="$PROJECT_DIR$/app/libraries/frozen" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/libraries/frozen" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/lz4" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/libraries/lz4" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/oboe" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/libraries/oboe" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/perfetto" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/pugixml" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/libraries/pugixml" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/vkhpp" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/libraries/vkhpp" vcs="Git" />
</component> </component>

View File

@ -32,9 +32,10 @@ include_directories("libraries/frozen/include")
find_package(mbedtls REQUIRED CONFIG) find_package(mbedtls REQUIRED CONFIG)
# Define a static library for Perfetto. # Perfetto SDK
include_directories(libraries/perfetto/sdk) include_directories(libraries/perfetto/sdk)
add_library(perfetto STATIC libraries/perfetto/sdk/perfetto.cc) add_library(perfetto STATIC libraries/perfetto/sdk/perfetto.cc)
target_compile_options(perfetto PRIVATE -Wno-everything)
include_directories(${source_DIR}/skyline) include_directories(${source_DIR}/skyline)
@ -45,7 +46,7 @@ add_library(skyline SHARED
${source_DIR}/skyline/common/settings.cpp ${source_DIR}/skyline/common/settings.cpp
${source_DIR}/skyline/common/signal.cpp ${source_DIR}/skyline/common/signal.cpp
${source_DIR}/skyline/common/uuid.cpp ${source_DIR}/skyline/common/uuid.cpp
${source_DIR}/skyline/common/tracing.cpp ${source_DIR}/skyline/common/trace.cpp
${source_DIR}/skyline/nce/guest.S ${source_DIR}/skyline/nce/guest.S
${source_DIR}/skyline/nce.cpp ${source_DIR}/skyline/nce.cpp
${source_DIR}/skyline/jvm.cpp ${source_DIR}/skyline/jvm.cpp

View File

@ -10,7 +10,7 @@
#include "skyline/common.h" #include "skyline/common.h"
#include "skyline/common/signal.h" #include "skyline/common/signal.h"
#include "skyline/common/settings.h" #include "skyline/common/settings.h"
#include "skyline/common/tracing.h" #include "skyline/common/trace.h"
#include "skyline/loader/loader.h" #include "skyline/loader/loader.h"
#include "skyline/vfs/android_asset_filesystem.h" #include "skyline/vfs/android_asset_filesystem.h"
#include "skyline/os.h" #include "skyline/os.h"
@ -80,14 +80,14 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
env->ReleaseStringUTFChars(appFilesPathJstring, appFilesPath); env->ReleaseStringUTFChars(appFilesPathJstring, appFilesPath);
auto romUri{env->GetStringUTFChars(romUriJstring, nullptr)}; auto romUri{env->GetStringUTFChars(romUriJstring, nullptr)};
logger->Info("Launching ROM {}", romUri); logger->InfoNoPrefix("Launching ROM {}", romUri);
env->ReleaseStringUTFChars(romUriJstring, romUri); env->ReleaseStringUTFChars(romUriJstring, romUri);
os->Execute(romFd, static_cast<skyline::loader::RomFormat>(romType)); os->Execute(romFd, static_cast<skyline::loader::RomFormat>(romType));
} catch (std::exception &e) { } catch (std::exception &e) {
logger->Error(e.what()); logger->Error("An exception has occurred: {}", e.what());
} catch (const skyline::signal::SignalException &e) { } catch (const skyline::signal::SignalException &e) {
logger->Error(e.what()); logger->Error("An exception has occurred: {}", e.what());
} catch (...) { } catch (...) {
logger->Error("An unknown exception has occurred"); logger->Error("An unknown exception has occurred");
} }
@ -96,10 +96,10 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
InputWeak.reset(); InputWeak.reset();
logger->Info("Emulation has ended"); logger->InfoNoPrefix("Emulation has ended");
auto end{std::chrono::steady_clock::now()}; auto end{std::chrono::steady_clock::now()};
logger->Info("Done in: {} ms", (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count())); logger->InfoNoPrefix("Done in: {} ms", (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
close(romFd); close(romFd);
} }

View File

@ -145,6 +145,14 @@ namespace skyline {
else else
return object; return object;
} }
/**
* @brief {fmt}::format but with FmtCast built into it
*/
template<typename S, typename... Args>
auto Format(S formatString, Args &&... args) {
return fmt::format(formatString, FmtCast(args)...);
}
} }
/** /**

View File

@ -0,0 +1,3 @@
#include "trace.h"
PERFETTO_TRACK_EVENT_STATIC_STORAGE(); //!< Expands into a structure with static storage for all track events

View File

@ -0,0 +1,26 @@
#pragma once
#include <limits>
#include <perfetto.h>
#include <common.h>
#define TRACE_EVENT_FMT(category, formatString, ...) TRACE_EVENT("kernel", nullptr, [&](perfetto::EventContext ctx) { \
ctx.event()->set_name(skyline::util::Format(formatString, __VA_ARGS__)); \
})
PERFETTO_DEFINE_CATEGORIES(
perfetto::Category("scheduler").SetDescription("Events from the HLE scheduler"),
perfetto::Category("kernel").SetDescription("Events from parts of the HLE kernel"),
perfetto::Category("guest").SetDescription("Events relating to guest code"),
perfetto::Category("gpu").SetDescription("Events from the emulated GPU"),
perfetto::Category("service").SetDescription("Events from the HLE sysmodule implementations")
);
namespace skyline::trace {
/**
* @brief Perfetto track IDs for custom tracks, counting down from U64 max to avoid conflicts
*/
enum class TrackIds : u64 {
Presentation = std::numeric_limits<u64>::max(),
};
}

View File

@ -1,3 +0,0 @@
#include "tracing.h"
PERFETTO_TRACK_EVENT_STATIC_STORAGE();

View File

@ -1,19 +0,0 @@
#pragma once
#include <limits>
#include <perfetto.h>
#include <common.h>
PERFETTO_DEFINE_CATEGORIES(perfetto::Category("sched").SetDescription("Events from the scheduler"),
perfetto::Category("kernel").SetDescription("Events from parts of the kernel"),
perfetto::Category("guest").SetDescription("Events relating to guest code"),
perfetto::Category("gpu").SetDescription("Events from the emulated GPU"));
namespace skyline::tracing {
/**
* @brief Perfetto track IDs for custom tracks, counting down from U64 max to avoid conflicts
*/
enum class TrackIds : u64 {
Presentation = std::numeric_limits<u64>::max()
};
}

View File

@ -9,7 +9,7 @@ extern skyline::u16 Fps;
extern skyline::u32 FrameTime; extern skyline::u32 FrameTime;
namespace skyline::gpu { namespace skyline::gpu {
PresentationEngine::PresentationEngine(const DeviceState &state) : state(state), vsyncEvent(std::make_shared<kernel::type::KEvent>(state, true)), bufferEvent(std::make_shared<kernel::type::KEvent>(state, true)), presentationTrack(static_cast<uint64_t>(tracing::TrackIds::Presentation), perfetto::ProcessTrack::Current()) { PresentationEngine::PresentationEngine(const DeviceState &state) : state(state), vsyncEvent(std::make_shared<kernel::type::KEvent>(state, true)), bufferEvent(std::make_shared<kernel::type::KEvent>(state, true)), presentationTrack(static_cast<uint64_t>(trace::TrackIds::Presentation), perfetto::ProcessTrack::Current()) {
auto desc{presentationTrack.Serialize()}; auto desc{presentationTrack.Serialize()};
desc.set_name("Presentation"); desc.set_name("Presentation");
perfetto::TrackEvent::SetTrackDescriptor(presentationTrack, desc); perfetto::TrackEvent::SetTrackDescriptor(presentationTrack, desc);

View File

@ -3,7 +3,7 @@
#pragma once #pragma once
#include <common/tracing.h> #include <common/trace.h>
#include <kernel/types/KEvent.h> #include <kernel/types/KEvent.h>
#include "texture.h" #include "texture.h"

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <common/tracing.h> #include <common/trace.h>
#include <android/native_window.h> #include <android/native_window.h>
#include <kernel/types/KProcess.h> #include <kernel/types/KProcess.h>
#include <unistd.h> #include <unistd.h>

View File

@ -3,7 +3,7 @@
#include <unistd.h> #include <unistd.h>
#include <common/signal.h> #include <common/signal.h>
#include <common/tracing.h> #include <common/trace.h>
#include "types/KThread.h" #include "types/KThread.h"
#include "scheduler.h" #include "scheduler.h"
@ -13,19 +13,18 @@ namespace skyline::kernel {
Scheduler::Scheduler(const DeviceState &state) : state(state) {} Scheduler::Scheduler(const DeviceState &state) : state(state) {}
void Scheduler::SignalHandler(int signal, siginfo *info, ucontext *ctx, void **tls) { void Scheduler::SignalHandler(int signal, siginfo *info, ucontext *ctx, void **tls) {
TRACE_EVENT_END("guest");
if (*tls) { if (*tls) {
TRACE_EVENT_END("guest");
const auto &state{*reinterpret_cast<nce::ThreadContext *>(*tls)->state}; const auto &state{*reinterpret_cast<nce::ThreadContext *>(*tls)->state};
if (signal == PreemptionSignal) if (signal == PreemptionSignal)
state.thread->isPreempted = false; state.thread->isPreempted = false;
state.scheduler->Rotate(false); state.scheduler->Rotate(false);
YieldPending = false; YieldPending = false;
state.scheduler->WaitSchedule(); state.scheduler->WaitSchedule();
TRACE_EVENT_BEGIN("guest", "Guest");
} else { } else {
YieldPending = true; YieldPending = true;
} }
TRACE_EVENT_BEGIN("guest", "Guest");
} }
Scheduler::CoreContext &Scheduler::GetOptimalCoreForThread(const std::shared_ptr<type::KThread> &thread) { Scheduler::CoreContext &Scheduler::GetOptimalCoreForThread(const std::shared_ptr<type::KThread> &thread) {
@ -154,7 +153,7 @@ namespace skyline::kernel {
return !core->queue.empty() && core->queue.front() == thread; return !core->queue.empty() && core->queue.front() == thread;
}}; }};
TRACE_EVENT("sched", "WaitSchedule"); TRACE_EVENT("scheduler", "WaitSchedule");
if (loadBalance && thread->affinityMask.count() > 1) { if (loadBalance && thread->affinityMask.count() > 1) {
std::chrono::milliseconds loadBalanceThreshold{PreemptiveTimeslice * 2}; //!< The amount of time that needs to pass unscheduled for a thread to attempt load balancing std::chrono::milliseconds loadBalanceThreshold{PreemptiveTimeslice * 2}; //!< The amount of time that needs to pass unscheduled for a thread to attempt load balancing
while (!thread->scheduleCondition.wait_for(lock, loadBalanceThreshold, wakeFunction)) { while (!thread->scheduleCondition.wait_for(lock, loadBalanceThreshold, wakeFunction)) {
@ -182,7 +181,7 @@ namespace skyline::kernel {
auto &thread{state.thread}; auto &thread{state.thread};
auto *core{&cores.at(thread->coreId)}; auto *core{&cores.at(thread->coreId)};
TRACE_EVENT("sched", "TimedWaitSchedule"); TRACE_EVENT("scheduler", "TimedWaitSchedule");
std::unique_lock lock(core->mutex); std::unique_lock lock(core->mutex);
if (thread->scheduleCondition.wait_for(lock, timeout, [&]() { if (thread->scheduleCondition.wait_for(lock, timeout, [&]() {
if (!thread->affinityMask.test(thread->coreId)) [[unlikely]] { if (!thread->affinityMask.test(thread->coreId)) [[unlikely]] {

View File

@ -3,7 +3,7 @@
#include <os.h> #include <os.h>
#include <kernel/types/KProcess.h> #include <kernel/types/KProcess.h>
#include <common/tracing.h> #include <common/trace.h>
#include <vfs/npdm.h> #include <vfs/npdm.h>
#include "results.h" #include "results.h"
#include "svc.h" #include "svc.h"
@ -287,11 +287,10 @@ namespace skyline::kernel::svc {
constexpr i64 yieldWithCoreMigration{-1}; constexpr i64 yieldWithCoreMigration{-1};
constexpr i64 yieldToAnyThread{-2}; constexpr i64 yieldToAnyThread{-2};
TRACE_EVENT("kernel", "SleepThread");
i64 in{static_cast<i64>(state.ctx->gpr.x0)}; i64 in{static_cast<i64>(state.ctx->gpr.x0)};
if (in > 0) { if (in > 0) {
state.logger->Debug("Sleeping for {}ns", in); state.logger->Debug("Sleeping for {}ns", in);
TRACE_EVENT("kernel", "SleepThread", "duration", in);
struct timespec spec{ struct timespec spec{
.tv_sec = static_cast<time_t>(in / 1000000000), .tv_sec = static_cast<time_t>(in / 1000000000),
@ -302,22 +301,30 @@ namespace skyline::kernel::svc {
nanosleep(&spec, nullptr); nanosleep(&spec, nullptr);
} else { } else {
switch (in) { switch (in) {
case yieldWithCoreMigration: case yieldWithCoreMigration: {
state.logger->Debug("Waking any appropriate parked threads and yielding"); state.logger->Debug("Waking any appropriate parked threads and yielding");
TRACE_EVENT("kernel", "YieldWithCoreMigration");
state.scheduler->WakeParkedThread(); state.scheduler->WakeParkedThread();
[[fallthrough]];
case yieldWithoutCoreMigration:
if (in == yieldWithoutCoreMigration)
state.logger->Debug("Cooperative yield");
state.scheduler->Rotate(); state.scheduler->Rotate();
state.scheduler->WaitSchedule(); state.scheduler->WaitSchedule();
break; break;
}
case yieldToAnyThread: case yieldWithoutCoreMigration: {
state.logger->Debug("Cooperative yield");
TRACE_EVENT("kernel", "YieldWithoutCoreMigration");
state.scheduler->Rotate();
state.scheduler->WaitSchedule();
break;
}
case yieldToAnyThread: {
state.logger->Debug("Parking current thread"); state.logger->Debug("Parking current thread");
TRACE_EVENT("kernel", "YieldToAnyThread");
state.scheduler->ParkThread(); state.scheduler->ParkThread();
state.scheduler->WaitSchedule(false); state.scheduler->WaitSchedule(false);
break; break;
}
default: default:
break; break;
@ -453,6 +460,7 @@ namespace skyline::kernel::svc {
void ClearEvent(const DeviceState &state) { void ClearEvent(const DeviceState &state) {
KHandle handle{state.ctx->gpr.w0}; KHandle handle{state.ctx->gpr.w0};
TRACE_EVENT_FMT("kernel", "ClearEvent 0x{:X}", handle);
try { try {
std::static_pointer_cast<type::KEvent>(state.process->GetHandle(handle))->ResetSignal(); std::static_pointer_cast<type::KEvent>(state.process->GetHandle(handle))->ResetSignal();
state.logger->Debug("Clearing 0x{:X}", handle); state.logger->Debug("Clearing 0x{:X}", handle);
@ -543,6 +551,7 @@ namespace skyline::kernel::svc {
void ResetSignal(const DeviceState &state) { void ResetSignal(const DeviceState &state) {
KHandle handle{state.ctx->gpr.w0}; KHandle handle{state.ctx->gpr.w0};
TRACE_EVENT_FMT("kernel", "ResetSignal 0x{:X}", handle);
try { try {
auto object{state.process->GetHandle(handle)}; auto object{state.process->GetHandle(handle)};
switch (object->objectType) { switch (object->objectType) {
@ -601,11 +610,13 @@ namespace skyline::kernel::svc {
i64 timeout{static_cast<i64>(state.ctx->gpr.x3)}; i64 timeout{static_cast<i64>(state.ctx->gpr.x3)};
if (waitHandles.size() == 1) { if (waitHandles.size() == 1) {
state.logger->Debug("Waiting on 0x{:X} for {}ns", waitHandles[0], timeout); state.logger->Debug("Waiting on 0x{:X} for {}ns", waitHandles[0], timeout);
TRACE_EVENT_FMT("kernel", "WaitSynchronization 0x{:X}", waitHandles[0]);
} else if (Logger::LogLevel::Debug <= state.logger->configLevel) { } else if (Logger::LogLevel::Debug <= state.logger->configLevel) {
std::string handleString; std::string handleString;
for (const auto &handle : waitHandles) for (const auto &handle : waitHandles)
handleString += fmt::format("* 0x{:X}\n", handle); handleString += fmt::format("* 0x{:X}\n", handle);
state.logger->Debug("Waiting on handles:\n{}Timeout: {}ns", handleString, timeout); state.logger->Debug("Waiting on handles:\n{}Timeout: {}ns", handleString, timeout);
TRACE_EVENT("kernel", "WaitSynchronizationMultiple");
} }
std::unique_lock lock(type::KSyncObject::syncObjectMutex); std::unique_lock lock(type::KSyncObject::syncObjectMutex);
@ -707,6 +718,7 @@ namespace skyline::kernel::svc {
} }
state.logger->Debug("Locking 0x{:X}", mutex); state.logger->Debug("Locking 0x{:X}", mutex);
TRACE_EVENT_FMT("kernel", "MutexLock 0x{:X}", mutex);
KHandle ownerHandle{state.ctx->gpr.w0}; KHandle ownerHandle{state.ctx->gpr.w0};
KHandle requesterHandle{state.ctx->gpr.w2}; KHandle requesterHandle{state.ctx->gpr.w2};
@ -729,6 +741,8 @@ namespace skyline::kernel::svc {
return; return;
} }
TRACE_EVENT_FMT("kernel", "MutexUnlock 0x{:X}", mutex);
state.logger->Debug("Unlocking 0x{:X}", mutex); state.logger->Debug("Unlocking 0x{:X}", mutex);
state.process->MutexUnlock(mutex); state.process->MutexUnlock(mutex);
state.logger->Debug("Unlocked 0x{:X}", mutex); state.logger->Debug("Unlocked 0x{:X}", mutex);

View File

@ -3,8 +3,8 @@
#include <nce.h> #include <nce.h>
#include <os.h> #include <os.h>
#include <common/trace.h>
#include <kernel/results.h> #include <kernel/results.h>
#include "KProcess.h" #include "KProcess.h"
namespace skyline::kernel::type { namespace skyline::kernel::type {
@ -104,6 +104,8 @@ namespace skyline::kernel::type {
constexpr u32 HandleWaitersBit{1UL << 30}; //!< A bit which denotes if a mutex psuedo-handle has waiters or not constexpr u32 HandleWaitersBit{1UL << 30}; //!< A bit which denotes if a mutex psuedo-handle has waiters or not
Result KProcess::MutexLock(u32 *mutex, KHandle ownerHandle, KHandle tag) { Result KProcess::MutexLock(u32 *mutex, KHandle ownerHandle, KHandle tag) {
TRACE_EVENT_FMT("kernel", "MutexLock 0x{:X}", mutex);
std::shared_ptr<KThread> owner; std::shared_ptr<KThread> owner;
try { try {
owner = GetHandle<KThread>(ownerHandle); owner = GetHandle<KThread>(ownerHandle);
@ -142,6 +144,8 @@ namespace skyline::kernel::type {
} }
void KProcess::MutexUnlock(u32 *mutex) { void KProcess::MutexUnlock(u32 *mutex) {
TRACE_EVENT_FMT("kernel", "MutexUnlock 0x{:X}", mutex);
std::lock_guard lock(state.thread->waiterMutex); std::lock_guard lock(state.thread->waiterMutex);
auto &waiters{state.thread->waiters}; auto &waiters{state.thread->waiters};
auto nextOwnerIt{std::find_if(waiters.begin(), waiters.end(), [mutex](const std::shared_ptr<KThread> &thread) { return thread->waitKey == mutex; })}; auto nextOwnerIt{std::find_if(waiters.begin(), waiters.end(), [mutex](const std::shared_ptr<KThread> &thread) { return thread->waitKey == mutex; })};
@ -203,6 +207,8 @@ namespace skyline::kernel::type {
} }
Result KProcess::ConditionalVariableWait(u32 *key, u32 *mutex, KHandle tag, i64 timeout) { Result KProcess::ConditionalVariableWait(u32 *key, u32 *mutex, KHandle tag, i64 timeout) {
TRACE_EVENT_FMT("kernel", "ConditionalVariableWait 0x{:X} (0x{:X})", key, mutex);
{ {
std::lock_guard lock(syncWaiterMutex); std::lock_guard lock(syncWaiterMutex);
auto queue{syncWaiters.equal_range(key)}; auto queue{syncWaiters.equal_range(key)};
@ -242,6 +248,8 @@ namespace skyline::kernel::type {
} }
void KProcess::ConditionalVariableSignal(u32 *key, i32 amount) { void KProcess::ConditionalVariableSignal(u32 *key, i32 amount) {
TRACE_EVENT_FMT("kernel", "ConditionalVariableSignal 0x{:X}", key);
std::lock_guard lock(syncWaiterMutex); std::lock_guard lock(syncWaiterMutex);
auto queue{syncWaiters.equal_range(key)}; auto queue{syncWaiters.equal_range(key)};
@ -254,6 +262,8 @@ namespace skyline::kernel::type {
} }
Result KProcess::WaitForAddress(u32 *address, u32 value, i64 timeout, bool (*arbitrationFunction)(u32 *, u32)) { Result KProcess::WaitForAddress(u32 *address, u32 value, i64 timeout, bool (*arbitrationFunction)(u32 *, u32)) {
TRACE_EVENT_FMT("kernel", "WaitForAddress 0x{:X}", address);
{ {
std::lock_guard lock(syncWaiterMutex); std::lock_guard lock(syncWaiterMutex);
if (!arbitrationFunction(address, value)) [[unlikely]] if (!arbitrationFunction(address, value)) [[unlikely]]
@ -287,6 +297,8 @@ namespace skyline::kernel::type {
} }
Result KProcess::SignalToAddress(u32 *address, u32 value, i32 amount, bool(*mutateFunction)(u32 *address, u32 value, u32 waiterCount)) { Result KProcess::SignalToAddress(u32 *address, u32 value, i32 amount, bool(*mutateFunction)(u32 *address, u32 value, u32 waiterCount)) {
TRACE_EVENT_FMT("kernel", "SignalToAddress 0x{:X}", address);
std::lock_guard lock(syncWaiterMutex); std::lock_guard lock(syncWaiterMutex);
auto queue{syncWaiters.equal_range(address)}; auto queue{syncWaiters.equal_range(address)};

View File

@ -4,7 +4,7 @@
#include <cxxabi.h> #include <cxxabi.h>
#include <unistd.h> #include <unistd.h>
#include <common/signal.h> #include <common/signal.h>
#include <common/tracing.h> #include <common/trace.h>
#include <nce.h> #include <nce.h>
#include <os.h> #include <os.h>
#include "KProcess.h" #include "KProcess.h"

View File

@ -4,7 +4,7 @@
#include <cxxabi.h> #include <cxxabi.h>
#include <unistd.h> #include <unistd.h>
#include "common/signal.h" #include "common/signal.h"
#include "common/tracing.h" #include "common/trace.h"
#include "os.h" #include "os.h"
#include "jvm.h" #include "jvm.h"
#include "kernel/types/KProcess.h" #include "kernel/types/KProcess.h"
@ -21,6 +21,7 @@ namespace skyline::nce {
auto svc{kernel::svc::SvcTable[svcId]}; auto svc{kernel::svc::SvcTable[svcId]};
try { try {
if (svc) [[likely]] { if (svc) [[likely]] {
TRACE_EVENT("kernel", perfetto::StaticString{svc.name});
(svc.function)(state); (svc.function)(state);
} else [[unlikely]] { } else [[unlikely]] {
throw exception("Unimplemented SVC 0x{:X}", svcId); throw exception("Unimplemented SVC 0x{:X}", svcId);

View File

@ -2,6 +2,7 @@
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <cxxabi.h> #include <cxxabi.h>
#include <common/trace.h>
#include "base_service.h" #include "base_service.h"
namespace skyline::service { namespace skyline::service {
@ -27,6 +28,7 @@ namespace skyline::service {
state.logger->Warn("Cannot find function in service '{0}': 0x{1:X} ({1})", GetName(), static_cast<u32>(request.payload->value)); state.logger->Warn("Cannot find function in service '{0}': 0x{1:X} ({1})", GetName(), static_cast<u32>(request.payload->value));
return {}; return {};
} }
TRACE_EVENT("service", perfetto::StaticString{function.name});
try { try {
return function(session, request, response); return function(session, request, response);
} catch (const std::exception &e) { } catch (const std::exception &e) {

View File

@ -2,6 +2,7 @@
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <cxxabi.h> #include <cxxabi.h>
#include <common/trace.h>
#include "nvdevice.h" #include "nvdevice.h"
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
@ -38,6 +39,7 @@ namespace skyline::service::nvdrv::device {
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd); state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd);
return NvStatus::NotImplemented; return NvStatus::NotImplemented;
} }
TRACE_EVENT("service", perfetto::StaticString{function.name});
try { try {
return function(type, buffer, inlineBuffer); return function(type, buffer, inlineBuffer);
} catch (const std::exception &e) { } catch (const std::exception &e) {

View File

@ -2,7 +2,7 @@
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <kernel/types/KProcess.h> #include <kernel/types/KProcess.h>
#include <common/tracing.h> #include <common/trace.h>
#include "sm/IUserInterface.h" #include "sm/IUserInterface.h"
#include "settings/ISettingsServer.h" #include "settings/ISettingsServer.h"
#include "settings/ISystemSettingsServer.h" #include "settings/ISystemSettingsServer.h"