From c22bac6398ff1705992fc44b2c29775c84cff662 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 14 Jan 2015 19:22:50 -0500 Subject: Kernel: Added WaitObject and changed "waitable" objects inherit from it. --- src/core/hle/kernel/event.cpp | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 271190dbe..bf71e9edb 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -14,7 +14,7 @@ namespace Kernel { -class Event : public Object { +class Event : public WaitObject { public: std::string GetTypeName() const override { return "Event"; } std::string GetName() const override { return name; } @@ -27,16 +27,12 @@ public: bool locked; ///< Event signal wait bool permanent_locked; ///< Hack - to set event permanent state (for easy passthrough) - std::vector waiting_threads; ///< Threads that are waiting for the event std::string name; ///< Name of event (optional) ResultVal WaitSynchronization() override { bool wait = locked; if (locked) { - Handle thread = GetCurrentThread()->GetHandle(); - if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { - waiting_threads.push_back(thread); - } + AddWaitingThread(GetCurrentThread()); Kernel::WaitCurrentThread(WAITTYPE_EVENT, this); } if (reset_type != RESETTYPE_STICKY && !permanent_locked) { @@ -86,20 +82,12 @@ ResultCode SignalEvent(const Handle handle) { if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); // Resume threads waiting for event to signal - bool event_caught = false; - for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { - Thread* thread = Kernel::g_handle_table.Get(evt->waiting_threads[i]).get(); - if (thread != nullptr) - thread->ResumeFromWait(); - - // If any thread is signalled awake by this event, assume the event was "caught" and reset - // the event. This will result in the next thread waiting on the event to block. Otherwise, - // the event will not be reset, and the next thread to call WaitSynchronization on it will - // not block. Not sure if this is correct behavior, but it seems to work. - event_caught = true; - } - evt->waiting_threads.clear(); + bool event_caught = evt->ResumeAllWaitingThreads(); + // If any thread is signalled awake by this event, assume the event was "caught" and reset + // the event. This will result in the next thread waiting on the event to block. Otherwise, + // the event will not be reset, and the next thread to call WaitSynchronization on it will + // not block. Not sure if this is correct behavior, but it seems to work. if (!evt->permanent_locked) { evt->locked = event_caught; } -- cgit v1.2.3 From 14cbbf4d9b8e07f9f2d679bcf66c2180463ae57c Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 14 Jan 2015 23:33:37 -0500 Subject: Event: Get rid of permanent_lock hack. --- src/core/hle/kernel/event.cpp | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index bf71e9edb..9dd3d0f5d 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -26,7 +26,6 @@ public: ResetType reset_type; ///< Current ResetType bool locked; ///< Event signal wait - bool permanent_locked; ///< Hack - to set event permanent state (for easy passthrough) std::string name; ///< Name of event (optional) ResultVal WaitSynchronization() override { @@ -35,27 +34,13 @@ public: AddWaitingThread(GetCurrentThread()); Kernel::WaitCurrentThread(WAITTYPE_EVENT, this); } - if (reset_type != RESETTYPE_STICKY && !permanent_locked) { + if (reset_type != RESETTYPE_STICKY) { locked = true; } return MakeResult(wait); } }; -/** - * Hackish function to set an events permanent lock state, used to pass through synch blocks - * @param handle Handle to event to change - * @param permanent_locked Boolean permanent locked value to set event - * @return Result of operation, 0 on success, otherwise error code - */ -ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { - Event* evt = g_handle_table.Get(handle).get(); - if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); - - evt->permanent_locked = permanent_locked; - return RESULT_SUCCESS; -} - /** * Changes whether an event is locked or not * @param handle Handle to event to change @@ -66,9 +51,8 @@ ResultCode SetEventLocked(const Handle handle, const bool locked) { Event* evt = g_handle_table.Get(handle).get(); if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); - if (!evt->permanent_locked) { - evt->locked = locked; - } + evt->locked = locked; + return RESULT_SUCCESS; } @@ -81,16 +65,13 @@ ResultCode SignalEvent(const Handle handle) { Event* evt = g_handle_table.Get(handle).get(); if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); - // Resume threads waiting for event to signal - bool event_caught = evt->ResumeAllWaitingThreads(); - // If any thread is signalled awake by this event, assume the event was "caught" and reset // the event. This will result in the next thread waiting on the event to block. Otherwise, // the event will not be reset, and the next thread to call WaitSynchronization on it will // not block. Not sure if this is correct behavior, but it seems to work. - if (!evt->permanent_locked) { - evt->locked = event_caught; - } + // TODO(bunnei): Test how this works on hardware + evt->locked = evt->ResumeAllWaitingThreads(); + return RESULT_SUCCESS; } @@ -103,9 +84,8 @@ ResultCode ClearEvent(Handle handle) { Event* evt = g_handle_table.Get(handle).get(); if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); - if (!evt->permanent_locked) { - evt->locked = true; - } + evt->locked = true; + return RESULT_SUCCESS; } @@ -123,7 +103,6 @@ Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE); evt->locked = true; - evt->permanent_locked = false; evt->reset_type = evt->intitial_reset_type = reset_type; evt->name = name; -- cgit v1.2.3 From e4a5d8ad4f708c9674c9865eb872e3c081d9a8c8 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 15 Jan 2015 19:29:46 -0500 Subject: Event: Fixed some bugs and cleanup (Subv) --- src/core/hle/kernel/event.cpp | 58 ++++++++----------------------------------- 1 file changed, 11 insertions(+), 47 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 9dd3d0f5d..540199e03 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -25,66 +25,36 @@ public: ResetType intitial_reset_type; ///< ResetType specified at Event initialization ResetType reset_type; ///< Current ResetType - bool locked; ///< Event signal wait + bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) ResultVal WaitSynchronization() override { - bool wait = locked; - if (locked) { + bool wait = !signaled; + if (wait) { AddWaitingThread(GetCurrentThread()); Kernel::WaitCurrentThread(WAITTYPE_EVENT, this); } - if (reset_type != RESETTYPE_STICKY) { - locked = true; - } return MakeResult(wait); } }; -/** - * Changes whether an event is locked or not - * @param handle Handle to event to change - * @param locked Boolean locked value to set event - * @return Result of operation, 0 on success, otherwise error code - */ -ResultCode SetEventLocked(const Handle handle, const bool locked) { - Event* evt = g_handle_table.Get(handle).get(); - if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); - - evt->locked = locked; - - return RESULT_SUCCESS; -} - -/** - * Signals an event - * @param handle Handle to event to signal - * @return Result of operation, 0 on success, otherwise error code - */ ResultCode SignalEvent(const Handle handle) { Event* evt = g_handle_table.Get(handle).get(); - if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); + if (evt == nullptr) + return InvalidHandle(ErrorModule::Kernel); - // If any thread is signalled awake by this event, assume the event was "caught" and reset - // the event. This will result in the next thread waiting on the event to block. Otherwise, - // the event will not be reset, and the next thread to call WaitSynchronization on it will - // not block. Not sure if this is correct behavior, but it seems to work. - // TODO(bunnei): Test how this works on hardware - evt->locked = evt->ResumeAllWaitingThreads(); + evt->signaled = true; + evt->ReleaseAllWaitingThreads(); return RESULT_SUCCESS; } -/** - * Clears an event - * @param handle Handle to event to clear - * @return Result of operation, 0 on success, otherwise error code - */ ResultCode ClearEvent(Handle handle) { Event* evt = g_handle_table.Get(handle).get(); - if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); + if (evt == nullptr) + return InvalidHandle(ErrorModule::Kernel); - evt->locked = true; + evt->signaled = false; return RESULT_SUCCESS; } @@ -102,19 +72,13 @@ Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string // TOOD(yuriks): Fix error reporting handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE); - evt->locked = true; + evt->signaled = false; evt->reset_type = evt->intitial_reset_type = reset_type; evt->name = name; return evt; } -/** - * Creates an event - * @param reset_type ResetType describing how to create event - * @param name Optional name of event - * @return Handle to newly created Event object - */ Handle CreateEvent(const ResetType reset_type, const std::string& name) { Handle handle; Event* evt = CreateEvent(handle, reset_type, name); -- cgit v1.2.3 From 7faf2d8e06e705d1866fa0d7848ff43541a4b172 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 17 Jan 2015 02:03:44 -0500 Subject: WaitSynchronizationN: Implement return values --- src/core/hle/kernel/event.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 540199e03..4173a980b 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,11 +28,11 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal WaitSynchronization() override { + ResultVal WaitSynchronization(unsigned index) override { bool wait = !signaled; if (wait) { AddWaitingThread(GetCurrentThread()); - Kernel::WaitCurrentThread(WAITTYPE_EVENT, this); + Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_EVENT, this, index); } return MakeResult(wait); } -- cgit v1.2.3 From aa01c57ae9d73e41b65d37860ca6fbb91caba33a Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 17 Jan 2015 22:23:49 -0500 Subject: Kernel: Separate WaitSynchronization into Wait and Acquire methods. --- src/core/hle/kernel/event.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 4173a980b..41e1bd6c5 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,7 +28,7 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal WaitSynchronization(unsigned index) override { + ResultVal Wait(unsigned index) override { bool wait = !signaled; if (wait) { AddWaitingThread(GetCurrentThread()); @@ -36,6 +36,10 @@ public: } return MakeResult(wait); } + + ResultVal Acquire() override { + return MakeResult(true); + } }; ResultCode SignalEvent(const Handle handle) { -- cgit v1.2.3 From 6643673f28b9273149fc945849a13ed832e9ef33 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 18 Jan 2015 01:27:46 -0500 Subject: WaitSynchronizationN: Refactor to fix several bugs - Separate wait checking from waiting the current thread - Resume thread when wait_all=true only if all objects are available at once - Set output to correct wait object index when there are duplicate handles --- src/core/hle/kernel/event.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 41e1bd6c5..ae9b06b84 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,11 +28,11 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal Wait(unsigned index) override { + ResultVal Wait(bool wait_thread) override { bool wait = !signaled; - if (wait) { + if (wait && wait_thread) { AddWaitingThread(GetCurrentThread()); - Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_EVENT, this, index); + Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_EVENT, this); } return MakeResult(wait); } -- cgit v1.2.3 From e5a9f1c64483e01b7856c581ae5685d0c5ad88dc Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 18 Jan 2015 13:25:51 -0500 Subject: Kernel: Get rid of WaitTypes and simplify lots of code, removing hacks. --- src/core/hle/kernel/event.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index ae9b06b84..399730cb1 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,13 +28,8 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal Wait(bool wait_thread) override { - bool wait = !signaled; - if (wait && wait_thread) { - AddWaitingThread(GetCurrentThread()); - Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_EVENT, this); - } - return MakeResult(wait); + ResultVal Wait() override { + return MakeResult(!signaled); } ResultVal Acquire() override { -- cgit v1.2.3 From 69c5830ef2a0190803e176615d5cb16d5462b971 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 19 Jan 2015 03:30:55 -0500 Subject: Event: Fix implementation of "non-sticky" events. --- src/core/hle/kernel/event.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 399730cb1..37f01652e 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -33,6 +33,10 @@ public: } ResultVal Acquire() override { + // Release the event if it's not sticky... + if (reset_type != RESETTYPE_STICKY) + signaled = false; + return MakeResult(true); } }; -- cgit v1.2.3 From c68eb1569549ae49ae25c6c29cec2e10d8329f2d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jan 2015 17:41:12 -0500 Subject: WaitObject: Renamed "Wait" to "ShouldWait", made "ShouldWait" and "Acquire" pure virtual. --- src/core/hle/kernel/event.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 37f01652e..bed856020 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,7 +28,7 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal Wait() override { + ResultVal ShouldWait() override { return MakeResult(!signaled); } -- cgit v1.2.3 From 15b6a4d9add6b260a2a1a84ab6228addced4f851 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jan 2015 18:16:45 -0500 Subject: Kernel: Changed "ShouldWait" to return bool and "Acquire" to return void. --- src/core/hle/kernel/event.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index bed856020..cdacba1d9 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,16 +28,16 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal ShouldWait() override { - return MakeResult(!signaled); + bool ShouldWait() override { + return !signaled; } - ResultVal Acquire() override { + void Acquire() override { + _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + // Release the event if it's not sticky... if (reset_type != RESETTYPE_STICKY) signaled = false; - - return MakeResult(true); } }; -- cgit v1.2.3 From f09806aed24b2f7de7d969cbfdb3b9d18ab90c61 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jan 2015 18:20:47 -0500 Subject: Kernel: Renamed some functions for clarity. - ReleaseNextThread->WakeupNextThread - ReleaseAllWaitingThreads->WakeupAllWaitingThreads. --- src/core/hle/kernel/event.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/event.cpp') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index cdacba1d9..a48125965 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -47,7 +47,7 @@ ResultCode SignalEvent(const Handle handle) { return InvalidHandle(ErrorModule::Kernel); evt->signaled = true; - evt->ReleaseAllWaitingThreads(); + evt->WakeupAllWaitingThreads(); return RESULT_SUCCESS; } -- cgit v1.2.3