diff options
| -rw-r--r-- | src/citra_qt/debugger/wait_tree.cpp | 15 | ||||
| -rw-r--r-- | src/citra_qt/debugger/wait_tree.h | 6 | ||||
| -rw-r--r-- | src/core/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/condition_variable.cpp | 65 | ||||
| -rw-r--r-- | src/core/hle/kernel/condition_variable.h | 65 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.cpp | 64 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.h | 66 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 58 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 2 | 
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.  | 
