mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 07:45:37 +03:00
Use likelihood attributes in NCE + Fix System Version + SVC improvements
The SVCs improvements are as follows: * Make SVC logs more concise for: * * `SleepThread` * * `ClearEvent` * * `CloseHandle` * * `ResetSignal` * * `WaitSynchronization` (Special case for single handle) * * `ArbitrateLock` * * `ArbitrateUnlock` * * `WaitProcessWideKeyAtomic` * * `SignalProcessWideKey` * Fix unintentional fallthrough into `yieldWithoutCoreMigration` from `yieldWithCoreMigration` in `SleepThread` * Return `result::InvalidState` when an unsignalled handle is reset in `ResetSignal` * Return `Result{}` (Success) in `CancelSynchronization` * Do not return `result::InvalidCurrentMemory` in `ArbitrateLock` as it's not a failure condition * Make `count` in `WaitProcessWideKeyAtomic` a `i32` from a `u32`, zero and all negative values result in waking all waiters
This commit is contained in:
parent
1884d98163
commit
11c5f50d37
5
.idea/inspectionProfiles/Project_Default.xml
generated
5
.idea/inspectionProfiles/Project_Default.xml
generated
@ -171,10 +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-err52-cpp,cert-err58-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,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" />
|
<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-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-member-init,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-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 class="ClangTidyInspection" enabled="false" level="WARNING" enabled_by_default="false">
|
|
||||||
<option name="useCustomListOfClangTidyChecks" value="false" />
|
|
||||||
</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" />
|
||||||
|
@ -288,7 +288,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
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("svcSleepThread: Thread sleeping for {} ns", in);
|
state.logger->Debug("svcSleepThread: Sleeping for {}ns", in);
|
||||||
|
|
||||||
struct timespec spec{
|
struct timespec spec{
|
||||||
.tv_sec = static_cast<time_t>(in / 1000000000),
|
.tv_sec = static_cast<time_t>(in / 1000000000),
|
||||||
@ -302,6 +302,8 @@ namespace skyline::kernel::svc {
|
|||||||
case yieldWithCoreMigration:
|
case yieldWithCoreMigration:
|
||||||
state.logger->Debug("svcSleepThread: Waking any appropriate parked threads");
|
state.logger->Debug("svcSleepThread: Waking any appropriate parked threads");
|
||||||
state.scheduler->WakeParkedThread();
|
state.scheduler->WakeParkedThread();
|
||||||
|
break;
|
||||||
|
|
||||||
case yieldWithoutCoreMigration:
|
case yieldWithoutCoreMigration:
|
||||||
state.logger->Debug("svcSleepThread: Cooperative Yield");
|
state.logger->Debug("svcSleepThread: Cooperative Yield");
|
||||||
state.scheduler->Rotate();
|
state.scheduler->Rotate();
|
||||||
@ -447,7 +449,7 @@ namespace skyline::kernel::svc {
|
|||||||
KHandle handle{state.ctx->gpr.w0};
|
KHandle handle{state.ctx->gpr.w0};
|
||||||
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("svcClearEvent: Clearing event: 0x{:X}", handle);
|
state.logger->Debug("svcClearEvent: Clearing 0x{:X}", handle);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("svcClearEvent: 'handle' invalid: 0x{:X}", handle);
|
state.logger->Warn("svcClearEvent: 'handle' invalid: 0x{:X}", handle);
|
||||||
@ -525,7 +527,7 @@ namespace skyline::kernel::svc {
|
|||||||
KHandle handle{static_cast<KHandle>(state.ctx->gpr.w0)};
|
KHandle handle{static_cast<KHandle>(state.ctx->gpr.w0)};
|
||||||
try {
|
try {
|
||||||
state.process->CloseHandle(handle);
|
state.process->CloseHandle(handle);
|
||||||
state.logger->Debug("svcCloseHandle: Closing handle: 0x{:X}", handle);
|
state.logger->Debug("svcCloseHandle: Closing 0x{:X}", handle);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("svcCloseHandle: 'handle' invalid: 0x{:X}", handle);
|
state.logger->Warn("svcCloseHandle: 'handle' invalid: 0x{:X}", handle);
|
||||||
@ -540,7 +542,7 @@ namespace skyline::kernel::svc {
|
|||||||
switch (object->objectType) {
|
switch (object->objectType) {
|
||||||
case type::KType::KEvent:
|
case type::KType::KEvent:
|
||||||
case type::KType::KProcess:
|
case type::KType::KProcess:
|
||||||
std::static_pointer_cast<type::KSyncObject>(object)->ResetSignal();
|
state.ctx->gpr.w0 = std::static_pointer_cast<type::KSyncObject>(object)->ResetSignal() ? Result{} : result::InvalidState;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
@ -550,7 +552,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.logger->Debug("svcResetSignal: Resetting signal: 0x{:X}", handle);
|
state.logger->Debug("svcResetSignal: Resetting 0x{:X}", handle);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("svcResetSignal: 'handle' invalid: 0x{:X}", handle);
|
state.logger->Warn("svcResetSignal: 'handle' invalid: 0x{:X}", handle);
|
||||||
@ -572,11 +574,7 @@ namespace skyline::kernel::svc {
|
|||||||
std::vector<std::shared_ptr<type::KSyncObject>> objectTable;
|
std::vector<std::shared_ptr<type::KSyncObject>> objectTable;
|
||||||
objectTable.reserve(numHandles);
|
objectTable.reserve(numHandles);
|
||||||
|
|
||||||
std::string handleString;
|
|
||||||
for (const auto &handle : waitHandles) {
|
for (const auto &handle : waitHandles) {
|
||||||
if (Logger::LogLevel::Debug <= state.logger->configLevel)
|
|
||||||
handleString += fmt::format("* 0x{:X}\n", handle);
|
|
||||||
|
|
||||||
auto object{state.process->GetHandle(handle)};
|
auto object{state.process->GetHandle(handle)};
|
||||||
switch (object->objectType) {
|
switch (object->objectType) {
|
||||||
case type::KType::KProcess:
|
case type::KType::KProcess:
|
||||||
@ -595,7 +593,14 @@ 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) {
|
||||||
|
state.logger->Debug("svcWaitSynchronization: Waiting on 0x{:X} for {}ns", waitHandles[0], timeout);
|
||||||
|
} else if (Logger::LogLevel::Debug <= state.logger->configLevel) {
|
||||||
|
std::string handleString;
|
||||||
|
for (const auto &handle : waitHandles)
|
||||||
|
handleString += fmt::format("* 0x{:X}\n", handle);
|
||||||
state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: {}ns", handleString, timeout);
|
state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: {}ns", handleString, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_lock lock(type::KSyncObject::syncObjectMutex);
|
std::unique_lock lock(type::KSyncObject::syncObjectMutex);
|
||||||
if (state.thread->cancelSync) {
|
if (state.thread->cancelSync) {
|
||||||
@ -607,7 +612,7 @@ namespace skyline::kernel::svc {
|
|||||||
u32 index{};
|
u32 index{};
|
||||||
for (const auto &object : objectTable) {
|
for (const auto &object : objectTable) {
|
||||||
if (object->signalled) {
|
if (object->signalled) {
|
||||||
state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles[index]);
|
state.logger->Debug("svcWaitSynchronization: Signalled 0x{:X}", waitHandles[index]);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
state.ctx->gpr.w1 = index;
|
state.ctx->gpr.w1 = index;
|
||||||
return;
|
return;
|
||||||
@ -655,7 +660,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wakeObject) {
|
if (wakeObject) {
|
||||||
state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles[wakeIndex]);
|
state.logger->Debug("svcWaitSynchronization: Signalled 0x{:X}", waitHandles[wakeIndex]);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
state.ctx->gpr.w1 = wakeIndex;
|
state.ctx->gpr.w1 = wakeIndex;
|
||||||
} else if (state.thread->cancelSync) {
|
} else if (state.thread->cancelSync) {
|
||||||
@ -680,6 +685,7 @@ namespace skyline::kernel::svc {
|
|||||||
thread->isCancellable = false;
|
thread->isCancellable = false;
|
||||||
state.scheduler->InsertThread(thread);
|
state.scheduler->InsertThread(thread);
|
||||||
}
|
}
|
||||||
|
state.ctx->gpr.w0 = Result{};
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", static_cast<u32>(state.ctx->gpr.w0));
|
state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", static_cast<u32>(state.ctx->gpr.w0));
|
||||||
state.ctx->gpr.w0 = result::InvalidHandle;
|
state.ctx->gpr.w0 = result::InvalidHandle;
|
||||||
@ -687,24 +693,24 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ArbitrateLock(const DeviceState &state) {
|
void ArbitrateLock(const DeviceState &state) {
|
||||||
auto pointer{reinterpret_cast<u32 *>(state.ctx->gpr.x1)};
|
auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x1)};
|
||||||
if (!util::WordAligned(pointer)) {
|
if (!util::WordAligned(mutex)) {
|
||||||
state.logger->Warn("svcArbitrateLock: 'pointer' not word aligned: 0x{:X}", pointer);
|
state.logger->Warn("svcArbitrateLock: 'mutex' not word aligned: 0x{:X}", mutex);
|
||||||
state.ctx->gpr.w0 = result::InvalidAddress;
|
state.ctx->gpr.w0 = result::InvalidAddress;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.logger->Debug("svcArbitrateLock: Locking mutex at 0x{:X}", pointer);
|
state.logger->Debug("svcArbitrateLock: Locking 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};
|
||||||
auto result{state.process->MutexLock(pointer, ownerHandle, requesterHandle)};
|
auto result{state.process->MutexLock(mutex, ownerHandle, requesterHandle)};
|
||||||
if (result == Result{})
|
if (result == Result{})
|
||||||
state.logger->Debug("svcArbitrateLock: Locked mutex at 0x{:X}", pointer);
|
state.logger->Debug("svcArbitrateLock: Locked 0x{:X}", mutex);
|
||||||
|
else if (result == result::InvalidCurrentMemory)
|
||||||
|
result = Result{}; // If the mutex value isn't expected then it's still successful
|
||||||
else if (result == result::InvalidHandle)
|
else if (result == result::InvalidHandle)
|
||||||
state.logger->Warn("svcArbitrateLock: 'ownerHandle' invalid: 0x{:X}", ownerHandle);
|
state.logger->Warn("svcArbitrateLock: 'ownerHandle' invalid: 0x{:X}", ownerHandle);
|
||||||
else if (result == result::InvalidCurrentMemory)
|
|
||||||
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex or didn't have waiter flag at 0x{:X}", pointer);
|
|
||||||
|
|
||||||
state.ctx->gpr.w0 = result;
|
state.ctx->gpr.w0 = result;
|
||||||
}
|
}
|
||||||
@ -717,9 +723,9 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.logger->Debug("svcArbitrateUnlock: Unlocking mutex at 0x{:X}", mutex);
|
state.logger->Debug("svcArbitrateUnlock: Unlocking 0x{:X}", mutex);
|
||||||
state.process->MutexUnlock(mutex);
|
state.process->MutexUnlock(mutex);
|
||||||
state.logger->Debug("svcArbitrateUnlock: Unlocked mutex at 0x{:X}", mutex);
|
state.logger->Debug("svcArbitrateUnlock: Unlocked 0x{:X}", mutex);
|
||||||
|
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
}
|
}
|
||||||
@ -736,22 +742,22 @@ namespace skyline::kernel::svc {
|
|||||||
KHandle requesterHandle{state.ctx->gpr.w2};
|
KHandle requesterHandle{state.ctx->gpr.w2};
|
||||||
|
|
||||||
i64 timeout{static_cast<i64>(state.ctx->gpr.x3)};
|
i64 timeout{static_cast<i64>(state.ctx->gpr.x3)};
|
||||||
state.logger->Debug("svcWaitProcessWideKeyAtomic: Mutex: 0x{:X}, Conditional-Variable: 0x{:X}, Timeout: {}ns", mutex, conditional, timeout);
|
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waiting on 0x{:X} with 0x{:X} for {}ns", conditional, mutex, timeout);
|
||||||
|
|
||||||
auto result{state.process->ConditionalVariableWait(conditional, mutex, requesterHandle, timeout)};
|
auto result{state.process->ConditionalVariableWait(conditional, mutex, requesterHandle, timeout)};
|
||||||
if (result == Result{})
|
if (result == Result{})
|
||||||
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for conditional variable (0x{:X}) and reacquired mutex", conditional);
|
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for 0x{:X} and reacquired 0x{:X}", conditional, mutex);
|
||||||
else if (result == result::TimedOut)
|
else if (result == result::TimedOut)
|
||||||
state.logger->Debug("svcWaitProcessWideKeyAtomic: Wait has timed out ({}ns) for 0x{:X}", timeout, conditional);
|
state.logger->Debug("svcWaitProcessWideKeyAtomic: Wait on 0x{:X} has timed out after {}ns", conditional, timeout);
|
||||||
state.ctx->gpr.w0 = result;
|
state.ctx->gpr.w0 = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalProcessWideKey(const DeviceState &state) {
|
void SignalProcessWideKey(const DeviceState &state) {
|
||||||
auto key{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
|
auto conditional{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
|
||||||
KHandle count{state.ctx->gpr.w1};
|
i32 count{static_cast<i32>(state.ctx->gpr.w1)};
|
||||||
|
|
||||||
state.logger->Debug("svcSignalProcessWideKey: Signalling Conditional-Variable at 0x{:X} for {}", key, count);
|
state.logger->Debug("svcSignalProcessWideKey: Signalling 0x{:X} for {} waiters", conditional, count);
|
||||||
state.process->ConditionalVariableSignal(key, count);
|
state.process->ConditionalVariableSignal(conditional, count);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +245,6 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
state.scheduler->RemoveThread();
|
state.scheduler->RemoveThread();
|
||||||
MutexUnlock(mutex);
|
MutexUnlock(mutex);
|
||||||
__sync_synchronize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout > 0 && !state.scheduler->TimedWaitSchedule(std::chrono::nanoseconds(timeout))) {
|
if (timeout > 0 && !state.scheduler->TimedWaitSchedule(std::chrono::nanoseconds(timeout))) {
|
||||||
@ -255,9 +254,11 @@ namespace skyline::kernel::type {
|
|||||||
if (iterator != queue.second)
|
if (iterator != queue.second)
|
||||||
if (syncWaiters.erase(iterator) == queue.second)
|
if (syncWaiters.erase(iterator) == queue.second)
|
||||||
__atomic_store_n(key, false, __ATOMIC_SEQ_CST);
|
__atomic_store_n(key, false, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
state.scheduler->InsertThread(state.thread);
|
state.scheduler->InsertThread(state.thread);
|
||||||
state.scheduler->WaitSchedule();
|
state.scheduler->WaitSchedule();
|
||||||
|
|
||||||
return result::TimedOut;
|
return result::TimedOut;
|
||||||
} else {
|
} else {
|
||||||
state.scheduler->WaitSchedule(false);
|
state.scheduler->WaitSchedule(false);
|
||||||
@ -275,13 +276,15 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::ConditionalVariableSignal(u32 *key, u64 amount) {
|
void KProcess::ConditionalVariableSignal(u32 *key, i32 amount) {
|
||||||
std::lock_guard lock(syncWaiterMutex);
|
std::lock_guard lock(syncWaiterMutex);
|
||||||
auto queue{syncWaiters.equal_range(key)};
|
auto queue{syncWaiters.equal_range(key)};
|
||||||
|
|
||||||
auto it{queue.first};
|
auto it{queue.first};
|
||||||
if (queue.first != queue.second)
|
if (queue.first != queue.second)
|
||||||
for (; it != queue.second && amount; it = syncWaiters.erase(it), amount--)
|
for (i32 waiterCount{amount}; it != queue.second && (amount <= 0 || waiterCount); it = syncWaiters.erase(it), waiterCount--)
|
||||||
state.scheduler->InsertThread(it->second);
|
state.scheduler->InsertThread(it->second);
|
||||||
|
|
||||||
if (it == queue.second)
|
if (it == queue.second)
|
||||||
__atomic_store_n(key, false, __ATOMIC_SEQ_CST); // We need to update the boolean flag denoting that there are no more threads waiting on this conditional variable
|
__atomic_store_n(key, false, __ATOMIC_SEQ_CST); // We need to update the boolean flag denoting that there are no more threads waiting on this conditional variable
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ namespace skyline {
|
|||||||
/**
|
/**
|
||||||
* @brief Signals the conditional variable at the specified address
|
* @brief Signals the conditional variable at the specified address
|
||||||
*/
|
*/
|
||||||
void ConditionalVariableSignal(u32 *key, u64 amount);
|
void ConditionalVariableSignal(u32 *key, i32 amount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Waits on the supplied address with the specified arbitration function
|
* @brief Waits on the supplied address with the specified arbitration function
|
||||||
|
@ -14,7 +14,7 @@ namespace skyline::kernel::type {
|
|||||||
public:
|
public:
|
||||||
inline static std::mutex syncObjectMutex; //!< A global lock used for locking all signalling to avoid races
|
inline static std::mutex syncObjectMutex; //!< A global lock used for locking all signalling to avoid races
|
||||||
std::list<std::shared_ptr<KThread>> syncObjectWaiters; //!< A list of threads waiting on this object to be signalled
|
std::list<std::shared_ptr<KThread>> syncObjectWaiters; //!< A list of threads waiting on this object to be signalled
|
||||||
std::atomic<bool> signalled; //!< If the current object is signalled (An object stays signalled till the signal has been explicitly reset)
|
bool signalled; //!< If the current object is signalled (An object stays signalled till the signal has been explicitly reset)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param presignalled If this object should be signalled initially or not
|
* @param presignalled If this object should be signalled initially or not
|
||||||
@ -28,10 +28,15 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resets the object to an unsignalled state
|
* @brief Resets the object to an unsignalled state
|
||||||
|
* @return If the signal was reset or not
|
||||||
*/
|
*/
|
||||||
inline void ResetSignal() {
|
inline bool ResetSignal() {
|
||||||
std::lock_guard lock(syncObjectMutex);
|
std::lock_guard lock(syncObjectMutex);
|
||||||
|
if (signalled) {
|
||||||
signalled = false;
|
signalled = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~KSyncObject() = default;
|
virtual ~KSyncObject() = default;
|
||||||
|
@ -18,14 +18,14 @@ namespace skyline::nce {
|
|||||||
const auto &state{*ctx->state};
|
const auto &state{*ctx->state};
|
||||||
try {
|
try {
|
||||||
auto function{kernel::svc::SvcTable[svc]};
|
auto function{kernel::svc::SvcTable[svc]};
|
||||||
if (function) {
|
if (function) [[likely]] {
|
||||||
state.logger->Debug("SVC called 0x{:X}", svc);
|
state.logger->Debug("SVC called 0x{:X}", svc);
|
||||||
(*function)(state);
|
(*function)(state);
|
||||||
} else {
|
} else [[unlikely]] {
|
||||||
throw exception("Unimplemented SVC 0x{:X}", svc);
|
throw exception("Unimplemented SVC 0x{:X}", svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (kernel::Scheduler::YieldPending) {
|
while (kernel::Scheduler::YieldPending) [[unlikely]] {
|
||||||
state.scheduler->Rotate(false);
|
state.scheduler->Rotate(false);
|
||||||
kernel::Scheduler::YieldPending = false;
|
kernel::Scheduler::YieldPending = false;
|
||||||
state.scheduler->WaitSchedule();
|
state.scheduler->WaitSchedule();
|
||||||
|
@ -7,7 +7,7 @@ namespace skyline::service::settings {
|
|||||||
ISystemSettingsServer::ISystemSettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
ISystemSettingsServer::ISystemSettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result ISystemSettingsServer::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISystemSettingsServer::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
request.outputBuf.at(0).as<SysVerTitle>() = {.major=5, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"};
|
request.outputBuf.at(0).as<SysVerTitle>() = {.major=9, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"};
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user