summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/citra_qt/debugger/wait_tree.cpp15
-rw-r--r--src/citra_qt/debugger/wait_tree.h6
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/hle/kernel/condition_variable.cpp65
-rw-r--r--src/core/hle/kernel/condition_variable.h65
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/semaphore.cpp64
-rw-r--r--src/core/hle/kernel/semaphore.h66
-rw-r--r--src/core/hle/kernel/svc.cpp58
-rw-r--r--src/core/hle/kernel/svc.h2
-rw-r--r--src/core/hle/kernel/svc_wrap.h2
11 files changed, 180 insertions, 171 deletions
diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp
index 6d15e43aa..cd03a6554 100644
--- a/src/citra_qt/debugger/wait_tree.cpp
+++ b/src/citra_qt/debugger/wait_tree.cpp
@@ -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;
}
diff --git a/src/citra_qt/debugger/wait_tree.h b/src/citra_qt/debugger/wait_tree.h
index 2b38712b9..4034e909b 100644
--- a/src/citra_qt/debugger/wait_tree.h
+++ b/src/citra_qt/debugger/wait_tree.h
@@ -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;
};
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index d35f974ca..a5dc67b07 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -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
diff --git a/src/core/hle/kernel/condition_variable.cpp b/src/core/hle/kernel/condition_variable.cpp
new file mode 100644
index 000000000..8908aeeb6
--- /dev/null
+++ b/src/core/hle/kernel/condition_variable.cpp
@@ -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
diff --git a/src/core/hle/kernel/condition_variable.h b/src/core/hle/kernel/condition_variable.h
new file mode 100644
index 000000000..27b8547c0
--- /dev/null
+++ b/src/core/hle/kernel/condition_variable.h
@@ -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
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index e43055bfd..a1f2090f7 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -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:
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
deleted file mode 100644
index b555bb28e..000000000
--- a/src/core/hle/kernel/semaphore.cpp
+++ /dev/null
@@ -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
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h
deleted file mode 100644
index 7254eb26d..000000000
--- a/src/core/hle/kernel/semaphore.h
+++ /dev/null
@@ -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
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index d18d7a182..b94503536 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -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());
}
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h
index b0265b6c8..a95598994 100644
--- a/src/core/hle/kernel/svc.h
+++ b/src/core/hle/kernel/svc.h
@@ -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.
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 4798ce733..bffa2f7f8 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -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.