aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp71
1 files changed, 26 insertions, 45 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 7f5c0cc86..047fa0c19 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1284,10 +1284,14 @@ static ResultCode StartThread(Handle thread_handle) {
/// Called when a thread exits
static void ExitThread() {
- LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC());
+ auto& system = Core::System::GetInstance();
- ExitCurrentThread();
- Core::System::GetInstance().PrepareReschedule();
+ LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
+
+ auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
+ current_thread->Stop();
+ system.CurrentScheduler().RemoveThread(current_thread);
+ system.PrepareReschedule();
}
/// Sleep the current thread
@@ -1300,32 +1304,32 @@ static void SleepThread(s64 nanoseconds) {
YieldAndWaitForLoadBalancing = -2,
};
+ auto& system = Core::System::GetInstance();
+ auto& scheduler = system.CurrentScheduler();
+ auto* const current_thread = scheduler.GetCurrentThread();
+
if (nanoseconds <= 0) {
- auto& scheduler{Core::System::GetInstance().CurrentScheduler()};
switch (static_cast<SleepType>(nanoseconds)) {
case SleepType::YieldWithoutLoadBalancing:
- scheduler.YieldWithoutLoadBalancing(GetCurrentThread());
+ scheduler.YieldWithoutLoadBalancing(current_thread);
break;
case SleepType::YieldWithLoadBalancing:
- scheduler.YieldWithLoadBalancing(GetCurrentThread());
+ scheduler.YieldWithLoadBalancing(current_thread);
break;
case SleepType::YieldAndWaitForLoadBalancing:
- scheduler.YieldAndWaitForLoadBalancing(GetCurrentThread());
+ scheduler.YieldAndWaitForLoadBalancing(current_thread);
break;
default:
UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
}
} else {
- // Sleep current thread and check for next thread to schedule
- WaitCurrentThread_Sleep();
-
- // Create an event to wake the thread up after the specified nanosecond delay has passed
- GetCurrentThread()->WakeAfterDelay(nanoseconds);
+ current_thread->Sleep(nanoseconds);
}
// Reschedule all CPU cores
- for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i)
- Core::System::GetInstance().CpuCore(i).PrepareReschedule();
+ for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i) {
+ system.CpuCore(i).PrepareReschedule();
+ }
}
/// Wait process wide key atomic
@@ -1479,21 +1483,10 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
return ERR_INVALID_ADDRESS;
}
- auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
- switch (static_cast<AddressArbiter::ArbitrationType>(type)) {
- case AddressArbiter::ArbitrationType::WaitIfLessThan:
- return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, false);
- case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan:
- return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, true);
- case AddressArbiter::ArbitrationType::WaitIfEqual:
- return address_arbiter.WaitForAddressIfEqual(address, value, timeout);
- default:
- LOG_ERROR(Kernel_SVC,
- "Invalid arbitration type, expected WaitIfLessThan, DecrementAndWaitIfLessThan "
- "or WaitIfEqual but got {}",
- type);
- return ERR_INVALID_ENUM_VALUE;
- }
+ const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
+ auto& address_arbiter =
+ Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
+ return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
}
// Signals to an address (via Address Arbiter)
@@ -1511,22 +1504,10 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
return ERR_INVALID_ADDRESS;
}
- auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
- switch (static_cast<AddressArbiter::SignalType>(type)) {
- case AddressArbiter::SignalType::Signal:
- return address_arbiter.SignalToAddress(address, num_to_wake);
- case AddressArbiter::SignalType::IncrementAndSignalIfEqual:
- return address_arbiter.IncrementAndSignalToAddressIfEqual(address, value, num_to_wake);
- case AddressArbiter::SignalType::ModifyByWaitingCountAndSignalIfEqual:
- return address_arbiter.ModifyByWaitingCountAndSignalToAddressIfEqual(address, value,
- num_to_wake);
- default:
- LOG_ERROR(Kernel_SVC,
- "Invalid signal type, expected Signal, IncrementAndSignalIfEqual "
- "or ModifyByWaitingCountAndSignalIfEqual but got {}",
- type);
- return ERR_INVALID_ENUM_VALUE;
- }
+ const auto signal_type = static_cast<AddressArbiter::SignalType>(type);
+ auto& address_arbiter =
+ Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
+ return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);
}
/// This returns the total CPU ticks elapsed since the CPU was powered-on