mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 10:44:49 +01:00 
			
		
		
		
	kernel: Rename Semaphore to ConditionVariable.
This commit is contained in:
		
							parent
							
								
									9fcd2bf672
								
							
						
					
					
						commit
						4236799832
					
				| @ -5,9 +5,9 @@ | ||||
| #include "citra_qt/debugger/wait_tree.h" | ||||
| #include "citra_qt/util/util.h" | ||||
| 
 | ||||
| #include "core/hle/kernel/condition_variable.h" | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/mutex.h" | ||||
| #include "core/hle/kernel/semaphore.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/kernel/timer.h" | ||||
| #include "core/hle/kernel/wait_object.h" | ||||
| @ -85,8 +85,9 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO | ||||
|         return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object)); | ||||
|     case Kernel::HandleType::Mutex: | ||||
|         return std::make_unique<WaitTreeMutex>(static_cast<const Kernel::Mutex&>(object)); | ||||
|     case Kernel::HandleType::Semaphore: | ||||
|         return std::make_unique<WaitTreeSemaphore>(static_cast<const Kernel::Semaphore&>(object)); | ||||
|     case Kernel::HandleType::ConditionVariable: | ||||
|         return std::make_unique<WaitTreeConditionVariable>( | ||||
|             static_cast<const Kernel::ConditionVariable&>(object)); | ||||
|     case Kernel::HandleType::Timer: | ||||
|         return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); | ||||
|     case Kernel::HandleType::Thread: | ||||
| @ -266,15 +267,15 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutex::GetChildren() const { | ||||
|     return list; | ||||
| } | ||||
| 
 | ||||
| WaitTreeSemaphore::WaitTreeSemaphore(const Kernel::Semaphore& object) | ||||
| WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object) | ||||
|     : WaitTreeWaitObject(object) {} | ||||
| 
 | ||||
| std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSemaphore::GetChildren() const { | ||||
| std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeConditionVariable::GetChildren() const { | ||||
|     std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); | ||||
| 
 | ||||
|     const auto& semaphore = static_cast<const Kernel::Semaphore&>(object); | ||||
|     const auto& condition_variable = static_cast<const Kernel::ConditionVariable&>(object); | ||||
|     list.push_back(std::make_unique<WaitTreeText>( | ||||
|         tr("available count = %1").arg(semaphore.GetAvailableCount()))); | ||||
|         tr("available count = %1").arg(condition_variable.GetAvailableCount()))); | ||||
|     return list; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -17,7 +17,7 @@ namespace Kernel { | ||||
| class WaitObject; | ||||
| class Event; | ||||
| class Mutex; | ||||
| class Semaphore; | ||||
| class ConditionVariable; | ||||
| class Thread; | ||||
| class Timer; | ||||
| } | ||||
| @ -111,10 +111,10 @@ public: | ||||
|     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||||
| }; | ||||
| 
 | ||||
| class WaitTreeSemaphore : public WaitTreeWaitObject { | ||||
| class WaitTreeConditionVariable : public WaitTreeWaitObject { | ||||
|     Q_OBJECT | ||||
| public: | ||||
|     explicit WaitTreeSemaphore(const Kernel::Semaphore& object); | ||||
|     explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object); | ||||
|     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -16,6 +16,7 @@ set(SRCS | ||||
|             hle/kernel/address_arbiter.cpp | ||||
|             hle/kernel/client_port.cpp | ||||
|             hle/kernel/client_session.cpp | ||||
|             hle/kernel/condition_variable.cpp | ||||
|             hle/kernel/domain.cpp | ||||
|             hle/kernel/event.cpp | ||||
|             hle/kernel/handle_table.cpp | ||||
| @ -26,7 +27,6 @@ set(SRCS | ||||
|             hle/kernel/object_address_table.cpp | ||||
|             hle/kernel/process.cpp | ||||
|             hle/kernel/resource_limit.cpp | ||||
|             hle/kernel/semaphore.cpp | ||||
|             hle/kernel/server_port.cpp | ||||
|             hle/kernel/server_session.cpp | ||||
|             hle/kernel/shared_memory.cpp | ||||
| @ -94,6 +94,7 @@ set(HEADERS | ||||
|             hle/kernel/address_arbiter.h | ||||
|             hle/kernel/client_port.h | ||||
|             hle/kernel/client_session.h | ||||
|             hle/kernel/condition_variable.h | ||||
|             hle/kernel/domain.h | ||||
|             hle/kernel/errors.h | ||||
|             hle/kernel/event.h | ||||
| @ -105,7 +106,6 @@ set(HEADERS | ||||
|             hle/kernel/object_address_table.h | ||||
|             hle/kernel/process.h | ||||
|             hle/kernel/resource_limit.h | ||||
|             hle/kernel/semaphore.h | ||||
|             hle/kernel/server_port.h | ||||
|             hle/kernel/server_session.h | ||||
|             hle/kernel/session.h | ||||
|  | ||||
							
								
								
									
										65
									
								
								src/core/hle/kernel/condition_variable.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/core/hle/kernel/condition_variable.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "core/hle/kernel/condition_variable.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/object_address_table.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| ConditionVariable::ConditionVariable() {} | ||||
| ConditionVariable::~ConditionVariable() {} | ||||
| 
 | ||||
| ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, | ||||
|                                                                   VAddr mutex_addr, | ||||
|                                                                   std::string name) { | ||||
|     SharedPtr<ConditionVariable> condition_variable(new ConditionVariable); | ||||
| 
 | ||||
|     condition_variable->name = std::move(name); | ||||
|     condition_variable->guest_addr = guest_addr; | ||||
|     condition_variable->mutex_addr = mutex_addr; | ||||
| 
 | ||||
|     // Condition variables are referenced by guest address, so track this in the kernel
 | ||||
|     g_object_address_table.Insert(guest_addr, condition_variable); | ||||
| 
 | ||||
|     return MakeResult<SharedPtr<ConditionVariable>>(std::move(condition_variable)); | ||||
| } | ||||
| 
 | ||||
| bool ConditionVariable::ShouldWait(Thread* thread) const { | ||||
|     return GetAvailableCount() <= 0; | ||||
| } | ||||
| 
 | ||||
| void ConditionVariable::Acquire(Thread* thread) { | ||||
|     if (GetAvailableCount() <= 0) | ||||
|         return; | ||||
| 
 | ||||
|     SetAvailableCount(GetAvailableCount() - 1); | ||||
| } | ||||
| 
 | ||||
| ResultCode ConditionVariable::Release(s32 target) { | ||||
|     if (target == -1) { | ||||
|         // When -1, wake up all waiting threads
 | ||||
|         SetAvailableCount(GetWaitingThreads().size()); | ||||
|         WakeupAllWaitingThreads(); | ||||
|     } else { | ||||
|         // Otherwise, wake up just a single thread
 | ||||
|         SetAvailableCount(target); | ||||
|         WakeupWaitingThread(GetHighestPriorityReadyThread()); | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| s32 ConditionVariable::GetAvailableCount() const { | ||||
|     return Memory::Read32(guest_addr); | ||||
| } | ||||
| 
 | ||||
| void ConditionVariable::SetAvailableCount(s32 value) const { | ||||
|     Memory::Write32(guest_addr, value); | ||||
| } | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
							
								
								
									
										65
									
								
								src/core/hle/kernel/condition_variable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/core/hle/kernel/condition_variable.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <queue> | ||||
| #include <string> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/wait_object.h" | ||||
| #include "core/hle/result.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| class ConditionVariable final : public WaitObject { | ||||
| public: | ||||
|     /**
 | ||||
|      * Creates a condition variable. | ||||
|      * @param guest_addr Address of the object tracking the condition variable in guest memory. If | ||||
|      * specified, this condition variable will update the guest object when its state changes. | ||||
|      * @param mutex_addr Optional address of a guest mutex associated with this condition variable, | ||||
|      * used by the OS for implementing events. | ||||
|      * @param name Optional name of condition variable. | ||||
|      * @return The created condition variable. | ||||
|      */ | ||||
|     static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, VAddr mutex_addr = 0, | ||||
|                                                           std::string name = "Unknown"); | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
|         return "ConditionVariable"; | ||||
|     } | ||||
|     std::string GetName() const override { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     static const HandleType HANDLE_TYPE = HandleType::ConditionVariable; | ||||
|     HandleType GetHandleType() const override { | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
| 
 | ||||
|     s32 GetAvailableCount() const; | ||||
|     void SetAvailableCount(s32 value) const; | ||||
| 
 | ||||
|     std::string name; ///< Name of condition variable (optional)
 | ||||
|     VAddr guest_addr; ///< Address of the guest condition variable value
 | ||||
|     VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this condition
 | ||||
|                       ///< variable, used for implementing events
 | ||||
| 
 | ||||
|     bool ShouldWait(Thread* thread) const override; | ||||
|     void Acquire(Thread* thread) override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Releases a slot from a condition variable. | ||||
|      * @param target The number of threads to wakeup, -1 is all. | ||||
|      * @return ResultCode indicating if the operation succeeded. | ||||
|      */ | ||||
|     ResultCode Release(s32 target); | ||||
| 
 | ||||
| private: | ||||
|     ConditionVariable(); | ||||
|     ~ConditionVariable() override; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
| @ -23,7 +23,7 @@ enum class HandleType : u32 { | ||||
|     Thread, | ||||
|     Process, | ||||
|     AddressArbiter, | ||||
|     Semaphore, | ||||
|     ConditionVariable, | ||||
|     Timer, | ||||
|     ResourceLimit, | ||||
|     CodeSet, | ||||
| @ -70,7 +70,7 @@ public: | ||||
|         case HandleType::Event: | ||||
|         case HandleType::Mutex: | ||||
|         case HandleType::Thread: | ||||
|         case HandleType::Semaphore: | ||||
|         case HandleType::ConditionVariable: | ||||
|         case HandleType::Timer: | ||||
|         case HandleType::ServerPort: | ||||
|         case HandleType::ServerSession: | ||||
|  | ||||
| @ -1,64 +0,0 @@ | ||||
| // Copyright 2014 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "core/hle/kernel/errors.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/object_address_table.h" | ||||
| #include "core/hle/kernel/semaphore.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| Semaphore::Semaphore() {} | ||||
| Semaphore::~Semaphore() {} | ||||
| 
 | ||||
| ResultVal<SharedPtr<Semaphore>> Semaphore::Create(VAddr guest_addr, VAddr mutex_addr, | ||||
|                                                   std::string name) { | ||||
|     SharedPtr<Semaphore> semaphore(new Semaphore); | ||||
| 
 | ||||
|     semaphore->name = std::move(name); | ||||
|     semaphore->guest_addr = guest_addr; | ||||
|     semaphore->mutex_addr = mutex_addr; | ||||
| 
 | ||||
|     // Semaphores are referenced by guest address, so track this in the kernel
 | ||||
|     g_object_address_table.Insert(guest_addr, semaphore); | ||||
| 
 | ||||
|     return MakeResult<SharedPtr<Semaphore>>(std::move(semaphore)); | ||||
| } | ||||
| 
 | ||||
| bool Semaphore::ShouldWait(Thread* thread) const { | ||||
|     return GetAvailableCount() <= 0; | ||||
| } | ||||
| 
 | ||||
| void Semaphore::Acquire(Thread* thread) { | ||||
|     if (GetAvailableCount() <= 0) | ||||
|         return; | ||||
| 
 | ||||
|     SetAvailableCount(GetAvailableCount() - 1); | ||||
| } | ||||
| 
 | ||||
| ResultCode Semaphore::Release(s32 target) { | ||||
|     if (target == -1) { | ||||
|         // When -1, wake up all waiting threads
 | ||||
|         SetAvailableCount(GetWaitingThreads().size()); | ||||
|         WakeupAllWaitingThreads(); | ||||
|     } else { | ||||
|         // Otherwise, wake up just a single thread
 | ||||
|         SetAvailableCount(target); | ||||
|         WakeupWaitingThread(GetHighestPriorityReadyThread()); | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| s32 Semaphore::GetAvailableCount() const { | ||||
|     return Memory::Read32(guest_addr); | ||||
| } | ||||
| 
 | ||||
| void Semaphore::SetAvailableCount(s32 value) const { | ||||
|     Memory::Write32(guest_addr, value); | ||||
| } | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
| @ -1,66 +0,0 @@ | ||||
| // Copyright 2014 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <queue> | ||||
| #include <string> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/wait_object.h" | ||||
| #include "core/hle/result.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| // TODO(Subv): This is actually a Condition Variable.
 | ||||
| class Semaphore final : public WaitObject { | ||||
| public: | ||||
|     /**
 | ||||
|      * Creates a semaphore. | ||||
|      * @param guest_addr Address of the object tracking the semaphore in guest memory. If specified, | ||||
|      * this semaphore will update the guest object when its state changes. | ||||
|      * @param mutex_addr Optional address of a guest mutex associated with this semaphore, used by | ||||
|      * the OS for implementing events. | ||||
|      * @param name Optional name of semaphore. | ||||
|      * @return The created semaphore. | ||||
|      */ | ||||
|     static ResultVal<SharedPtr<Semaphore>> Create(VAddr guest_addr, VAddr mutex_addr = 0, | ||||
|                                                   std::string name = "Unknown"); | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
|         return "Semaphore"; | ||||
|     } | ||||
|     std::string GetName() const override { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     static const HandleType HANDLE_TYPE = HandleType::Semaphore; | ||||
|     HandleType GetHandleType() const override { | ||||
|         return HANDLE_TYPE; | ||||
|     } | ||||
| 
 | ||||
|     s32 GetAvailableCount() const; | ||||
|     void SetAvailableCount(s32 value) const; | ||||
| 
 | ||||
|     std::string name;    ///< Name of semaphore (optional)
 | ||||
|     VAddr guest_addr;    ///< Address of the guest semaphore value
 | ||||
|     VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this semaphore,
 | ||||
|                       ///< used for implementing events
 | ||||
| 
 | ||||
|     bool ShouldWait(Thread* thread) const override; | ||||
|     void Acquire(Thread* thread) override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Releases a slot from a semaphore. | ||||
|      * @param target The number of threads to wakeup, -1 is all. | ||||
|      * @return ResultCode indicating if the operation succeeded. | ||||
|      */ | ||||
|     ResultCode Release(s32 target); | ||||
| 
 | ||||
| private: | ||||
|     Semaphore(); | ||||
|     ~Semaphore() override; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Kernel
 | ||||
| @ -1,4 +1,4 @@ | ||||
| // Copyright 2014 Citra Emulator Project
 | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| @ -8,12 +8,12 @@ | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/client_session.h" | ||||
| #include "core/hle/kernel/condition_variable.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/mutex.h" | ||||
| #include "core/hle/kernel/object_address_table.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/resource_limit.h" | ||||
| #include "core/hle/kernel/semaphore.h" | ||||
| #include "core/hle/kernel/svc.h" | ||||
| #include "core/hle/kernel/svc_wrap.h" | ||||
| #include "core/hle/kernel/sync_object.h" | ||||
| @ -476,11 +476,12 @@ static void SleepThread(s64 nanoseconds) { | ||||
| } | ||||
| 
 | ||||
| /// Signal process wide key atomic
 | ||||
| static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_addr, | ||||
| static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, | ||||
|                                            Handle thread_handle, s64 nano_seconds) { | ||||
|     LOG_TRACE(Kernel_SVC, | ||||
|               "called mutex_addr=%llx, semaphore_addr=%llx, thread_handle=0x%08X, timeout=%d", | ||||
|               mutex_addr, semaphore_addr, thread_handle, nano_seconds); | ||||
|     LOG_TRACE( | ||||
|         Kernel_SVC, | ||||
|         "called mutex_addr=%llx, condition_variable_addr=%llx, thread_handle=0x%08X, timeout=%d", | ||||
|         mutex_addr, condition_variable_addr, thread_handle, nano_seconds); | ||||
| 
 | ||||
|     SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | ||||
|     ASSERT(thread); | ||||
| @ -494,15 +495,18 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add | ||||
| 
 | ||||
|     ASSERT(mutex->GetOwnerHandle() == thread_handle); | ||||
| 
 | ||||
|     SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr); | ||||
|     if (!semaphore) { | ||||
|         // Create a new semaphore for the specified address if one does not already exist
 | ||||
|         semaphore = Semaphore::Create(semaphore_addr, mutex_addr).Unwrap(); | ||||
|         semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr); | ||||
|     SharedPtr<ConditionVariable> condition_variable = | ||||
|         g_object_address_table.Get<ConditionVariable>(condition_variable_addr); | ||||
|     if (!condition_variable) { | ||||
|         // Create a new condition_variable for the specified address if one does not already exist
 | ||||
|         condition_variable = | ||||
|             ConditionVariable::Create(condition_variable_addr, mutex_addr).Unwrap(); | ||||
|         condition_variable->name = | ||||
|             Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(semaphore->GetAvailableCount() == 0); | ||||
|     ASSERT(semaphore->mutex_addr == mutex_addr); | ||||
|     ASSERT(condition_variable->GetAvailableCount() == 0); | ||||
|     ASSERT(condition_variable->mutex_addr == mutex_addr); | ||||
| 
 | ||||
|     auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, | ||||
|                                                  SharedPtr<Thread> thread, | ||||
| @ -541,7 +545,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add | ||||
| 
 | ||||
|         return false; | ||||
|     }; | ||||
|     CASCADE_CODE(WaitSynchronization1(semaphore, thread.get(), nano_seconds, wakeup_callback)); | ||||
|     CASCADE_CODE( | ||||
|         WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); | ||||
| 
 | ||||
|     mutex->Release(thread.get()); | ||||
| 
 | ||||
| @ -549,24 +554,27 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add | ||||
| } | ||||
| 
 | ||||
| /// Signal process wide key
 | ||||
| static ResultCode SignalProcessWideKey(VAddr semaphore_addr, s32 target) { | ||||
|     LOG_TRACE(Kernel_SVC, "called, semaphore_addr=0x%llx, target=0x%08x", semaphore_addr, target); | ||||
| static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { | ||||
|     LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x", | ||||
|               condition_variable_addr, target); | ||||
| 
 | ||||
|     // Wakeup all or one thread - Any other value is unimplemented
 | ||||
|     ASSERT(target == -1 || target == 1); | ||||
| 
 | ||||
|     SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr); | ||||
|     if (!semaphore) { | ||||
|         // Create a new semaphore for the specified address if one does not already exist
 | ||||
|         semaphore = Semaphore::Create(semaphore_addr).Unwrap(); | ||||
|         semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr); | ||||
|     SharedPtr<ConditionVariable> condition_variable = | ||||
|         g_object_address_table.Get<ConditionVariable>(condition_variable_addr); | ||||
|     if (!condition_variable) { | ||||
|         // Create a new condition_variable for the specified address if one does not already exist
 | ||||
|         condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); | ||||
|         condition_variable->name = | ||||
|             Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); | ||||
|     } | ||||
| 
 | ||||
|     CASCADE_CODE(semaphore->Release(target)); | ||||
|     CASCADE_CODE(condition_variable->Release(target)); | ||||
| 
 | ||||
|     if (semaphore->mutex_addr) { | ||||
|         // If a mutex was created for this semaphore, wait the current thread on it
 | ||||
|         SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(semaphore->mutex_addr); | ||||
|     if (condition_variable->mutex_addr) { | ||||
|         // If a mutex was created for this condition_variable, wait the current thread on it
 | ||||
|         SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(condition_variable->mutex_addr); | ||||
|         return WaitSynchronization1(mutex, GetCurrentThread()); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user