diff options
| -rw-r--r-- | src/core/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/event.cpp | 53 | ||||
| -rw-r--r-- | src/core/hle/kernel/readable_event.cpp | 48 | ||||
| -rw-r--r-- | src/core/hle/kernel/readable_event.h | 56 | ||||
| -rw-r--r-- | src/core/hle/kernel/writable_event.cpp | 81 | ||||
| -rw-r--r-- | src/core/hle/kernel/writable_event.h (renamed from src/core/hle/kernel/event.h) | 27 | 
6 files changed, 210 insertions, 61 deletions
| diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e1f21a764..73aec8ab0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -97,8 +97,6 @@ add_library(core STATIC      hle/kernel/client_session.cpp      hle/kernel/client_session.h      hle/kernel/errors.h -    hle/kernel/event.cpp -    hle/kernel/event.h      hle/kernel/handle_table.cpp      hle/kernel/handle_table.h      hle/kernel/hle_ipc.cpp @@ -111,6 +109,8 @@ add_library(core STATIC      hle/kernel/object.h      hle/kernel/process.cpp      hle/kernel/process.h +    hle/kernel/readable_event.cpp +    hle/kernel/readable_event.h      hle/kernel/resource_limit.cpp      hle/kernel/resource_limit.h      hle/kernel/scheduler.cpp @@ -133,6 +133,8 @@ add_library(core STATIC      hle/kernel/vm_manager.h      hle/kernel/wait_object.cpp      hle/kernel/wait_object.h +    hle/kernel/writable_event.cpp +    hle/kernel/writable_event.h      hle/lock.cpp      hle/lock.h      hle/result.h diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp deleted file mode 100644 index 8967e602e..000000000 --- a/src/core/hle/kernel/event.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <algorithm> -#include "common/assert.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/object.h" -#include "core/hle/kernel/thread.h" - -namespace Kernel { - -Event::Event(KernelCore& kernel) : WaitObject{kernel} {} -Event::~Event() = default; - -SharedPtr<Event> Event::Create(KernelCore& kernel, ResetType reset_type, std::string name) { -    SharedPtr<Event> evt(new Event(kernel)); - -    evt->signaled = false; -    evt->reset_type = reset_type; -    evt->name = std::move(name); - -    return evt; -} - -bool Event::ShouldWait(Thread* thread) const { -    return !signaled; -} - -void Event::Acquire(Thread* thread) { -    ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); - -    if (reset_type == ResetType::OneShot) -        signaled = false; -} - -void Event::Signal() { -    signaled = true; -    WakeupAllWaitingThreads(); -} - -void Event::Clear() { -    signaled = false; -} - -void Event::WakeupAllWaitingThreads() { -    WaitObject::WakeupAllWaitingThreads(); - -    if (reset_type == ResetType::Pulse) -        signaled = false; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp new file mode 100644 index 000000000..164cffbdb --- /dev/null +++ b/src/core/hle/kernel/readable_event.cpp @@ -0,0 +1,48 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <algorithm> +#include "common/assert.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/readable_event.h" +#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/writable_event.h" + +namespace Kernel { + +ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {} +ReadableEvent::~ReadableEvent() = default; + +bool ReadableEvent::ShouldWait(Thread* thread) const { +    return !writable_event->IsSignaled(); +} + +void ReadableEvent::Acquire(Thread* thread) { +    ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); + +    writable_event->ResetOnAcquire(); +} + +void ReadableEvent::AddWaitingThread(SharedPtr<Thread> thread) { +    writable_event->AddWaitingThread(thread); +} + +void ReadableEvent::RemoveWaitingThread(Thread* thread) { +    writable_event->RemoveWaitingThread(thread); +} + +void ReadableEvent::Signal() { +    writable_event->Signal(); +} + +void ReadableEvent::Clear() { +    writable_event->Clear(); +} + +void ReadableEvent::WakeupAllWaitingThreads() { +    writable_event->WakeupAllWaitingThreads(); +    writable_event->ResetOnWakeup(); +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h new file mode 100644 index 000000000..020ef4ebc --- /dev/null +++ b/src/core/hle/kernel/readable_event.h @@ -0,0 +1,56 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/wait_object.h" + +namespace Kernel { + +class KernelCore; +class WritableEvent; + +class ReadableEvent final : public WaitObject { +    friend class WritableEvent; + +public: +    ~ReadableEvent() override; + +    std::string GetTypeName() const override { +        return "ReadableEvent"; +    } +    std::string GetName() const override { +        return name; +    } + +    static const HandleType HANDLE_TYPE = HandleType::Event; +    HandleType GetHandleType() const override { +        return HANDLE_TYPE; +    } + +    bool ShouldWait(Thread* thread) const override; +    void Acquire(Thread* thread) override; + +    void WakeupAllWaitingThreads() override; + +    void AddWaitingThread(SharedPtr<Thread> thread) override; +    void RemoveWaitingThread(Thread* thread) override; + +    void Signal(); +    void Clear(); + +    SharedPtr<WritableEvent> PromoteToWritable() const { +        return writable_event; +    } + +private: +    explicit ReadableEvent(KernelCore& kernel); + +    SharedPtr<WritableEvent> writable_event; ///< WritableEvent associated with this ReadableEvent + +    std::string name; ///< Name of event (optional) +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp new file mode 100644 index 000000000..4eb387ac0 --- /dev/null +++ b/src/core/hle/kernel/writable_event.cpp @@ -0,0 +1,81 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <algorithm> +#include "common/assert.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/readable_event.h" +#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/writable_event.h" + +namespace Kernel { + +WritableEvent::WritableEvent(KernelCore& kernel) : WaitObject{kernel} {} +WritableEvent::~WritableEvent() = default; + +std::tuple<SharedPtr<WritableEvent>, SharedPtr<ReadableEvent>> WritableEvent::CreateEventPair( +    KernelCore& kernel, ResetType reset_type, std::string name) { +    SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel)); +    SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel)); + +    writable_event->name = name + ":Writable"; +    writable_event->signaled = false; +    writable_event->reset_type = reset_type; +    readable_event->name = name + ":Readable"; +    readable_event->writable_event = writable_event; + +    return std::make_tuple(std::move(writable_event), std::move(readable_event)); +} + +SharedPtr<WritableEvent> WritableEvent::CreateRegisteredEventPair(KernelCore& kernel, +                                                                  ResetType reset_type, +                                                                  std::string name) { +    auto [writable_event, readable_event] = CreateEventPair(kernel, reset_type, name); +    kernel.AddNamedEvent(name, std::move(readable_event)); +    return std::move(writable_event); +} + +bool WritableEvent::ShouldWait(Thread* thread) const { +    return !signaled; +} + +void WritableEvent::Acquire(Thread* thread) { +    ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); + +    if (reset_type == ResetType::OneShot) +        signaled = false; +} + +void WritableEvent::Signal() { +    signaled = true; +    WakeupAllWaitingThreads(); +} + +void WritableEvent::Clear() { +    signaled = false; +} + +void WritableEvent::ResetOnAcquire() { +    if (reset_type == ResetType::OneShot) +        Clear(); +} + +void WritableEvent::ResetOnWakeup() { +    if (reset_type == ResetType::Pulse) +        Clear(); +} + +bool WritableEvent::IsSignaled() const { +    return signaled; +} + +void WritableEvent::WakeupAllWaitingThreads() { +    WaitObject::WakeupAllWaitingThreads(); + +    if (reset_type == ResetType::Pulse) +        signaled = false; +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/writable_event.h index 27d6126b0..c0fe42302 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/writable_event.h @@ -11,20 +11,33 @@  namespace Kernel {  class KernelCore; +class ReadableEvent; -class Event final : public WaitObject { +class WritableEvent final : public WaitObject {  public: +    ~WritableEvent() override; +      /**       * Creates an event       * @param kernel The kernel instance to create this event under.       * @param reset_type ResetType describing how to create event       * @param name Optional name of event       */ -    static SharedPtr<Event> Create(KernelCore& kernel, ResetType reset_type, -                                   std::string name = "Unknown"); +    static std::tuple<SharedPtr<WritableEvent>, SharedPtr<ReadableEvent>> CreateEventPair( +        KernelCore& kernel, ResetType reset_type, std::string name = "Unknown"); + +    /** +     * Creates an event and registers it in the kernel's named event table +     * @param kernel The kernel instance to create this event under. +     * @param reset_type ResetType describing how to create event +     * @param name name of event +     */ +    static SharedPtr<WritableEvent> CreateRegisteredEventPair(KernelCore& kernel, +                                                              ResetType reset_type, +                                                              std::string name);      std::string GetTypeName() const override { -        return "Event"; +        return "WritableEvent";      }      std::string GetName() const override {          return name; @@ -46,10 +59,12 @@ public:      void Signal();      void Clear(); +    void ResetOnAcquire(); +    void ResetOnWakeup(); +    bool IsSignaled() const;  private: -    explicit Event(KernelCore& kernel); -    ~Event() override; +    explicit WritableEvent(KernelCore& kernel);      ResetType reset_type; ///< Current ResetType | 
