mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-23 02:19:19 +01:00
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:
parent
df3427a8c0
commit
ae68009f9b
@ -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" />
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)...);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
3
app/src/main/cpp/skyline/common/trace.cpp
Normal file
3
app/src/main/cpp/skyline/common/trace.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
PERFETTO_TRACK_EVENT_STATIC_STORAGE(); //!< Expands into a structure with static storage for all track events
|
26
app/src/main/cpp/skyline/common/trace.h
Normal file
26
app/src/main/cpp/skyline/common/trace.h
Normal 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(),
|
||||||
|
};
|
||||||
|
}
|
@ -1,3 +0,0 @@
|
|||||||
#include "tracing.h"
|
|
||||||
|
|
||||||
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
|
|
@ -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()
|
|
||||||
};
|
|
||||||
}
|
|
@ -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);
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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]] {
|
||||||
|
@ -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);
|
||||||
|
@ -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)};
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user