summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/synchronization.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/synchronization.cpp')
-rw-r--r--src/core/hle/kernel/synchronization.cpp116
1 files changed, 0 insertions, 116 deletions
diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp
deleted file mode 100644
index d3f520ea2..000000000
--- a/src/core/hle/kernel/synchronization.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/core.h"
6#include "core/hle/kernel/errors.h"
7#include "core/hle/kernel/handle_table.h"
8#include "core/hle/kernel/k_scheduler.h"
9#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
10#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/synchronization.h"
12#include "core/hle/kernel/synchronization_object.h"
13#include "core/hle/kernel/thread.h"
14#include "core/hle/kernel/time_manager.h"
15
16namespace Kernel {
17
18Synchronization::Synchronization(Core::System& system) : system{system} {}
19
20void Synchronization::SignalObject(SynchronizationObject& obj) const {
21 auto& kernel = system.Kernel();
22 KScopedSchedulerLock lock(kernel);
23 if (obj.IsSignaled()) {
24 for (auto thread : obj.GetWaitingThreads()) {
25 if (thread->GetSchedulingStatus() == ThreadSchedStatus::Paused) {
26 if (thread->GetStatus() != ThreadStatus::WaitHLEEvent) {
27 ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
28 ASSERT(thread->IsWaitingSync());
29 }
30 thread->SetSynchronizationResults(&obj, RESULT_SUCCESS);
31 thread->ResumeFromWait();
32 }
33 }
34 obj.ClearWaitingThreads();
35 }
36}
37
38std::pair<ResultCode, Handle> Synchronization::WaitFor(
39 std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) {
40 auto& kernel = system.Kernel();
41 auto* const thread = kernel.CurrentScheduler()->GetCurrentThread();
42 Handle event_handle = InvalidHandle;
43 {
44 KScopedSchedulerLockAndSleep lock(kernel, event_handle, thread, nano_seconds);
45 const auto itr =
46 std::find_if(sync_objects.begin(), sync_objects.end(),
47 [thread](const std::shared_ptr<SynchronizationObject>& object) {
48 return object->IsSignaled();
49 });
50
51 if (itr != sync_objects.end()) {
52 // We found a ready object, acquire it and set the result value
53 SynchronizationObject* object = itr->get();
54 object->Acquire(thread);
55 const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr));
56 lock.CancelSleep();
57 return {RESULT_SUCCESS, index};
58 }
59
60 if (nano_seconds == 0) {
61 lock.CancelSleep();
62 return {RESULT_TIMEOUT, InvalidHandle};
63 }
64
65 if (thread->IsPendingTermination()) {
66 lock.CancelSleep();
67 return {ERR_THREAD_TERMINATING, InvalidHandle};
68 }
69
70 if (thread->IsSyncCancelled()) {
71 thread->SetSyncCancelled(false);
72 lock.CancelSleep();
73 return {ERR_SYNCHRONIZATION_CANCELED, InvalidHandle};
74 }
75
76 for (auto& object : sync_objects) {
77 object->AddWaitingThread(SharedFrom(thread));
78 }
79
80 thread->SetSynchronizationObjects(&sync_objects);
81 thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
82 thread->SetStatus(ThreadStatus::WaitSynch);
83 thread->SetWaitingSync(true);
84 }
85 thread->SetWaitingSync(false);
86
87 if (event_handle != InvalidHandle) {
88 auto& time_manager = kernel.TimeManager();
89 time_manager.UnscheduleTimeEvent(event_handle);
90 }
91
92 {
93 KScopedSchedulerLock lock(kernel);
94 ResultCode signaling_result = thread->GetSignalingResult();
95 SynchronizationObject* signaling_object = thread->GetSignalingObject();
96 thread->SetSynchronizationObjects(nullptr);
97 auto shared_thread = SharedFrom(thread);
98 for (auto& obj : sync_objects) {
99 obj->RemoveWaitingThread(shared_thread);
100 }
101 if (signaling_object != nullptr) {
102 const auto itr = std::find_if(
103 sync_objects.begin(), sync_objects.end(),
104 [signaling_object](const std::shared_ptr<SynchronizationObject>& object) {
105 return object.get() == signaling_object;
106 });
107 ASSERT(itr != sync_objects.end());
108 signaling_object->Acquire(thread);
109 const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr));
110 return {signaling_result, index};
111 }
112 return {signaling_result, -1};
113 }
114}
115
116} // namespace Kernel