summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar liamwhite2023-03-10 16:19:41 -0500
committerGravatar GitHub2023-03-10 16:19:41 -0500
commit92c89312fcfe75d030de9e7bced94bc70dcba00b (patch)
tree2bdc9dcf0a110c0df5f0f4a78904bdcebe42a31f
parentMerge pull request #9928 from german77/super_nfp (diff)
parentkernel: add timer pointer to KThreadQueue (diff)
downloadyuzu-92c89312fcfe75d030de9e7bced94bc70dcba00b.tar.gz
yuzu-92c89312fcfe75d030de9e7bced94bc70dcba00b.tar.xz
yuzu-92c89312fcfe75d030de9e7bced94bc70dcba00b.zip
Merge pull request #9923 from liamwhite/kht
kernel: add timer pointer to KThreadQueue
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp8
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp4
-rw-r--r--src/core/hle/kernel/k_light_condition_variable.cpp4
-rw-r--r--src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h15
-rw-r--r--src/core/hle/kernel/k_synchronization_object.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.cpp4
-rw-r--r--src/core/hle/kernel/k_thread_queue.cpp8
-rw-r--r--src/core/hle/kernel/k_thread_queue.h10
8 files changed, 42 insertions, 15 deletions
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index fb86451ea..a4c16eca9 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -237,10 +237,11 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 val
237Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { 237Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) {
238 // Prepare to wait. 238 // Prepare to wait.
239 KThread* cur_thread = GetCurrentThreadPointer(kernel); 239 KThread* cur_thread = GetCurrentThreadPointer(kernel);
240 KHardwareTimer* timer{};
240 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); 241 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree));
241 242
242 { 243 {
243 KScopedSchedulerLockAndSleep slp{kernel, cur_thread, timeout}; 244 KScopedSchedulerLockAndSleep slp{kernel, std::addressof(timer), cur_thread, timeout};
244 245
245 // Check that the thread isn't terminating. 246 // Check that the thread isn't terminating.
246 if (cur_thread->IsTerminationRequested()) { 247 if (cur_thread->IsTerminationRequested()) {
@@ -279,6 +280,7 @@ Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s6
279 thread_tree.insert(*cur_thread); 280 thread_tree.insert(*cur_thread);
280 281
281 // Wait for the thread to finish. 282 // Wait for the thread to finish.
283 wait_queue.SetHardwareTimer(timer);
282 cur_thread->BeginWait(std::addressof(wait_queue)); 284 cur_thread->BeginWait(std::addressof(wait_queue));
283 cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); 285 cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration);
284 } 286 }
@@ -290,10 +292,11 @@ Result KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s6
290Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { 292Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
291 // Prepare to wait. 293 // Prepare to wait.
292 KThread* cur_thread = GetCurrentThreadPointer(kernel); 294 KThread* cur_thread = GetCurrentThreadPointer(kernel);
295 KHardwareTimer* timer{};
293 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); 296 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree));
294 297
295 { 298 {
296 KScopedSchedulerLockAndSleep slp{kernel, cur_thread, timeout}; 299 KScopedSchedulerLockAndSleep slp{kernel, std::addressof(timer), cur_thread, timeout};
297 300
298 // Check that the thread isn't terminating. 301 // Check that the thread isn't terminating.
299 if (cur_thread->IsTerminationRequested()) { 302 if (cur_thread->IsTerminationRequested()) {
@@ -325,6 +328,7 @@ Result KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
325 thread_tree.insert(*cur_thread); 328 thread_tree.insert(*cur_thread);
326 329
327 // Wait for the thread to finish. 330 // Wait for the thread to finish.
331 wait_queue.SetHardwareTimer(timer);
328 cur_thread->BeginWait(std::addressof(wait_queue)); 332 cur_thread->BeginWait(std::addressof(wait_queue));
329 cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); 333 cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration);
330 } 334 }
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index f40cf92b1..458f4c94e 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -266,11 +266,12 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
266Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { 266Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) {
267 // Prepare to wait. 267 // Prepare to wait.
268 KThread* cur_thread = GetCurrentThreadPointer(kernel); 268 KThread* cur_thread = GetCurrentThreadPointer(kernel);
269 KHardwareTimer* timer{};
269 ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue( 270 ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue(
270 kernel, std::addressof(thread_tree)); 271 kernel, std::addressof(thread_tree));
271 272
272 { 273 {
273 KScopedSchedulerLockAndSleep slp(kernel, cur_thread, timeout); 274 KScopedSchedulerLockAndSleep slp(kernel, std::addressof(timer), cur_thread, timeout);
274 275
275 // Check that the thread isn't terminating. 276 // Check that the thread isn't terminating.
276 if (cur_thread->IsTerminationRequested()) { 277 if (cur_thread->IsTerminationRequested()) {
@@ -320,6 +321,7 @@ Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) {
320 thread_tree.insert(*cur_thread); 321 thread_tree.insert(*cur_thread);
321 322
322 // Begin waiting. 323 // Begin waiting.
324 wait_queue.SetHardwareTimer(timer);
323 cur_thread->BeginWait(std::addressof(wait_queue)); 325 cur_thread->BeginWait(std::addressof(wait_queue));
324 cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar); 326 cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar);
325 cur_thread->SetMutexWaitAddressForDebugging(addr); 327 cur_thread->SetMutexWaitAddressForDebugging(addr);
diff --git a/src/core/hle/kernel/k_light_condition_variable.cpp b/src/core/hle/kernel/k_light_condition_variable.cpp
index cade99cfd..8fce2bc71 100644
--- a/src/core/hle/kernel/k_light_condition_variable.cpp
+++ b/src/core/hle/kernel/k_light_condition_variable.cpp
@@ -40,13 +40,14 @@ private:
40void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_terminating_thread) { 40void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_terminating_thread) {
41 // Create thread queue. 41 // Create thread queue.
42 KThread* owner = GetCurrentThreadPointer(kernel); 42 KThread* owner = GetCurrentThreadPointer(kernel);
43 KHardwareTimer* timer{};
43 44
44 ThreadQueueImplForKLightConditionVariable wait_queue(kernel, std::addressof(wait_list), 45 ThreadQueueImplForKLightConditionVariable wait_queue(kernel, std::addressof(wait_list),
45 allow_terminating_thread); 46 allow_terminating_thread);
46 47
47 // Sleep the thread. 48 // Sleep the thread.
48 { 49 {
49 KScopedSchedulerLockAndSleep lk(kernel, owner, timeout); 50 KScopedSchedulerLockAndSleep lk(kernel, std::addressof(timer), owner, timeout);
50 51
51 if (!allow_terminating_thread && owner->IsTerminationRequested()) { 52 if (!allow_terminating_thread && owner->IsTerminationRequested()) {
52 lk.CancelSleep(); 53 lk.CancelSleep();
@@ -59,6 +60,7 @@ void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_ter
59 wait_list.push_back(*owner); 60 wait_list.push_back(*owner);
60 61
61 // Begin waiting. 62 // Begin waiting.
63 wait_queue.SetHardwareTimer(timer);
62 owner->BeginWait(std::addressof(wait_queue)); 64 owner->BeginWait(std::addressof(wait_queue));
63 } 65 }
64 66
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
index 76db65a4d..14b83a819 100644
--- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
+++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
@@ -13,16 +13,22 @@ namespace Kernel {
13 13
14class [[nodiscard]] KScopedSchedulerLockAndSleep { 14class [[nodiscard]] KScopedSchedulerLockAndSleep {
15public: 15public:
16 explicit KScopedSchedulerLockAndSleep(KernelCore& kernel_, KThread* t, s64 timeout) 16 explicit KScopedSchedulerLockAndSleep(KernelCore& kernel_, KHardwareTimer** out_timer,
17 : kernel(kernel_), thread(t), timeout_tick(timeout) { 17 KThread* t, s64 timeout)
18 : kernel(kernel_), timeout_tick(timeout), thread(t), timer() {
18 // Lock the scheduler. 19 // Lock the scheduler.
19 kernel.GlobalSchedulerContext().scheduler_lock.Lock(); 20 kernel.GlobalSchedulerContext().scheduler_lock.Lock();
21
22 // Set our timer only if the time is positive.
23 timer = (timeout_tick > 0) ? std::addressof(kernel.HardwareTimer()) : nullptr;
24
25 *out_timer = timer;
20 } 26 }
21 27
22 ~KScopedSchedulerLockAndSleep() { 28 ~KScopedSchedulerLockAndSleep() {
23 // Register the sleep. 29 // Register the sleep.
24 if (timeout_tick > 0) { 30 if (timeout_tick > 0) {
25 kernel.HardwareTimer().RegisterTask(thread, timeout_tick); 31 timer->RegisterTask(thread, timeout_tick);
26 } 32 }
27 33
28 // Unlock the scheduler. 34 // Unlock the scheduler.
@@ -35,8 +41,9 @@ public:
35 41
36private: 42private:
37 KernelCore& kernel; 43 KernelCore& kernel;
38 KThread* thread{};
39 s64 timeout_tick{}; 44 s64 timeout_tick{};
45 KThread* thread{};
46 KHardwareTimer* timer{};
40}; 47};
41 48
42} // namespace Kernel 49} // namespace Kernel
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp
index 802dca046..40fd0c038 100644
--- a/src/core/hle/kernel/k_synchronization_object.cpp
+++ b/src/core/hle/kernel/k_synchronization_object.cpp
@@ -79,12 +79,13 @@ Result KSynchronizationObject::Wait(KernelCore& kernel_ctx, s32* out_index,
79 79
80 // Prepare for wait. 80 // Prepare for wait.
81 KThread* thread = GetCurrentThreadPointer(kernel_ctx); 81 KThread* thread = GetCurrentThreadPointer(kernel_ctx);
82 KHardwareTimer* timer{};
82 ThreadQueueImplForKSynchronizationObjectWait wait_queue(kernel_ctx, objects, 83 ThreadQueueImplForKSynchronizationObjectWait wait_queue(kernel_ctx, objects,
83 thread_nodes.data(), num_objects); 84 thread_nodes.data(), num_objects);
84 85
85 { 86 {
86 // Setup the scheduling lock and sleep. 87 // Setup the scheduling lock and sleep.
87 KScopedSchedulerLockAndSleep slp(kernel_ctx, thread, timeout); 88 KScopedSchedulerLockAndSleep slp(kernel_ctx, std::addressof(timer), thread, timeout);
88 89
89 // Check if the thread should terminate. 90 // Check if the thread should terminate.
90 if (thread->IsTerminationRequested()) { 91 if (thread->IsTerminationRequested()) {
@@ -131,6 +132,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel_ctx, s32* out_index,
131 thread->SetSyncedIndex(-1); 132 thread->SetSyncedIndex(-1);
132 133
133 // Wait for an object to be signaled. 134 // Wait for an object to be signaled.
135 wait_queue.SetHardwareTimer(timer);
134 thread->BeginWait(std::addressof(wait_queue)); 136 thread->BeginWait(std::addressof(wait_queue));
135 thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Synchronization); 137 thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Synchronization);
136 } 138 }
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 15ae652f9..26e3700e4 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -1290,9 +1290,10 @@ Result KThread::Sleep(s64 timeout) {
1290 ASSERT(timeout > 0); 1290 ASSERT(timeout > 0);
1291 1291
1292 ThreadQueueImplForKThreadSleep wait_queue_(kernel); 1292 ThreadQueueImplForKThreadSleep wait_queue_(kernel);
1293 KHardwareTimer* timer{};
1293 { 1294 {
1294 // Setup the scheduling lock and sleep. 1295 // Setup the scheduling lock and sleep.
1295 KScopedSchedulerLockAndSleep slp(kernel, this, timeout); 1296 KScopedSchedulerLockAndSleep slp(kernel, std::addressof(timer), this, timeout);
1296 1297
1297 // Check if the thread should terminate. 1298 // Check if the thread should terminate.
1298 if (this->IsTerminationRequested()) { 1299 if (this->IsTerminationRequested()) {
@@ -1301,6 +1302,7 @@ Result KThread::Sleep(s64 timeout) {
1301 } 1302 }
1302 1303
1303 // Wait for the sleep to end. 1304 // Wait for the sleep to end.
1305 wait_queue_.SetHardwareTimer(timer);
1304 this->BeginWait(std::addressof(wait_queue_)); 1306 this->BeginWait(std::addressof(wait_queue_));
1305 SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep); 1307 SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep);
1306 } 1308 }
diff --git a/src/core/hle/kernel/k_thread_queue.cpp b/src/core/hle/kernel/k_thread_queue.cpp
index 5f1dc97eb..fe648447b 100644
--- a/src/core/hle/kernel/k_thread_queue.cpp
+++ b/src/core/hle/kernel/k_thread_queue.cpp
@@ -22,7 +22,9 @@ void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) {
22 waiting_thread->ClearWaitQueue(); 22 waiting_thread->ClearWaitQueue();
23 23
24 // Cancel the thread task. 24 // Cancel the thread task.
25 kernel.HardwareTimer().CancelTask(waiting_thread); 25 if (m_hardware_timer != nullptr) {
26 m_hardware_timer->CancelTask(waiting_thread);
27 }
26} 28}
27 29
28void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) { 30void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) {
@@ -36,8 +38,8 @@ void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool
36 waiting_thread->ClearWaitQueue(); 38 waiting_thread->ClearWaitQueue();
37 39
38 // Cancel the thread task. 40 // Cancel the thread task.
39 if (cancel_timer_task) { 41 if (cancel_timer_task && m_hardware_timer != nullptr) {
40 kernel.HardwareTimer().CancelTask(waiting_thread); 42 m_hardware_timer->CancelTask(waiting_thread);
41 } 43 }
42} 44}
43 45
diff --git a/src/core/hle/kernel/k_thread_queue.h b/src/core/hle/kernel/k_thread_queue.h
index 8d76ece81..01e330e2e 100644
--- a/src/core/hle/kernel/k_thread_queue.h
+++ b/src/core/hle/kernel/k_thread_queue.h
@@ -8,11 +8,17 @@
8 8
9namespace Kernel { 9namespace Kernel {
10 10
11class KHardwareTimer;
12
11class KThreadQueue { 13class KThreadQueue {
12public: 14public:
13 explicit KThreadQueue(KernelCore& kernel_) : kernel{kernel_} {} 15 explicit KThreadQueue(KernelCore& kernel_) : kernel{kernel_}, m_hardware_timer{} {}
14 virtual ~KThreadQueue() = default; 16 virtual ~KThreadQueue() = default;
15 17
18 void SetHardwareTimer(KHardwareTimer* timer) {
19 m_hardware_timer = timer;
20 }
21
16 virtual void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, 22 virtual void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object,
17 Result wait_result); 23 Result wait_result);
18 virtual void EndWait(KThread* waiting_thread, Result wait_result); 24 virtual void EndWait(KThread* waiting_thread, Result wait_result);
@@ -20,7 +26,7 @@ public:
20 26
21private: 27private:
22 KernelCore& kernel; 28 KernelCore& kernel;
23 KThread::WaiterList wait_list{}; 29 KHardwareTimer* m_hardware_timer{};
24}; 30};
25 31
26class KThreadQueueWithoutEndWait : public KThreadQueue { 32class KThreadQueueWithoutEndWait : public KThreadQueue {