Kernel/Synch: Do not attempt a reschedule on every syscall.
Not all syscalls should cause reschedules, this commit attempts to remedy that, however, it still does not cover all cases.
This commit is contained in:
parent
8f6c3b5c20
commit
38a90882a4
2 changed files with 18 additions and 2 deletions
|
@ -84,6 +84,7 @@ void Mutex::Release() {
|
||||||
if (lock_count == 0) {
|
if (lock_count == 0) {
|
||||||
holding_thread->held_mutexes.erase(this);
|
holding_thread->held_mutexes.erase(this);
|
||||||
ResumeWaitingThread(this);
|
ResumeWaitingThread(this);
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,6 +248,8 @@ static ResultCode SendSyncRequest(Kernel::Handle handle) {
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
|
LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
|
||||||
|
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
// TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server
|
// TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server
|
||||||
// responds and cause a reschedule.
|
// responds and cause a reschedule.
|
||||||
return session->SendSyncRequest();
|
return session->SendSyncRequest();
|
||||||
|
@ -284,6 +286,8 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds)
|
||||||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||||
thread->WakeAfterDelay(nano_seconds);
|
thread->WakeAfterDelay(nano_seconds);
|
||||||
|
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
// Note: The output of this SVC will be set to RESULT_SUCCESS if the thread
|
// Note: The output of this SVC will be set to RESULT_SUCCESS if the thread
|
||||||
// resumes due to a signal in its wait objects.
|
// resumes due to a signal in its wait objects.
|
||||||
// Otherwise we retain the default value of timeout.
|
// Otherwise we retain the default value of timeout.
|
||||||
|
@ -366,6 +370,8 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
|
||||||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||||
thread->WakeAfterDelay(nano_seconds);
|
thread->WakeAfterDelay(nano_seconds);
|
||||||
|
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
// This value gets set to -1 by default in this case, it is not modified after this.
|
// This value gets set to -1 by default in this case, it is not modified after this.
|
||||||
*out = -1;
|
*out = -1;
|
||||||
// Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to
|
// Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to
|
||||||
|
@ -414,6 +420,8 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
|
||||||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||||
thread->WakeAfterDelay(nano_seconds);
|
thread->WakeAfterDelay(nano_seconds);
|
||||||
|
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
// Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to a
|
// Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to a
|
||||||
// signal in one of its wait objects.
|
// signal in one of its wait objects.
|
||||||
// Otherwise we retain the default value of timeout, and -1 in the out parameter
|
// Otherwise we retain the default value of timeout, and -1 in the out parameter
|
||||||
|
@ -448,6 +456,9 @@ static ResultCode ArbitrateAddress(Kernel::Handle handle, u32 address, u32 type,
|
||||||
auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), address, value,
|
auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), address, value,
|
||||||
nanoseconds);
|
nanoseconds);
|
||||||
|
|
||||||
|
// TODO(Subv): Identify in which specific cases this call should cause a reschedule.
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,6 +585,8 @@ static ResultCode CreateThread(Kernel::Handle* out_handle, s32 priority, u32 ent
|
||||||
|
|
||||||
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread)));
|
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread)));
|
||||||
|
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
|
LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
|
||||||
"threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
|
"threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
|
||||||
entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle);
|
entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle);
|
||||||
|
@ -586,6 +599,7 @@ static void ExitThread() {
|
||||||
LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC());
|
LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC());
|
||||||
|
|
||||||
Kernel::ExitCurrentThread();
|
Kernel::ExitCurrentThread();
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the priority for the specified thread
|
/// Gets the priority for the specified thread
|
||||||
|
@ -605,6 +619,7 @@ static ResultCode SetThreadPriority(Kernel::Handle handle, s32 priority) {
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
thread->SetPriority(priority);
|
thread->SetPriority(priority);
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,6 +864,8 @@ static void SleepThread(s64 nanoseconds) {
|
||||||
|
|
||||||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||||
Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds);
|
Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds);
|
||||||
|
|
||||||
|
Core::System::GetInstance().PrepareReschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This returns the total CPU ticks elapsed since the CPU was powered-on
|
/// This returns the total CPU ticks elapsed since the CPU was powered-on
|
||||||
|
@ -1184,8 +1201,6 @@ void CallSVC(u32 immediate) {
|
||||||
if (info) {
|
if (info) {
|
||||||
if (info->func) {
|
if (info->func) {
|
||||||
info->func();
|
info->func();
|
||||||
// TODO(Subv): Not all service functions should cause a reschedule in all cases.
|
|
||||||
Core::System::GetInstance().PrepareReschedule();
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name);
|
LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue