summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-01-18 14:33:11 -0500
committerGravatar bunnei2015-01-21 20:47:46 -0500
commit9412996c8f86f5da5a9052f7533b05e9780c4eb0 (patch)
treeaf0ddc0b464d92c7e13664f6f435c5de6c36301a /src
parentSVC: Removed a Sleep that made no sense (diff)
downloadyuzu-9412996c8f86f5da5a9052f7533b05e9780c4eb0.tar.gz
yuzu-9412996c8f86f5da5a9052f7533b05e9780c4eb0.tar.xz
yuzu-9412996c8f86f5da5a9052f7533b05e9780c4eb0.zip
Kernel: Moved Wait and Acquire to WaitObject, added way to retrieve a WaitObject safely.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/kernel.h71
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/kernel/thread.h2
-rw-r--r--src/core/hle/svc.cpp4
4 files changed, 59 insertions, 20 deletions
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 5bf9a2bfc..a9a893f41 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -60,26 +60,34 @@ class Object : NonCopyable {
60public: 60public:
61 virtual ~Object() {} 61 virtual ~Object() {}
62 Handle GetHandle() const { return handle; } 62 Handle GetHandle() const { return handle; }
63
63 virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } 64 virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; }
64 virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } 65 virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; }
65 virtual Kernel::HandleType GetHandleType() const = 0; 66 virtual Kernel::HandleType GetHandleType() const = 0;
66 67
67 /** 68 /**
68 * Check if this object is available 69 * Check if a thread can wait on the object
69 * @return True if the current thread should wait due to this object being unavailable 70 * @return True if a thread can wait on the object, otherwise false
70 */ 71 */
71 virtual ResultVal<bool> Wait() { 72 bool IsWaitable() const {
72 LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); 73 switch (GetHandleType()) {
73 return UnimplementedFunction(ErrorModule::Kernel); 74 case HandleType::Event:
74 } 75 case HandleType::Mutex:
76 case HandleType::Thread:
77 case HandleType::Semaphore:
78 case HandleType::Timer:
79 return true;
80
81 case HandleType::Unknown:
82 case HandleType::Port:
83 case HandleType::SharedMemory:
84 case HandleType::Redirection:
85 case HandleType::Process:
86 case HandleType::AddressArbiter:
87 return false;
88 }
75 89
76 /** 90 return false;
77 * Acquire/lock the this object if it is available
78 * @return True if we were able to acquire this object, otherwise false
79 */
80 virtual ResultVal<bool> Acquire() {
81 LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
82 return UnimplementedFunction(ErrorModule::Kernel);
83 } 91 }
84 92
85private: 93private:
@@ -108,6 +116,24 @@ class WaitObject : public Object {
108public: 116public:
109 117
110 /** 118 /**
119 * Check if this object is available
120 * @return True if the current thread should wait due to this object being unavailable
121 */
122 virtual ResultVal<bool> Wait() {
123 LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
124 return UnimplementedFunction(ErrorModule::Kernel);
125 }
126
127 /**
128 * Acquire/lock the this object if it is available
129 * @return True if we were able to acquire this object, otherwise false
130 */
131 virtual ResultVal<bool> Acquire() {
132 LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
133 return UnimplementedFunction(ErrorModule::Kernel);
134 }
135
136 /**
111 * Add a thread to wait on this object 137 * Add a thread to wait on this object
112 * @param thread Pointer to thread to add 138 * @param thread Pointer to thread to add
113 */ 139 */
@@ -186,14 +212,14 @@ public:
186 212
187 /** 213 /**
188 * Looks up a handle. 214 * Looks up a handle.
189 * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. 215 * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
190 */ 216 */
191 SharedPtr<Object> GetGeneric(Handle handle) const; 217 SharedPtr<Object> GetGeneric(Handle handle) const;
192 218
193 /** 219 /**
194 * Looks up a handle while verifying its type. 220 * Looks up a handle while verifying its type.
195 * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid or its 221 * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
196 * type differs from the handle type `T::HANDLE_TYPE`. 222 * type differs from the handle type `T::HANDLE_TYPE`.
197 */ 223 */
198 template <class T> 224 template <class T>
199 SharedPtr<T> Get(Handle handle) const { 225 SharedPtr<T> Get(Handle handle) const {
@@ -204,6 +230,19 @@ public:
204 return nullptr; 230 return nullptr;
205 } 231 }
206 232
233 /**
234 * Looks up a handle while verifying that it is an object that a thread can wait on
235 * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or it is
236 * not a waitable object.
237 */
238 SharedPtr<WaitObject> GetWaitObject(Handle handle) const {
239 SharedPtr<Object> object = GetGeneric(handle);
240 if (object != nullptr && object->IsWaitable()) {
241 return boost::static_pointer_cast<WaitObject>(std::move(object));
242 }
243 return nullptr;
244 }
245
207 /// Closes all handles held in this table. 246 /// Closes all handles held in this table.
208 void Clear(); 247 void Clear();
209 248
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 16865ccc4..271828ea7 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -210,7 +210,7 @@ void WaitCurrentThread_Sleep() {
210 ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); 210 ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND)));
211} 211}
212 212
213void WaitCurrentThread_WaitSynchronization(WaitObject* wait_object, bool wait_all) { 213void WaitCurrentThread_WaitSynchronization(SharedPtr<WaitObject> wait_object, bool wait_all) {
214 Thread* thread = GetCurrentThread(); 214 Thread* thread = GetCurrentThread();
215 thread->wait_all = wait_all; 215 thread->wait_all = wait_all;
216 thread->wait_address = 0; 216 thread->wait_address = 0;
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 9907aa6e1..a3a17e6c0 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -136,7 +136,7 @@ void WaitCurrentThread_Sleep();
136 * @param wait_object Kernel object that we are waiting on 136 * @param wait_object Kernel object that we are waiting on
137 * @param wait_all If true, wait on all objects before resuming (for WaitSynchronizationN only) 137 * @param wait_all If true, wait on all objects before resuming (for WaitSynchronizationN only)
138 */ 138 */
139void WaitCurrentThread_WaitSynchronization(WaitObject* wait_object, bool wait_all=false); 139void WaitCurrentThread_WaitSynchronization(SharedPtr<WaitObject> wait_object, bool wait_all = false);
140 140
141/** 141/**
142 * Waits the current thread from an ArbitrateAddress call 142 * Waits the current thread from an ArbitrateAddress call
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 5e9c38973..8df861669 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -115,7 +115,7 @@ static Result CloseHandle(Handle handle) {
115 115
116/// Wait for a handle to synchronize, timeout after the specified nanoseconds 116/// Wait for a handle to synchronize, timeout after the specified nanoseconds
117static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { 117static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
118 Kernel::WaitObject* object = static_cast<Kernel::WaitObject*>(Kernel::g_handle_table.GetGeneric(handle).get()); 118 auto object = Kernel::g_handle_table.GetWaitObject(handle);
119 if (object == nullptr) 119 if (object == nullptr)
120 return InvalidHandle(ErrorModule::Kernel).raw; 120 return InvalidHandle(ErrorModule::Kernel).raw;
121 121
@@ -163,7 +163,7 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
163 if (handle_count != 0) { 163 if (handle_count != 0) {
164 bool selected = false; // True once an object has been selected 164 bool selected = false; // True once an object has been selected
165 for (int i = 0; i < handle_count; ++i) { 165 for (int i = 0; i < handle_count; ++i) {
166 Kernel::WaitObject* object = static_cast<Kernel::WaitObject*>(Kernel::g_handle_table.GetGeneric(handles[i]).get()); 166 auto object = Kernel::g_handle_table.GetWaitObject(handles[i]);
167 if (object == nullptr) 167 if (object == nullptr)
168 return InvalidHandle(ErrorModule::Kernel).raw; 168 return InvalidHandle(ErrorModule::Kernel).raw;
169 169