diff options
Diffstat (limited to 'src/core/hle')
31 files changed, 330 insertions, 176 deletions
| diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 4669a14ad..6d66276bc 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -12,7 +12,7 @@  namespace Kernel { -ClientSession::ClientSession(KernelCore& kernel) : WaitObject{kernel} {} +ClientSession::ClientSession(KernelCore& kernel) : SynchronizationObject{kernel} {}  ClientSession::~ClientSession() {      // This destructor will be called automatically when the last ClientSession handle is closed by @@ -31,6 +31,11 @@ void ClientSession::Acquire(Thread* thread) {      UNIMPLEMENTED();  } +bool ClientSession::IsSignaled() const { +    UNIMPLEMENTED(); +    return true; +} +  ResultVal<std::shared_ptr<ClientSession>> ClientSession::Create(KernelCore& kernel,                                                                  std::shared_ptr<Session> parent,                                                                  std::string name) { diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index b4289a9a8..d15b09554 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -7,7 +7,7 @@  #include <memory>  #include <string> -#include "core/hle/kernel/wait_object.h" +#include "core/hle/kernel/synchronization_object.h"  #include "core/hle/result.h"  union ResultCode; @@ -22,7 +22,7 @@ class KernelCore;  class Session;  class Thread; -class ClientSession final : public WaitObject { +class ClientSession final : public SynchronizationObject {  public:      explicit ClientSession(KernelCore& kernel);      ~ClientSession() override; @@ -48,6 +48,8 @@ public:      void Acquire(Thread* thread) override; +    bool IsSignaled() const override; +  private:      static ResultVal<std::shared_ptr<ClientSession>> Create(KernelCore& kernel,                                                              std::shared_ptr<Session> parent, diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index ab05788d7..c558a2f33 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -47,15 +47,15 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(      const std::string& reason, u64 timeout, WakeupCallback&& callback,      std::shared_ptr<WritableEvent> writable_event) {      // Put the client thread to sleep until the wait event is signaled or the timeout expires. -    thread->SetWakeupCallback([context = *this, callback](ThreadWakeupReason reason, -                                                          std::shared_ptr<Thread> thread, -                                                          std::shared_ptr<WaitObject> object, -                                                          std::size_t index) mutable -> bool { -        ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent); -        callback(thread, context, reason); -        context.WriteToOutgoingCommandBuffer(*thread); -        return true; -    }); +    thread->SetWakeupCallback( +        [context = *this, callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread, +                                    std::shared_ptr<SynchronizationObject> object, +                                    std::size_t index) mutable -> bool { +            ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent); +            callback(thread, context, reason); +            context.WriteToOutgoingCommandBuffer(*thread); +            return true; +        });      auto& kernel = Core::System::GetInstance().Kernel();      if (!writable_event) { @@ -67,7 +67,7 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(      const auto readable_event{writable_event->GetReadableEvent()};      writable_event->Clear();      thread->SetStatus(ThreadStatus::WaitHLEEvent); -    thread->SetWaitObjects({readable_event}); +    thread->SetSynchronizationObjects({readable_event});      readable_event->AddWaitingThread(thread);      if (timeout > 0) { diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index edd4c4259..4eb1d8703 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -23,6 +23,7 @@  #include "core/hle/kernel/process.h"  #include "core/hle/kernel/resource_limit.h"  #include "core/hle/kernel/scheduler.h" +#include "core/hle/kernel/synchronization.h"  #include "core/hle/kernel/thread.h"  #include "core/hle/lock.h"  #include "core/hle/result.h" @@ -54,10 +55,10 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_      if (thread->GetStatus() == ThreadStatus::WaitSynch ||          thread->GetStatus() == ThreadStatus::WaitHLEEvent) {          // Remove the thread from each of its waiting objects' waitlists -        for (const auto& object : thread->GetWaitObjects()) { +        for (const auto& object : thread->GetSynchronizationObjects()) {              object->RemoveWaitingThread(thread);          } -        thread->ClearWaitObjects(); +        thread->ClearSynchronizationObjects();          // Invoke the wakeup callback before clearing the wait objects          if (thread->HasWakeupCallback()) { @@ -96,7 +97,8 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_  }  struct KernelCore::Impl { -    explicit Impl(Core::System& system) : system{system}, global_scheduler{system} {} +    explicit Impl(Core::System& system) +        : system{system}, global_scheduler{system}, synchronization{system} {}      void Initialize(KernelCore& kernel) {          Shutdown(); @@ -191,6 +193,7 @@ struct KernelCore::Impl {      std::vector<std::shared_ptr<Process>> process_list;      Process* current_process = nullptr;      Kernel::GlobalScheduler global_scheduler; +    Kernel::Synchronization synchronization;      std::shared_ptr<ResourceLimit> system_resource_limit; @@ -270,6 +273,14 @@ const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const {      return impl->cores[id];  } +Kernel::Synchronization& KernelCore::Synchronization() { +    return impl->synchronization; +} + +const Kernel::Synchronization& KernelCore::Synchronization() const { +    return impl->synchronization; +} +  Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {      return *impl->exclusive_monitor;  } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index fccffaf3a..1eede3063 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -29,6 +29,7 @@ class HandleTable;  class PhysicalCore;  class Process;  class ResourceLimit; +class Synchronization;  class Thread;  /// Represents a single instance of the kernel. @@ -92,6 +93,12 @@ public:      /// Gets the an instance of the respective physical CPU core.      const Kernel::PhysicalCore& PhysicalCore(std::size_t id) const; +    /// Gets the an instance of the Synchronization Interface. +    Kernel::Synchronization& Synchronization(); + +    /// Gets the an instance of the Synchronization Interface. +    const Kernel::Synchronization& Synchronization() const; +      /// Stops execution of 'id' core, in order to reschedule a new thread.      void PrepareReschedule(std::size_t id); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index b9035a0be..2fcb7326c 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -337,7 +337,7 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) {  }  Process::Process(Core::System& system) -    : WaitObject{system.Kernel()}, vm_manager{system}, +    : SynchronizationObject{system.Kernel()}, vm_manager{system},        address_arbiter{system}, mutex{system}, system{system} {}  Process::~Process() = default; @@ -357,7 +357,7 @@ void Process::ChangeStatus(ProcessStatus new_status) {      status = new_status;      is_signaled = true; -    WakeupAllWaitingThreads(); +    Signal();  }  void Process::AllocateMainThreadStack(u64 stack_size) { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 3483fa19d..4887132a7 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -15,8 +15,8 @@  #include "core/hle/kernel/handle_table.h"  #include "core/hle/kernel/mutex.h"  #include "core/hle/kernel/process_capability.h" +#include "core/hle/kernel/synchronization_object.h"  #include "core/hle/kernel/vm_manager.h" -#include "core/hle/kernel/wait_object.h"  #include "core/hle/result.h"  namespace Core { @@ -60,7 +60,7 @@ enum class ProcessStatus {      DebugBreak,  }; -class Process final : public WaitObject { +class Process final : public SynchronizationObject {  public:      explicit Process(Core::System& system);      ~Process() override; @@ -359,10 +359,6 @@ private:      /// specified by metadata provided to the process during loading.      bool is_64bit_process = true; -    /// Whether or not this process is signaled. This occurs -    /// upon the process changing to a different state. -    bool is_signaled = false; -      /// Total running time for the process in ticks.      u64 total_process_running_time_ticks = 0; diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp index d8ac97aa1..9d3d3a81b 100644 --- a/src/core/hle/kernel/readable_event.cpp +++ b/src/core/hle/kernel/readable_event.cpp @@ -11,30 +11,30 @@  namespace Kernel { -ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {} +ReadableEvent::ReadableEvent(KernelCore& kernel) : SynchronizationObject{kernel} {}  ReadableEvent::~ReadableEvent() = default;  bool ReadableEvent::ShouldWait(const Thread* thread) const { -    return !signaled; +    return !is_signaled;  }  void ReadableEvent::Acquire(Thread* thread) { -    ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); +    ASSERT_MSG(IsSignaled(), "object unavailable!");  }  void ReadableEvent::Signal() { -    if (!signaled) { -        signaled = true; -        WakeupAllWaitingThreads(); +    if (!is_signaled) { +        is_signaled = true; +        SynchronizationObject::Signal();      };  }  void ReadableEvent::Clear() { -    signaled = false; +    is_signaled = false;  }  ResultCode ReadableEvent::Reset() { -    if (!signaled) { +    if (!is_signaled) {          return ERR_INVALID_STATE;      } diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h index 11ff71c3a..3264dd066 100644 --- a/src/core/hle/kernel/readable_event.h +++ b/src/core/hle/kernel/readable_event.h @@ -5,7 +5,7 @@  #pragma once  #include "core/hle/kernel/object.h" -#include "core/hle/kernel/wait_object.h" +#include "core/hle/kernel/synchronization_object.h"  union ResultCode; @@ -14,7 +14,7 @@ namespace Kernel {  class KernelCore;  class WritableEvent; -class ReadableEvent final : public WaitObject { +class ReadableEvent final : public SynchronizationObject {      friend class WritableEvent;  public: @@ -46,13 +46,11 @@ public:      ///      then ERR_INVALID_STATE will be returned.      ResultCode Reset(); +    void Signal() override; +  private:      explicit ReadableEvent(KernelCore& kernel); -    void Signal(); - -    bool signaled{}; -      std::string name; ///< Name of event (optional)  }; diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index eb196a690..86f1421bf 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -124,8 +124,8 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) {                 "Thread yielding without being in front");      scheduled_queue[core_id].yield(priority); -    std::array<Thread*, NUM_CPU_CORES> current_threads; -    for (u32 i = 0; i < NUM_CPU_CORES; i++) { +    std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads; +    for (std::size_t i = 0; i < current_threads.size(); i++) {          current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front();      } @@ -177,8 +177,8 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread      // function...      if (scheduled_queue[core_id].empty()) {          // Here, "current_threads" is calculated after the ""yield"", unlike yield -1 -        std::array<Thread*, NUM_CPU_CORES> current_threads; -        for (u32 i = 0; i < NUM_CPU_CORES; i++) { +        std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads; +        for (std::size_t i = 0; i < current_threads.size(); i++) {              current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front();          }          for (auto& thread : suggested_queue[core_id]) { @@ -208,7 +208,7 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread  }  void GlobalScheduler::PreemptThreads() { -    for (std::size_t core_id = 0; core_id < NUM_CPU_CORES; core_id++) { +    for (std::size_t core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {          const u32 priority = preemption_priorities[core_id];          if (scheduled_queue[core_id].size(priority) > 0) { @@ -349,7 +349,7 @@ bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread,  }  void GlobalScheduler::Shutdown() { -    for (std::size_t core = 0; core < NUM_CPU_CORES; core++) { +    for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          scheduled_queue[core].clear();          suggested_queue[core].clear();      } diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 14b77960a..96db049cb 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -10,6 +10,7 @@  #include "common/common_types.h"  #include "common/multi_level_queue.h" +#include "core/hardware_properties.h"  #include "core/hle/kernel/thread.h"  namespace Core { @@ -23,8 +24,6 @@ class Process;  class GlobalScheduler final {  public: -    static constexpr u32 NUM_CPU_CORES = 4; -      explicit GlobalScheduler(Core::System& system);      ~GlobalScheduler(); @@ -125,7 +124,7 @@ public:      void PreemptThreads();      u32 CpuCoresCount() const { -        return NUM_CPU_CORES; +        return Core::Hardware::NUM_CPU_CORES;      }      void SetReselectionPending() { @@ -149,13 +148,15 @@ private:      bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner);      static constexpr u32 min_regular_priority = 2; -    std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> scheduled_queue; -    std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> suggested_queue; +    std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, Core::Hardware::NUM_CPU_CORES> +        scheduled_queue; +    std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, Core::Hardware::NUM_CPU_CORES> +        suggested_queue;      std::atomic<bool> is_reselection_pending{false};      // The priority levels at which the global scheduler preempts threads every 10 ms. They are      // ordered from Core 0 to Core 3. -    std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; +    std::array<u32, Core::Hardware::NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62};      /// Lists all thread ids that aren't deleted/etc.      std::vector<std::shared_ptr<Thread>> thread_list; diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index a4ccfa35e..a549ae9d7 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -13,7 +13,7 @@  namespace Kernel { -ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {} +ServerPort::ServerPort(KernelCore& kernel) : SynchronizationObject{kernel} {}  ServerPort::~ServerPort() = default;  ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() { @@ -39,6 +39,10 @@ void ServerPort::Acquire(Thread* thread) {      ASSERT_MSG(!ShouldWait(thread), "object unavailable!");  } +bool ServerPort::IsSignaled() const { +    return !pending_sessions.empty(); +} +  ServerPort::PortPair ServerPort::CreatePortPair(KernelCore& kernel, u32 max_sessions,                                                  std::string name) {      std::shared_ptr<ServerPort> server_port = std::make_shared<ServerPort>(kernel); diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 8be8a75ea..41b191b86 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -10,7 +10,7 @@  #include <vector>  #include "common/common_types.h"  #include "core/hle/kernel/object.h" -#include "core/hle/kernel/wait_object.h" +#include "core/hle/kernel/synchronization_object.h"  #include "core/hle/result.h"  namespace Kernel { @@ -20,7 +20,7 @@ class KernelCore;  class ServerSession;  class SessionRequestHandler; -class ServerPort final : public WaitObject { +class ServerPort final : public SynchronizationObject {  public:      explicit ServerPort(KernelCore& kernel);      ~ServerPort() override; @@ -82,6 +82,8 @@ public:      bool ShouldWait(const Thread* thread) const override;      void Acquire(Thread* thread) override; +    bool IsSignaled() const override; +  private:      /// ServerSessions waiting to be accepted by the port      std::vector<std::shared_ptr<ServerSession>> pending_sessions; diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 7825e1ec4..4604e35c5 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -24,7 +24,7 @@  namespace Kernel { -ServerSession::ServerSession(KernelCore& kernel) : WaitObject{kernel} {} +ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {}  ServerSession::~ServerSession() = default;  ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, @@ -50,6 +50,16 @@ bool ServerSession::ShouldWait(const Thread* thread) const {      return pending_requesting_threads.empty() || currently_handling != nullptr;  } +bool ServerSession::IsSignaled() const { +    // Closed sessions should never wait, an error will be returned from svcReplyAndReceive. +    if (!parent->Client()) { +        return true; +    } + +    // Wait if we have no pending requests, or if we're currently handling a request. +    return !pending_requesting_threads.empty() && currently_handling == nullptr; +} +  void ServerSession::Acquire(Thread* thread) {      ASSERT_MSG(!ShouldWait(thread), "object unavailable!");      // We are now handling a request, pop it from the stack. diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index d6e48109e..77e4f6721 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -10,7 +10,7 @@  #include <vector>  #include "common/threadsafe_queue.h" -#include "core/hle/kernel/wait_object.h" +#include "core/hle/kernel/synchronization_object.h"  #include "core/hle/result.h"  namespace Memory { @@ -41,7 +41,7 @@ class Thread;   * After the server replies to the request, the response is marshalled back to the caller's   * TLS buffer and control is transferred back to it.   */ -class ServerSession final : public WaitObject { +class ServerSession final : public SynchronizationObject {  public:      explicit ServerSession(KernelCore& kernel);      ~ServerSession() override; @@ -73,6 +73,8 @@ public:          return parent.get();      } +    bool IsSignaled() const override; +      /**       * Sets the HLE handler for the session. This handler will be called to service IPC requests       * instead of the regular IPC machinery. (The regular IPC machinery is currently not diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index dee6e2b72..e4dd53e24 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -9,7 +9,7 @@  namespace Kernel { -Session::Session(KernelCore& kernel) : WaitObject{kernel} {} +Session::Session(KernelCore& kernel) : SynchronizationObject{kernel} {}  Session::~Session() = default;  Session::SessionPair Session::Create(KernelCore& kernel, std::string name) { @@ -29,6 +29,11 @@ bool Session::ShouldWait(const Thread* thread) const {      return {};  } +bool Session::IsSignaled() const { +    UNIMPLEMENTED(); +    return true; +} +  void Session::Acquire(Thread* thread) {      UNIMPLEMENTED();  } diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 15a5ac15f..7cd9c0d77 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -8,7 +8,7 @@  #include <string>  #include <utility> -#include "core/hle/kernel/wait_object.h" +#include "core/hle/kernel/synchronization_object.h"  namespace Kernel { @@ -19,7 +19,7 @@ class ServerSession;   * Parent structure to link the client and server endpoints of a session with their associated   * client port.   */ -class Session final : public WaitObject { +class Session final : public SynchronizationObject {  public:      explicit Session(KernelCore& kernel);      ~Session() override; @@ -39,6 +39,8 @@ public:      bool ShouldWait(const Thread* thread) const override; +    bool IsSignaled() const override; +      void Acquire(Thread* thread) override;      std::shared_ptr<ClientSession> Client() { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9cae5c73d..fd91779a3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -32,6 +32,7 @@  #include "core/hle/kernel/shared_memory.h"  #include "core/hle/kernel/svc.h"  #include "core/hle/kernel/svc_wrap.h" +#include "core/hle/kernel/synchronization.h"  #include "core/hle/kernel/thread.h"  #include "core/hle/kernel/transfer_memory.h"  #include "core/hle/kernel/writable_event.h" @@ -433,22 +434,6 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han      return ERR_INVALID_HANDLE;  } -/// Default thread wakeup callback for WaitSynchronization -static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, -                                        std::shared_ptr<WaitObject> object, std::size_t index) { -    ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); - -    if (reason == ThreadWakeupReason::Timeout) { -        thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); -        return true; -    } - -    ASSERT(reason == ThreadWakeupReason::Signal); -    thread->SetWaitSynchronizationResult(RESULT_SUCCESS); -    thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); -    return true; -}; -  /// Wait for the given handles to synchronize, timeout after the specified nanoseconds  static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address,                                        u64 handle_count, s64 nano_seconds) { @@ -472,14 +457,14 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr      }      auto* const thread = system.CurrentScheduler().GetCurrentThread(); - -    using ObjectPtr = Thread::ThreadWaitObjects::value_type; -    Thread::ThreadWaitObjects objects(handle_count); -    const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); +    auto& kernel = system.Kernel(); +    using ObjectPtr = Thread::ThreadSynchronizationObjects::value_type; +    Thread::ThreadSynchronizationObjects objects(handle_count); +    const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();      for (u64 i = 0; i < handle_count; ++i) {          const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); -        const auto object = handle_table.Get<WaitObject>(handle); +        const auto object = handle_table.Get<SynchronizationObject>(handle);          if (object == nullptr) {              LOG_ERROR(Kernel_SVC, "Object is a nullptr"); @@ -488,47 +473,10 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr          objects[i] = object;      } - -    // Find the first object that is acquirable in the provided list of objects -    auto itr = std::find_if(objects.begin(), objects.end(), [thread](const ObjectPtr& object) { -        return !object->ShouldWait(thread); -    }); - -    if (itr != objects.end()) { -        // We found a ready object, acquire it and set the result value -        WaitObject* object = itr->get(); -        object->Acquire(thread); -        *index = static_cast<s32>(std::distance(objects.begin(), itr)); -        return RESULT_SUCCESS; -    } - -    // No objects were ready to be acquired, prepare to suspend the thread. - -    // If a timeout value of 0 was provided, just return the Timeout error code instead of -    // suspending the thread. -    if (nano_seconds == 0) { -        return RESULT_TIMEOUT; -    } - -    if (thread->IsSyncCancelled()) { -        thread->SetSyncCancelled(false); -        return ERR_SYNCHRONIZATION_CANCELED; -    } - -    for (auto& object : objects) { -        object->AddWaitingThread(SharedFrom(thread)); -    } - -    thread->SetWaitObjects(std::move(objects)); -    thread->SetStatus(ThreadStatus::WaitSynch); - -    // Create an event to wake the thread up after the specified nanosecond delay has passed -    thread->WakeAfterDelay(nano_seconds); -    thread->SetWakeupCallback(DefaultThreadWakeupCallback); - -    system.PrepareReschedule(thread->GetProcessorID()); - -    return RESULT_TIMEOUT; +    auto& synchronization = kernel.Synchronization(); +    const auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); +    *index = handle_result; +    return result;  }  /// Resumes a thread waiting on WaitSynchronization diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp new file mode 100644 index 000000000..dc37fad1a --- /dev/null +++ b/src/core/hle/kernel/synchronization.cpp @@ -0,0 +1,87 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/core.h" +#include "core/hle/kernel/errors.h" +#include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/scheduler.h" +#include "core/hle/kernel/synchronization.h" +#include "core/hle/kernel/synchronization_object.h" +#include "core/hle/kernel/thread.h" + +namespace Kernel { + +/// Default thread wakeup callback for WaitSynchronization +static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, +                                        std::shared_ptr<SynchronizationObject> object, +                                        std::size_t index) { +    ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); + +    if (reason == ThreadWakeupReason::Timeout) { +        thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); +        return true; +    } + +    ASSERT(reason == ThreadWakeupReason::Signal); +    thread->SetWaitSynchronizationResult(RESULT_SUCCESS); +    thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); +    return true; +} + +Synchronization::Synchronization(Core::System& system) : system{system} {} + +void Synchronization::SignalObject(SynchronizationObject& obj) const { +    if (obj.IsSignaled()) { +        obj.WakeupAllWaitingThreads(); +    } +} + +std::pair<ResultCode, Handle> Synchronization::WaitFor( +    std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) { +    auto* const thread = system.CurrentScheduler().GetCurrentThread(); +    // Find the first object that is acquirable in the provided list of objects +    const auto itr = std::find_if(sync_objects.begin(), sync_objects.end(), +                                  [thread](const std::shared_ptr<SynchronizationObject>& object) { +                                      return object->IsSignaled(); +                                  }); + +    if (itr != sync_objects.end()) { +        // We found a ready object, acquire it and set the result value +        SynchronizationObject* object = itr->get(); +        object->Acquire(thread); +        const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr)); +        return {RESULT_SUCCESS, index}; +    } + +    // No objects were ready to be acquired, prepare to suspend the thread. + +    // If a timeout value of 0 was provided, just return the Timeout error code instead of +    // suspending the thread. +    if (nano_seconds == 0) { +        return {RESULT_TIMEOUT, InvalidHandle}; +    } + +    if (thread->IsSyncCancelled()) { +        thread->SetSyncCancelled(false); +        return {ERR_SYNCHRONIZATION_CANCELED, InvalidHandle}; +    } + +    for (auto& object : sync_objects) { +        object->AddWaitingThread(SharedFrom(thread)); +    } + +    thread->SetSynchronizationObjects(std::move(sync_objects)); +    thread->SetStatus(ThreadStatus::WaitSynch); + +    // Create an event to wake the thread up after the specified nanosecond delay has passed +    thread->WakeAfterDelay(nano_seconds); +    thread->SetWakeupCallback(DefaultThreadWakeupCallback); + +    system.PrepareReschedule(thread->GetProcessorID()); + +    return {RESULT_TIMEOUT, InvalidHandle}; +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/synchronization.h b/src/core/hle/kernel/synchronization.h new file mode 100644 index 000000000..379f4b1d3 --- /dev/null +++ b/src/core/hle/kernel/synchronization.h @@ -0,0 +1,44 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include <utility> +#include <vector> + +#include "core/hle/kernel/object.h" +#include "core/hle/result.h" + +namespace Core { +class System; +} // namespace Core + +namespace Kernel { + +class SynchronizationObject; + +/** + * The 'Synchronization' class is an interface for handling synchronization methods + * used by Synchronization objects and synchronization SVCs. This centralizes processing of + * such + */ +class Synchronization { +public: +    explicit Synchronization(Core::System& system); + +    /// Signals a synchronization object, waking up all its waiting threads +    void SignalObject(SynchronizationObject& obj) const; + +    /// Tries to see if waiting for any of the sync_objects is necessary, if not +    /// it returns Success and the handle index of the signaled sync object. In +    /// case not, the current thread will be locked and wait for nano_seconds or +    /// for a synchronization object to signal. +    std::pair<ResultCode, Handle> WaitFor( +        std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds); + +private: +    Core::System& system; +}; +} // namespace Kernel diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/synchronization_object.cpp index 1838260fd..43f3eef18 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/synchronization_object.cpp @@ -10,20 +10,26 @@  #include "core/hle/kernel/kernel.h"  #include "core/hle/kernel/object.h"  #include "core/hle/kernel/process.h" +#include "core/hle/kernel/synchronization.h" +#include "core/hle/kernel/synchronization_object.h"  #include "core/hle/kernel/thread.h"  namespace Kernel { -WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {} -WaitObject::~WaitObject() = default; +SynchronizationObject::SynchronizationObject(KernelCore& kernel) : Object{kernel} {} +SynchronizationObject::~SynchronizationObject() = default; -void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) { +void SynchronizationObject::Signal() { +    kernel.Synchronization().SignalObject(*this); +} + +void SynchronizationObject::AddWaitingThread(std::shared_ptr<Thread> thread) {      auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);      if (itr == waiting_threads.end())          waiting_threads.push_back(std::move(thread));  } -void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) { +void SynchronizationObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) {      auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);      // If a thread passed multiple handles to the same object,      // the kernel might attempt to remove the thread from the object's @@ -32,7 +38,7 @@ void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) {          waiting_threads.erase(itr);  } -std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const { +std::shared_ptr<Thread> SynchronizationObject::GetHighestPriorityReadyThread() const {      Thread* candidate = nullptr;      u32 candidate_priority = THREADPRIO_LOWEST + 1; @@ -57,7 +63,7 @@ std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const {      return SharedFrom(candidate);  } -void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) { +void SynchronizationObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {      ASSERT(!ShouldWait(thread.get()));      if (!thread) { @@ -65,7 +71,7 @@ void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {      }      if (thread->IsSleepingOnWait()) { -        for (const auto& object : thread->GetWaitObjects()) { +        for (const auto& object : thread->GetSynchronizationObjects()) {              ASSERT(!object->ShouldWait(thread.get()));              object->Acquire(thread.get());          } @@ -73,9 +79,9 @@ void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {          Acquire(thread.get());      } -    const std::size_t index = thread->GetWaitObjectIndex(SharedFrom(this)); +    const std::size_t index = thread->GetSynchronizationObjectIndex(SharedFrom(this)); -    thread->ClearWaitObjects(); +    thread->ClearSynchronizationObjects();      thread->CancelWakeupTimer(); @@ -90,13 +96,13 @@ void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {      }  } -void WaitObject::WakeupAllWaitingThreads() { +void SynchronizationObject::WakeupAllWaitingThreads() {      while (auto thread = GetHighestPriorityReadyThread()) {          WakeupWaitingThread(thread);      }  } -const std::vector<std::shared_ptr<Thread>>& WaitObject::GetWaitingThreads() const { +const std::vector<std::shared_ptr<Thread>>& SynchronizationObject::GetWaitingThreads() const {      return waiting_threads;  } diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/synchronization_object.h index 9a17958a4..741c31faf 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/synchronization_object.h @@ -15,10 +15,10 @@ class KernelCore;  class Thread;  /// Class that represents a Kernel object that a thread can be waiting on -class WaitObject : public Object { +class SynchronizationObject : public Object {  public: -    explicit WaitObject(KernelCore& kernel); -    ~WaitObject() override; +    explicit SynchronizationObject(KernelCore& kernel); +    ~SynchronizationObject() override;      /**       * Check if the specified thread should wait until the object is available @@ -30,6 +30,13 @@ public:      /// Acquire/lock the object for the specified thread if it is available      virtual void Acquire(Thread* thread) = 0; +    /// Signal this object +    virtual void Signal(); + +    virtual bool IsSignaled() const { +        return is_signaled; +    } +      /**       * Add a thread to wait on this object       * @param thread Pointer to thread to add @@ -60,16 +67,20 @@ public:      /// Get a const reference to the waiting threads list for debug use      const std::vector<std::shared_ptr<Thread>>& GetWaitingThreads() const; +protected: +    bool is_signaled{}; // Tells if this sync object is signalled; +  private:      /// Threads waiting for this object to become available      std::vector<std::shared_ptr<Thread>> waiting_threads;  }; -// Specialization of DynamicObjectCast for WaitObjects +// Specialization of DynamicObjectCast for SynchronizationObjects  template <> -inline std::shared_ptr<WaitObject> DynamicObjectCast<WaitObject>(std::shared_ptr<Object> object) { +inline std::shared_ptr<SynchronizationObject> DynamicObjectCast<SynchronizationObject>( +    std::shared_ptr<Object> object) {      if (object != nullptr && object->IsWaitable()) { -        return std::static_pointer_cast<WaitObject>(object); +        return std::static_pointer_cast<SynchronizationObject>(object);      }      return nullptr;  } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ad464e03b..ae5f2c8bd 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -15,6 +15,7 @@  #include "core/core.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h" +#include "core/hardware_properties.h"  #include "core/hle/kernel/errors.h"  #include "core/hle/kernel/handle_table.h"  #include "core/hle/kernel/kernel.h" @@ -31,11 +32,15 @@ bool Thread::ShouldWait(const Thread* thread) const {      return status != ThreadStatus::Dead;  } +bool Thread::IsSignaled() const { +    return status == ThreadStatus::Dead; +} +  void Thread::Acquire(Thread* thread) {      ASSERT_MSG(!ShouldWait(thread), "object unavailable!");  } -Thread::Thread(KernelCore& kernel) : WaitObject{kernel} {} +Thread::Thread(KernelCore& kernel) : SynchronizationObject{kernel} {}  Thread::~Thread() = default;  void Thread::Stop() { @@ -45,7 +50,7 @@ void Thread::Stop() {      kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle);      callback_handle = 0;      SetStatus(ThreadStatus::Dead); -    WakeupAllWaitingThreads(); +    Signal();      // Clean up any dangling references in objects that this thread was waiting for      for (auto& wait_object : wait_objects) { @@ -215,7 +220,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {      context.cpu_registers[1] = output;  } -s32 Thread::GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const { +s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {      ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");      const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);      return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1); @@ -336,14 +341,16 @@ void Thread::ChangeCore(u32 core, u64 mask) {      SetCoreAndAffinityMask(core, mask);  } -bool Thread::AllWaitObjectsReady() const { -    return std::none_of( -        wait_objects.begin(), wait_objects.end(), -        [this](const std::shared_ptr<WaitObject>& object) { return object->ShouldWait(this); }); +bool Thread::AllSynchronizationObjectsReady() const { +    return std::none_of(wait_objects.begin(), wait_objects.end(), +                        [this](const std::shared_ptr<SynchronizationObject>& object) { +                            return object->ShouldWait(this); +                        });  }  bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, -                                  std::shared_ptr<WaitObject> object, std::size_t index) { +                                  std::shared_ptr<SynchronizationObject> object, +                                  std::size_t index) {      ASSERT(wakeup_callback);      return wakeup_callback(reason, std::move(thread), std::move(object), index);  } @@ -425,7 +432,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {              const s32 old_core = processor_id;              if (processor_id >= 0 && ((affinity_mask >> processor_id) & 1) == 0) {                  if (static_cast<s32>(ideal_core) < 0) { -                    processor_id = HighestSetCore(affinity_mask, GlobalScheduler::NUM_CPU_CORES); +                    processor_id = HighestSetCore(affinity_mask, Core::Hardware::NUM_CPU_CORES);                  } else {                      processor_id = ideal_core;                  } @@ -449,7 +456,7 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) {              scheduler.Unschedule(current_priority, static_cast<u32>(processor_id), this);          } -        for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { +        for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {              if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {                  scheduler.Unsuggest(current_priority, core, this);              } @@ -460,7 +467,7 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) {              scheduler.Schedule(current_priority, static_cast<u32>(processor_id), this);          } -        for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { +        for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {              if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {                  scheduler.Suggest(current_priority, core, this);              } @@ -479,7 +486,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) {          scheduler.Unschedule(old_priority, static_cast<u32>(processor_id), this);      } -    for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { +    for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {              scheduler.Unsuggest(old_priority, core, this);          } @@ -496,7 +503,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) {          }      } -    for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { +    for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          if (core != static_cast<u32>(processor_id) && ((affinity_mask >> core) & 1) != 0) {              scheduler.Suggest(current_priority, core, this);          } @@ -512,7 +519,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) {          return;      } -    for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { +    for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          if (((old_affinity_mask >> core) & 1) != 0) {              if (core == static_cast<u32>(old_core)) {                  scheduler.Unschedule(current_priority, core, this); @@ -522,7 +529,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) {          }      } -    for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { +    for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          if (((affinity_mask >> core) & 1) != 0) {              if (core == static_cast<u32>(processor_id)) {                  scheduler.Schedule(current_priority, core, this); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 3bcf9e137..7a4916318 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -11,7 +11,7 @@  #include "common/common_types.h"  #include "core/arm/arm_interface.h"  #include "core/hle/kernel/object.h" -#include "core/hle/kernel/wait_object.h" +#include "core/hle/kernel/synchronization_object.h"  #include "core/hle/result.h"  namespace Kernel { @@ -95,7 +95,7 @@ enum class ThreadSchedMasks : u32 {      ForcePauseMask = 0x0070,  }; -class Thread final : public WaitObject { +class Thread final : public SynchronizationObject {  public:      explicit Thread(KernelCore& kernel);      ~Thread() override; @@ -104,11 +104,11 @@ public:      using ThreadContext = Core::ARM_Interface::ThreadContext; -    using ThreadWaitObjects = std::vector<std::shared_ptr<WaitObject>>; +    using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;      using WakeupCallback =          std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, -                           std::shared_ptr<WaitObject> object, std::size_t index)>; +                           std::shared_ptr<SynchronizationObject> object, std::size_t index)>;      /**       * Creates and returns a new thread. The new thread is immediately scheduled @@ -146,6 +146,7 @@ public:      bool ShouldWait(const Thread* thread) const override;      void Acquire(Thread* thread) override; +    bool IsSignaled() const override;      /**       * Gets the thread's current priority @@ -233,7 +234,7 @@ public:       *       * @param object Object to query the index of.       */ -    s32 GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const; +    s32 GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const;      /**       * Stops a thread, invalidating it from further use @@ -314,15 +315,15 @@ public:          return owner_process;      } -    const ThreadWaitObjects& GetWaitObjects() const { +    const ThreadSynchronizationObjects& GetSynchronizationObjects() const {          return wait_objects;      } -    void SetWaitObjects(ThreadWaitObjects objects) { +    void SetSynchronizationObjects(ThreadSynchronizationObjects objects) {          wait_objects = std::move(objects);      } -    void ClearWaitObjects() { +    void ClearSynchronizationObjects() {          for (const auto& waiting_object : wait_objects) {              waiting_object->RemoveWaitingThread(SharedFrom(this));          } @@ -330,7 +331,7 @@ public:      }      /// Determines whether all the objects this thread is waiting on are ready. -    bool AllWaitObjectsReady() const; +    bool AllSynchronizationObjectsReady() const;      const MutexWaitingThreads& GetMutexWaitingThreads() const {          return wait_mutex_threads; @@ -395,7 +396,7 @@ public:       *      will cause an assertion to trigger.       */      bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, -                              std::shared_ptr<WaitObject> object, std::size_t index); +                              std::shared_ptr<SynchronizationObject> object, std::size_t index);      u32 GetIdealCore() const {          return ideal_core; @@ -494,7 +495,7 @@ private:      /// Objects that the thread is waiting on, in the same order as they were      /// passed to WaitSynchronization. -    ThreadWaitObjects wait_objects; +    ThreadSynchronizationObjects wait_objects;      /// List of threads that are waiting for a mutex that is held by this thread.      MutexWaitingThreads wait_mutex_threads; diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp index c9332e3e1..fc2f7c424 100644 --- a/src/core/hle/kernel/writable_event.cpp +++ b/src/core/hle/kernel/writable_event.cpp @@ -22,7 +22,6 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {      writable_event->name = name + ":Writable";      writable_event->readable = readable_event;      readable_event->name = name + ":Readable"; -    readable_event->signaled = false;      return {std::move(readable_event), std::move(writable_event)};  } @@ -40,7 +39,7 @@ void WritableEvent::Clear() {  }  bool WritableEvent::IsSignaled() const { -    return readable->signaled; +    return readable->IsSignaled();  }  } // namespace Kernel diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 89bf8b815..e6b56a9f9 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -10,6 +10,7 @@  #include "core/core_timing_util.h"  #include "core/frontend/emu_window.h"  #include "core/frontend/input.h" +#include "core/hardware_properties.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/kernel/client_port.h"  #include "core/hle/kernel/client_session.h" @@ -37,11 +38,11 @@ namespace Service::HID {  // Updating period for each HID device.  // TODO(ogniK): Find actual polling rate of hid -constexpr s64 pad_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 66); +constexpr s64 pad_update_ticks = static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 66);  [[maybe_unused]] constexpr s64 accelerometer_update_ticks = -    static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100); +    static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 100);  [[maybe_unused]] constexpr s64 gyroscope_update_ticks = -    static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100); +    static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 100);  constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;  IAppletResource::IAppletResource(Core::System& system) diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 62752e419..134152210 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -12,6 +12,7 @@  #include "core/core.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h" +#include "core/hardware_properties.h"  #include "core/hle/kernel/kernel.h"  #include "core/hle/kernel/readable_event.h"  #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" @@ -26,8 +27,8 @@  namespace Service::NVFlinger { -constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60); -constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 30); +constexpr s64 frame_ticks = static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 60); +constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 30);  NVFlinger::NVFlinger(Core::System& system) : system(system) {      displays.emplace_back(0, "Default", system); @@ -222,7 +223,7 @@ void NVFlinger::Compose() {  s64 NVFlinger::GetNextTicks() const {      constexpr s64 max_hertz = 120LL; -    return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / max_hertz; +    return (Core::Hardware::BASE_CLOCK_RATE * (1LL << swap_interval)) / max_hertz;  }  } // namespace Service::NVFlinger diff --git a/src/core/hle/service/time/standard_steady_clock_core.cpp b/src/core/hle/service/time/standard_steady_clock_core.cpp index ca1a783fc..1575f0b49 100644 --- a/src/core/hle/service/time/standard_steady_clock_core.cpp +++ b/src/core/hle/service/time/standard_steady_clock_core.cpp @@ -5,6 +5,7 @@  #include "core/core.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h" +#include "core/hardware_properties.h"  #include "core/hle/service/time/standard_steady_clock_core.h"  namespace Service::Time::Clock { @@ -12,7 +13,7 @@ namespace Service::Time::Clock {  TimeSpanType StandardSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) {      const TimeSpanType ticks_time_span{TimeSpanType::FromTicks(          Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), -        Core::Timing::CNTFREQ)}; +        Core::Hardware::CNTFREQ)};      TimeSpanType raw_time_point{setup_value.nanoseconds + ticks_time_span.nanoseconds};      if (raw_time_point.nanoseconds < cached_raw_time_point.nanoseconds) { diff --git a/src/core/hle/service/time/tick_based_steady_clock_core.cpp b/src/core/hle/service/time/tick_based_steady_clock_core.cpp index c77b98189..44d5bc651 100644 --- a/src/core/hle/service/time/tick_based_steady_clock_core.cpp +++ b/src/core/hle/service/time/tick_based_steady_clock_core.cpp @@ -5,6 +5,7 @@  #include "core/core.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h" +#include "core/hardware_properties.h"  #include "core/hle/service/time/tick_based_steady_clock_core.h"  namespace Service::Time::Clock { @@ -12,7 +13,7 @@ namespace Service::Time::Clock {  SteadyClockTimePoint TickBasedSteadyClockCore::GetTimePoint(Core::System& system) {      const TimeSpanType ticks_time_span{TimeSpanType::FromTicks(          Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), -        Core::Timing::CNTFREQ)}; +        Core::Hardware::CNTFREQ)};      return {ticks_time_span.ToSeconds(), GetClockSourceId()};  } diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 8ef4efcef..749b7be70 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -6,6 +6,7 @@  #include "core/core.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h" +#include "core/hardware_properties.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/kernel/client_port.h"  #include "core/hle/kernel/client_session.h" @@ -233,7 +234,7 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERe      if (current_time_point.clock_source_id == context.steady_time_point.clock_source_id) {          const auto ticks{Clock::TimeSpanType::FromTicks(              Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), -            Core::Timing::CNTFREQ)}; +            Core::Hardware::CNTFREQ)};          const s64 base_time_point{context.offset + current_time_point.time_point -                                    ticks.ToSeconds()};          IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index 9b03191bf..fdaef233f 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp @@ -5,6 +5,7 @@  #include "core/core.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h" +#include "core/hardware_properties.h"  #include "core/hle/service/time/clock_types.h"  #include "core/hle/service/time/steady_clock_core.h"  #include "core/hle/service/time/time_sharedmemory.h" @@ -31,7 +32,7 @@ void SharedMemory::SetupStandardSteadyClock(Core::System& system,                                              Clock::TimeSpanType current_time_point) {      const Clock::TimeSpanType ticks_time_span{Clock::TimeSpanType::FromTicks(          Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), -        Core::Timing::CNTFREQ)}; +        Core::Hardware::CNTFREQ)};      const Clock::SteadyClockContext context{          static_cast<u64>(current_time_point.nanoseconds - ticks_time_span.nanoseconds),          clock_source_id}; | 
