summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2020-12-03 21:56:02 -0800
committerGravatar bunnei2020-12-06 00:03:24 -0800
commit4756cb203e8ef09377988eb1b49ca20ef45f4492 (patch)
tree69aed28dbf048dea702665e68797f14c20650276 /src/core
parenthle: kernel: Separate KScheduler from GlobalSchedulerContext class. (diff)
downloadyuzu-4756cb203e8ef09377988eb1b49ca20ef45f4492.tar.gz
yuzu-4756cb203e8ef09377988eb1b49ca20ef45f4492.tar.xz
yuzu-4756cb203e8ef09377988eb1b49ca20ef45f4492.zip
hle: kernel: Separate KScopedSchedulerLockAndSleep from k_scheduler.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp5
-rw-r--r--src/core/hle/kernel/global_scheduler_context.cpp8
-rw-r--r--src/core/hle/kernel/global_scheduler_context.h10
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp8
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp25
-rw-r--r--src/core/hle/kernel/k_scheduler.h19
-rw-r--r--src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h56
-rw-r--r--src/core/hle/kernel/svc.cpp3
-rw-r--r--src/core/hle/kernel/synchronization.cpp3
-rw-r--r--src/core/hle/kernel/thread.cpp3
11 files changed, 72 insertions, 69 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index ee61f22c0..5f6dce52a 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -159,6 +159,7 @@ add_library(core STATIC
159 hle/kernel/k_scheduler.cpp 159 hle/kernel/k_scheduler.cpp
160 hle/kernel/k_scheduler.h 160 hle/kernel/k_scheduler.h
161 hle/kernel/k_scheduler_lock.h 161 hle/kernel/k_scheduler_lock.h
162 hle/kernel/k_scoped_scheduler_lock_and_sleep.h
162 hle/kernel/kernel.cpp 163 hle/kernel/kernel.cpp
163 hle/kernel/kernel.h 164 hle/kernel/kernel.h
164 hle/kernel/memory/address_space_info.cpp 165 hle/kernel/memory/address_space_info.cpp
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index bc32be18b..ac4913173 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -13,6 +13,7 @@
13#include "core/hle/kernel/errors.h" 13#include "core/hle/kernel/errors.h"
14#include "core/hle/kernel/handle_table.h" 14#include "core/hle/kernel/handle_table.h"
15#include "core/hle/kernel/k_scheduler.h" 15#include "core/hle/kernel/k_scheduler.h"
16#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
16#include "core/hle/kernel/kernel.h" 17#include "core/hle/kernel/kernel.h"
17#include "core/hle/kernel/thread.h" 18#include "core/hle/kernel/thread.h"
18#include "core/hle/kernel/time_manager.h" 19#include "core/hle/kernel/time_manager.h"
@@ -157,7 +158,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
157 158
158 Handle event_handle = InvalidHandle; 159 Handle event_handle = InvalidHandle;
159 { 160 {
160 SchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout); 161 KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);
161 162
162 if (current_thread->IsPendingTermination()) { 163 if (current_thread->IsPendingTermination()) {
163 lock.CancelSleep(); 164 lock.CancelSleep();
@@ -227,7 +228,7 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
227 228
228 Handle event_handle = InvalidHandle; 229 Handle event_handle = InvalidHandle;
229 { 230 {
230 SchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout); 231 KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout);
231 232
232 if (current_thread->IsPendingTermination()) { 233 if (current_thread->IsPendingTermination()) {
233 lock.CancelSleep(); 234 lock.CancelSleep();
diff --git a/src/core/hle/kernel/global_scheduler_context.cpp b/src/core/hle/kernel/global_scheduler_context.cpp
index 40e9adf47..a9cb48b38 100644
--- a/src/core/hle/kernel/global_scheduler_context.cpp
+++ b/src/core/hle/kernel/global_scheduler_context.cpp
@@ -44,12 +44,4 @@ bool GlobalSchedulerContext::IsLocked() const {
44 return scheduler_lock.IsLockedByCurrentThread(); 44 return scheduler_lock.IsLockedByCurrentThread();
45} 45}
46 46
47void GlobalSchedulerContext::Lock() {
48 scheduler_lock.Lock();
49}
50
51void GlobalSchedulerContext::Unlock() {
52 scheduler_lock.Unlock();
53}
54
55} // namespace Kernel 47} // namespace Kernel
diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h
index 40fe44cc0..39c383746 100644
--- a/src/core/hle/kernel/global_scheduler_context.h
+++ b/src/core/hle/kernel/global_scheduler_context.h
@@ -55,15 +55,7 @@ public:
55 55
56private: 56private:
57 friend class SchedulerLock; 57 friend class SchedulerLock;
58 58 friend class KScopedSchedulerLockAndSleep;
59 /// Lock the scheduler to the current thread.
60 void Lock();
61
62 /// Unlocks the scheduler, reselects threads, interrupts cores for rescheduling
63 /// and reschedules current core if needed.
64 void Unlock();
65
66 using LockType = KAbstractSchedulerLock<KScheduler>;
67 59
68 KernelCore& kernel; 60 KernelCore& kernel;
69 61
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 7eda89786..e75e80ad0 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -18,6 +18,7 @@
18#include "core/hle/kernel/handle_table.h" 18#include "core/hle/kernel/handle_table.h"
19#include "core/hle/kernel/hle_ipc.h" 19#include "core/hle/kernel/hle_ipc.h"
20#include "core/hle/kernel/k_scheduler.h" 20#include "core/hle/kernel/k_scheduler.h"
21#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
21#include "core/hle/kernel/kernel.h" 22#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/object.h" 23#include "core/hle/kernel/object.h"
23#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
@@ -56,9 +57,9 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
56 writable_event = pair.writable; 57 writable_event = pair.writable;
57 } 58 }
58 59
60 Handle event_handle = InvalidHandle;
59 { 61 {
60 Handle event_handle = InvalidHandle; 62 KScopedSchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout);
61 SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout);
62 thread->SetHLECallback( 63 thread->SetHLECallback(
63 [context = *this, callback](std::shared_ptr<Thread> thread) mutable -> bool { 64 [context = *this, callback](std::shared_ptr<Thread> thread) mutable -> bool {
64 ThreadWakeupReason reason = thread->GetSignalingResult() == RESULT_TIMEOUT 65 ThreadWakeupReason reason = thread->GetSignalingResult() == RESULT_TIMEOUT
@@ -74,9 +75,8 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
74 thread->SetStatus(ThreadStatus::WaitHLEEvent); 75 thread->SetStatus(ThreadStatus::WaitHLEEvent);
75 thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); 76 thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
76 readable_event->AddWaitingThread(thread); 77 readable_event->AddWaitingThread(thread);
77 lock.Release();
78 thread->SetHLETimeEvent(event_handle);
79 } 78 }
79 thread->SetHLETimeEvent(event_handle);
80 80
81 is_thread_waiting = true; 81 is_thread_waiting = true;
82 82
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index c7e2eabd4..466147498 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -14,6 +14,7 @@
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/cpu_manager.h" 15#include "core/cpu_manager.h"
16#include "core/hle/kernel/k_scheduler.h" 16#include "core/hle/kernel/k_scheduler.h"
17#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
17#include "core/hle/kernel/kernel.h" 18#include "core/hle/kernel/kernel.h"
18#include "core/hle/kernel/physical_core.h" 19#include "core/hle/kernel/physical_core.h"
19#include "core/hle/kernel/process.h" 20#include "core/hle/kernel/process.h"
@@ -800,28 +801,4 @@ SchedulerLock::~SchedulerLock() {
800 kernel.GlobalSchedulerContext().Unlock(); 801 kernel.GlobalSchedulerContext().Unlock();
801} 802}
802 803
803SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle,
804 Thread* time_task, s64 nanoseconds)
805 : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{
806 nanoseconds} {
807 event_handle = InvalidHandle;
808}
809
810SchedulerLockAndSleep::~SchedulerLockAndSleep() {
811 if (sleep_cancelled) {
812 return;
813 }
814 auto& time_manager = kernel.TimeManager();
815 time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds);
816}
817
818void SchedulerLockAndSleep::Release() {
819 if (sleep_cancelled) {
820 return;
821 }
822 auto& time_manager = kernel.TimeManager();
823 time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds);
824 sleep_cancelled = true;
825}
826
827} // namespace Kernel 804} // namespace Kernel
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index 7f020d96e..5ba0f3c32 100644
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -207,23 +207,4 @@ protected:
207 KernelCore& kernel; 207 KernelCore& kernel;
208}; 208};
209 209
210class SchedulerLockAndSleep : public SchedulerLock {
211public:
212 explicit SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* time_task,
213 s64 nanoseconds);
214 ~SchedulerLockAndSleep();
215
216 void CancelSleep() {
217 sleep_cancelled = true;
218 }
219
220 void Release();
221
222private:
223 Handle& event_handle;
224 Thread* time_task;
225 s64 nanoseconds;
226 bool sleep_cancelled{};
227};
228
229} // namespace Kernel 210} // namespace Kernel
diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
new file mode 100644
index 000000000..f11a62216
--- /dev/null
+++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
@@ -0,0 +1,56 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5// This file references various implementation details from Atmosphere, an open-source firmware for
6// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
7
8#pragma once
9
10#include "common/common_types.h"
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/thread.h"
13#include "core/hle/kernel/time_manager.h"
14
15namespace Kernel {
16
17class KScopedSchedulerLockAndSleep {
18private:
19 KernelCore& kernel;
20 s64 timeout_tick{};
21 Thread* thread{};
22 Handle* event_handle{};
23
24public:
25 explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, Thread* t, s64 timeout)
26 : kernel(kernel), timeout_tick(timeout), thread(t) {
27 /* Lock the scheduler. */
28 kernel.GlobalSchedulerContext().scheduler_lock.Lock();
29 }
30
31 explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* t,
32 s64 timeout)
33 : kernel(kernel), event_handle(&event_handle), timeout_tick(timeout), thread(t) {
34 /* Lock the scheduler. */
35 kernel.GlobalSchedulerContext().scheduler_lock.Lock();
36 }
37
38 ~KScopedSchedulerLockAndSleep() {
39 /* Register the sleep. */
40 if (this->timeout_tick > 0) {
41 auto& time_manager = kernel.TimeManager();
42 Handle handle{};
43 time_manager.ScheduleTimeEvent(event_handle ? *event_handle : handle, this->thread,
44 this->timeout_tick);
45 }
46
47 /* Unlock the scheduler. */
48 kernel.GlobalSchedulerContext().scheduler_lock.Unlock();
49 }
50
51 void CancelSleep() {
52 this->timeout_tick = 0;
53 }
54};
55
56} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 2612a6b0d..2760a307c 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -25,6 +25,7 @@
25#include "core/hle/kernel/errors.h" 25#include "core/hle/kernel/errors.h"
26#include "core/hle/kernel/handle_table.h" 26#include "core/hle/kernel/handle_table.h"
27#include "core/hle/kernel/k_scheduler.h" 27#include "core/hle/kernel/k_scheduler.h"
28#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
28#include "core/hle/kernel/kernel.h" 29#include "core/hle/kernel/kernel.h"
29#include "core/hle/kernel/memory/memory_block.h" 30#include "core/hle/kernel/memory/memory_block.h"
30#include "core/hle/kernel/memory/page_table.h" 31#include "core/hle/kernel/memory/page_table.h"
@@ -1654,7 +1655,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
1654 Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread(); 1655 Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread();
1655 auto* const current_process = kernel.CurrentProcess(); 1656 auto* const current_process = kernel.CurrentProcess();
1656 { 1657 {
1657 SchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds); 1658 KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds);
1658 const auto& handle_table = current_process->GetHandleTable(); 1659 const auto& handle_table = current_process->GetHandleTable();
1659 std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1660 std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1660 ASSERT(thread); 1661 ASSERT(thread);
diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp
index 342fb4516..6651ad90c 100644
--- a/src/core/hle/kernel/synchronization.cpp
+++ b/src/core/hle/kernel/synchronization.cpp
@@ -6,6 +6,7 @@
6#include "core/hle/kernel/errors.h" 6#include "core/hle/kernel/errors.h"
7#include "core/hle/kernel/handle_table.h" 7#include "core/hle/kernel/handle_table.h"
8#include "core/hle/kernel/k_scheduler.h" 8#include "core/hle/kernel/k_scheduler.h"
9#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
9#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
10#include "core/hle/kernel/synchronization.h" 11#include "core/hle/kernel/synchronization.h"
11#include "core/hle/kernel/synchronization_object.h" 12#include "core/hle/kernel/synchronization_object.h"
@@ -40,7 +41,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
40 auto* const thread = kernel.CurrentScheduler()->GetCurrentThread(); 41 auto* const thread = kernel.CurrentScheduler()->GetCurrentThread();
41 Handle event_handle = InvalidHandle; 42 Handle event_handle = InvalidHandle;
42 { 43 {
43 SchedulerLockAndSleep lock(kernel, event_handle, thread, nano_seconds); 44 KScopedSchedulerLockAndSleep lock(kernel, event_handle, thread, nano_seconds);
44 const auto itr = 45 const auto itr =
45 std::find_if(sync_objects.begin(), sync_objects.end(), 46 std::find_if(sync_objects.begin(), sync_objects.end(),
46 [thread](const std::shared_ptr<SynchronizationObject>& object) { 47 [thread](const std::shared_ptr<SynchronizationObject>& object) {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 804e07f2b..6f89238ca 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -18,6 +18,7 @@
18#include "core/hle/kernel/errors.h" 18#include "core/hle/kernel/errors.h"
19#include "core/hle/kernel/handle_table.h" 19#include "core/hle/kernel/handle_table.h"
20#include "core/hle/kernel/k_scheduler.h" 20#include "core/hle/kernel/k_scheduler.h"
21#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
21#include "core/hle/kernel/kernel.h" 22#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/object.h" 23#include "core/hle/kernel/object.h"
23#include "core/hle/kernel/process.h" 24#include "core/hle/kernel/process.h"
@@ -393,7 +394,7 @@ ResultCode Thread::SetActivity(ThreadActivity value) {
393ResultCode Thread::Sleep(s64 nanoseconds) { 394ResultCode Thread::Sleep(s64 nanoseconds) {
394 Handle event_handle{}; 395 Handle event_handle{};
395 { 396 {
396 SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); 397 KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
397 SetStatus(ThreadStatus::WaitSleep); 398 SetStatus(ThreadStatus::WaitSleep);
398 } 399 }
399 400