hle: kernel: Reimplement KReadableEvent and KWritableEvent.
This commit is contained in:
		@@ -1,9 +1,10 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Copyright 2021 yuzu emulator team
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/common_funcs.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/hle/kernel/errors.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
@@ -11,40 +12,43 @@
 | 
			
		||||
#include "core/hle/kernel/k_thread.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
#include "core/hle/kernel/svc_results.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
KReadableEvent::KReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {}
 | 
			
		||||
KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name)
 | 
			
		||||
    : KSynchronizationObject{kernel, std::move(name)} {}
 | 
			
		||||
KReadableEvent::~KReadableEvent() = default;
 | 
			
		||||
 | 
			
		||||
void KReadableEvent::Signal() {
 | 
			
		||||
    if (is_signaled) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    is_signaled = true;
 | 
			
		||||
    NotifyAvailable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool KReadableEvent::IsSignaled() const {
 | 
			
		||||
    ASSERT(kernel.GlobalSchedulerContext().IsLocked());
 | 
			
		||||
 | 
			
		||||
    return is_signaled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KReadableEvent::Clear() {
 | 
			
		||||
    is_signaled = false;
 | 
			
		||||
ResultCode KReadableEvent::Signal() {
 | 
			
		||||
    KScopedSchedulerLock lk{kernel};
 | 
			
		||||
 | 
			
		||||
    if (!is_signaled) {
 | 
			
		||||
        is_signaled = true;
 | 
			
		||||
        NotifyAvailable();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode KReadableEvent::Clear() {
 | 
			
		||||
    Reset();
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode KReadableEvent::Reset() {
 | 
			
		||||
    KScopedSchedulerLock lock(kernel);
 | 
			
		||||
    if (!is_signaled) {
 | 
			
		||||
        LOG_TRACE(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}",
 | 
			
		||||
                  GetObjectId(), GetTypeName(), GetName());
 | 
			
		||||
        return ERR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
    KScopedSchedulerLock lk{kernel};
 | 
			
		||||
 | 
			
		||||
    Clear();
 | 
			
		||||
    R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState);
 | 
			
		||||
 | 
			
		||||
    is_signaled = false;
 | 
			
		||||
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Copyright 2021 yuzu emulator team
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
@@ -6,25 +6,20 @@
 | 
			
		||||
 | 
			
		||||
#include "core/hle/kernel/k_synchronization_object.h"
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
 | 
			
		||||
union ResultCode;
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
class KernelCore;
 | 
			
		||||
class KWritableEvent;
 | 
			
		||||
class KEvent;
 | 
			
		||||
 | 
			
		||||
class KReadableEvent final : public KSynchronizationObject {
 | 
			
		||||
    friend class KWritableEvent;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit KReadableEvent(KernelCore& kernel, std::string&& name);
 | 
			
		||||
    ~KReadableEvent() override;
 | 
			
		||||
 | 
			
		||||
    std::string GetTypeName() const override {
 | 
			
		||||
        return "ReadableEvent";
 | 
			
		||||
    }
 | 
			
		||||
    std::string GetName() const override {
 | 
			
		||||
        return name;
 | 
			
		||||
        return "KReadableEvent";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent;
 | 
			
		||||
@@ -32,28 +27,25 @@ public:
 | 
			
		||||
        return HANDLE_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Unconditionally clears the readable event's state.
 | 
			
		||||
    void Clear();
 | 
			
		||||
    KEvent* GetParent() const {
 | 
			
		||||
        return parent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Clears the readable event's state if and only if it
 | 
			
		||||
    /// has already been signaled.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @pre The event must be in a signaled state. If this event
 | 
			
		||||
    ///      is in an unsignaled state and this function is called,
 | 
			
		||||
    ///      then ERR_INVALID_STATE will be returned.
 | 
			
		||||
    ResultCode Reset();
 | 
			
		||||
 | 
			
		||||
    void Signal();
 | 
			
		||||
    void Initialize(KEvent* parent_) {
 | 
			
		||||
        is_signaled = false;
 | 
			
		||||
        parent = parent_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool IsSignaled() const override;
 | 
			
		||||
 | 
			
		||||
    void Finalize() override {}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    explicit KReadableEvent(KernelCore& kernel);
 | 
			
		||||
    ResultCode Signal();
 | 
			
		||||
    ResultCode Clear();
 | 
			
		||||
    ResultCode Reset();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool is_signaled{};
 | 
			
		||||
    std::string name; ///< Name of event (optional)
 | 
			
		||||
    KEvent* parent{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 
 | 
			
		||||
@@ -132,6 +132,9 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
 | 
			
		||||
 | 
			
		||||
KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {}
 | 
			
		||||
 | 
			
		||||
KSynchronizationObject::KSynchronizationObject(KernelCore& kernel, std::string&& name)
 | 
			
		||||
    : Object{kernel, std::move(name)} {}
 | 
			
		||||
 | 
			
		||||
KSynchronizationObject::~KSynchronizationObject() = default;
 | 
			
		||||
 | 
			
		||||
void KSynchronizationObject::NotifyAvailable(ResultCode result) {
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ public:
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    explicit KSynchronizationObject(KernelCore& kernel);
 | 
			
		||||
    explicit KSynchronizationObject(KernelCore& kernel, std::string&& name);
 | 
			
		||||
    virtual ~KSynchronizationObject();
 | 
			
		||||
 | 
			
		||||
    void NotifyAvailable(ResultCode result);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +1,27 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Copyright 2021 yuzu emulator team
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_thread.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
KWritableEvent::KWritableEvent(KernelCore& kernel) : Object{kernel} {}
 | 
			
		||||
KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name)
 | 
			
		||||
    : Object{kernel, std::move(name)} {}
 | 
			
		||||
KWritableEvent::~KWritableEvent() = default;
 | 
			
		||||
 | 
			
		||||
EventPair KWritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
 | 
			
		||||
    std::shared_ptr<KWritableEvent> writable_event(new KWritableEvent(kernel));
 | 
			
		||||
    std::shared_ptr<KReadableEvent> readable_event(new KReadableEvent(kernel));
 | 
			
		||||
 | 
			
		||||
    writable_event->name = name + ":Writable";
 | 
			
		||||
    writable_event->readable = readable_event;
 | 
			
		||||
    readable_event->name = name + ":Readable";
 | 
			
		||||
 | 
			
		||||
    return {std::move(readable_event), std::move(writable_event)};
 | 
			
		||||
void KWritableEvent::Initialize(KEvent* parent_) {
 | 
			
		||||
    parent = parent_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<KReadableEvent> KWritableEvent::GetReadableEvent() const {
 | 
			
		||||
    return readable;
 | 
			
		||||
ResultCode KWritableEvent::Signal() {
 | 
			
		||||
    return parent->GetReadableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KWritableEvent::Signal() {
 | 
			
		||||
    readable->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KWritableEvent::Clear() {
 | 
			
		||||
    readable->Clear();
 | 
			
		||||
ResultCode KWritableEvent::Clear() {
 | 
			
		||||
    return parent->GetReadableEvent()->Clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 
 | 
			
		||||
@@ -4,37 +4,21 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
class KernelCore;
 | 
			
		||||
class KReadableEvent;
 | 
			
		||||
class KWritableEvent;
 | 
			
		||||
 | 
			
		||||
struct EventPair {
 | 
			
		||||
    std::shared_ptr<KReadableEvent> readable;
 | 
			
		||||
    std::shared_ptr<KWritableEvent> writable;
 | 
			
		||||
};
 | 
			
		||||
class KEvent;
 | 
			
		||||
 | 
			
		||||
class KWritableEvent final : public Object {
 | 
			
		||||
public:
 | 
			
		||||
    explicit KWritableEvent(KernelCore& kernel, std::string&& name);
 | 
			
		||||
    ~KWritableEvent() override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an event
 | 
			
		||||
     * @param kernel The kernel instance to create this event under.
 | 
			
		||||
     * @param name Optional name of event
 | 
			
		||||
     */
 | 
			
		||||
    static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown");
 | 
			
		||||
 | 
			
		||||
    std::string GetTypeName() const override {
 | 
			
		||||
        return "WritableEvent";
 | 
			
		||||
    }
 | 
			
		||||
    std::string GetName() const override {
 | 
			
		||||
        return name;
 | 
			
		||||
        return "KWritableEvent";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent;
 | 
			
		||||
@@ -42,19 +26,19 @@ public:
 | 
			
		||||
        return HANDLE_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<KReadableEvent> GetReadableEvent() const;
 | 
			
		||||
 | 
			
		||||
    void Signal();
 | 
			
		||||
    void Clear();
 | 
			
		||||
    void Initialize(KEvent* parent_);
 | 
			
		||||
 | 
			
		||||
    void Finalize() override {}
 | 
			
		||||
 | 
			
		||||
    ResultCode Signal();
 | 
			
		||||
    ResultCode Clear();
 | 
			
		||||
 | 
			
		||||
    KEvent* GetParent() const {
 | 
			
		||||
        return parent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    explicit KWritableEvent(KernelCore& kernel);
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<KReadableEvent> readable;
 | 
			
		||||
 | 
			
		||||
    std::string name; ///< Name of event (optional)
 | 
			
		||||
    KEvent* parent{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,10 @@
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
Object::Object(KernelCore& kernel) : kernel{kernel}, object_id{kernel.CreateNewObjectID()} {}
 | 
			
		||||
Object::Object(KernelCore& kernel_)
 | 
			
		||||
    : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{"[UNKNOWN KERNEL OBJECT]"} {}
 | 
			
		||||
Object::Object(KernelCore& kernel_, std::string&& name_)
 | 
			
		||||
    : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{std::move(name_)} {}
 | 
			
		||||
Object::~Object() = default;
 | 
			
		||||
 | 
			
		||||
bool Object::IsWaitable() const {
 | 
			
		||||
@@ -21,6 +24,7 @@ bool Object::IsWaitable() const {
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
    case HandleType::Unknown:
 | 
			
		||||
    case HandleType::Event:
 | 
			
		||||
    case HandleType::WritableEvent:
 | 
			
		||||
    case HandleType::SharedMemory:
 | 
			
		||||
    case HandleType::TransferMemory:
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ using Handle = u32;
 | 
			
		||||
 | 
			
		||||
enum class HandleType : u32 {
 | 
			
		||||
    Unknown,
 | 
			
		||||
    Event,
 | 
			
		||||
    WritableEvent,
 | 
			
		||||
    ReadableEvent,
 | 
			
		||||
    SharedMemory,
 | 
			
		||||
@@ -34,7 +35,8 @@ enum class HandleType : u32 {
 | 
			
		||||
 | 
			
		||||
class Object : NonCopyable, public std::enable_shared_from_this<Object> {
 | 
			
		||||
public:
 | 
			
		||||
    explicit Object(KernelCore& kernel);
 | 
			
		||||
    explicit Object(KernelCore& kernel_);
 | 
			
		||||
    explicit Object(KernelCore& kernel_, std::string&& name_);
 | 
			
		||||
    virtual ~Object();
 | 
			
		||||
 | 
			
		||||
    /// Returns a unique identifier for the object. For debugging purposes only.
 | 
			
		||||
@@ -46,7 +48,7 @@ public:
 | 
			
		||||
        return "[BAD KERNEL OBJECT TYPE]";
 | 
			
		||||
    }
 | 
			
		||||
    virtual std::string GetName() const {
 | 
			
		||||
        return "[UNKNOWN KERNEL OBJECT]";
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
    virtual HandleType GetHandleType() const = 0;
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +71,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::atomic<u32> object_id{0};
 | 
			
		||||
    std::string name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@
 | 
			
		||||
#include "core/hle/kernel/handle_table.h"
 | 
			
		||||
#include "core/hle/kernel/k_address_arbiter.h"
 | 
			
		||||
#include "core/hle/kernel/k_condition_variable.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_resource_limit.h"
 | 
			
		||||
#include "core/hle/kernel/k_scheduler.h"
 | 
			
		||||
@@ -1870,18 +1871,18 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle
 | 
			
		||||
    LOG_DEBUG(Kernel_SVC, "called");
 | 
			
		||||
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    const auto [readable_event, writable_event] =
 | 
			
		||||
        KWritableEvent::CreateEventPair(kernel, "CreateEvent");
 | 
			
		||||
    const auto event = KEvent::Create(kernel, "CreateEvent");
 | 
			
		||||
    event->Initialize();
 | 
			
		||||
 | 
			
		||||
    HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
 | 
			
		||||
 | 
			
		||||
    const auto write_create_result = handle_table.Create(writable_event);
 | 
			
		||||
    const auto write_create_result = handle_table.Create(event->GetWritableEvent());
 | 
			
		||||
    if (write_create_result.Failed()) {
 | 
			
		||||
        return write_create_result.Code();
 | 
			
		||||
    }
 | 
			
		||||
    *write_handle = *write_create_result;
 | 
			
		||||
 | 
			
		||||
    const auto read_create_result = handle_table.Create(readable_event);
 | 
			
		||||
    const auto read_create_result = handle_table.Create(event->GetReadableEvent());
 | 
			
		||||
    if (read_create_result.Failed()) {
 | 
			
		||||
        handle_table.Close(*write_create_result);
 | 
			
		||||
        return read_create_result.Code();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
#include "core/file_sys/registered_cache.h"
 | 
			
		||||
#include "core/file_sys/savedata_factory.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
@@ -303,17 +304,18 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    launchable_event =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, "ISelfController:LaunchableEvent");
 | 
			
		||||
    launchable_event = Kernel::KEvent::Create(kernel, "ISelfController:LaunchableEvent");
 | 
			
		||||
    launchable_event->Initialize();
 | 
			
		||||
 | 
			
		||||
    // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is
 | 
			
		||||
    // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple
 | 
			
		||||
    // ISelfControllers. The event is signaled on creation, and on transition from suspended -> not
 | 
			
		||||
    // suspended if the event has previously been created by a call to
 | 
			
		||||
    // GetAccumulatedSuspendedTickChangedEvent.
 | 
			
		||||
    accumulated_suspended_tick_changed_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
        kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent");
 | 
			
		||||
    accumulated_suspended_tick_changed_event.writable->Signal();
 | 
			
		||||
    accumulated_suspended_tick_changed_event =
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent");
 | 
			
		||||
    accumulated_suspended_tick_changed_event->Initialize();
 | 
			
		||||
    accumulated_suspended_tick_changed_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ISelfController::~ISelfController() = default;
 | 
			
		||||
@@ -372,11 +374,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    LOG_WARNING(Service_AM, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
    launchable_event.writable->Signal();
 | 
			
		||||
    launchable_event->GetWritableEvent()->Signal();
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(launchable_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(launchable_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -555,41 +557,42 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(accumulated_suspended_tick_changed_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
 | 
			
		||||
    on_new_message =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, "AMMessageQueue:OnMessageReceived");
 | 
			
		||||
    on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived");
 | 
			
		||||
    on_new_message->Initialize();
 | 
			
		||||
    on_operation_mode_changed =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, "AMMessageQueue:OperationModeChanged");
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "AMMessageQueue:OperationModeChanged");
 | 
			
		||||
    on_operation_mode_changed->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppletMessageQueue::~AppletMessageQueue() = default;
 | 
			
		||||
 | 
			
		||||
const std::shared_ptr<Kernel::KReadableEvent>& AppletMessageQueue::GetMessageReceiveEvent() const {
 | 
			
		||||
    return on_new_message.readable;
 | 
			
		||||
    return on_new_message->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::shared_ptr<Kernel::KReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
 | 
			
		||||
    const {
 | 
			
		||||
    return on_operation_mode_changed.readable;
 | 
			
		||||
    return on_operation_mode_changed->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppletMessageQueue::PushMessage(AppletMessage msg) {
 | 
			
		||||
    messages.push(msg);
 | 
			
		||||
    on_new_message.writable->Signal();
 | 
			
		||||
    on_new_message->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
 | 
			
		||||
    if (messages.empty()) {
 | 
			
		||||
        on_new_message.writable->Clear();
 | 
			
		||||
        on_new_message->GetWritableEvent()->Clear();
 | 
			
		||||
        return AppletMessage::NoMessage;
 | 
			
		||||
    }
 | 
			
		||||
    auto msg = messages.front();
 | 
			
		||||
    messages.pop();
 | 
			
		||||
    if (messages.empty()) {
 | 
			
		||||
        on_new_message.writable->Clear();
 | 
			
		||||
        on_new_message->GetWritableEvent()->Clear();
 | 
			
		||||
    }
 | 
			
		||||
    return msg;
 | 
			
		||||
}
 | 
			
		||||
@@ -601,7 +604,7 @@ std::size_t AppletMessageQueue::GetMessageCount() const {
 | 
			
		||||
void AppletMessageQueue::OperationModeChanged() {
 | 
			
		||||
    PushMessage(AppletMessage::OperationModeChanged);
 | 
			
		||||
    PushMessage(AppletMessage::PerformanceModeChanged);
 | 
			
		||||
    on_operation_mode_changed.writable->Signal();
 | 
			
		||||
    on_operation_mode_changed->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppletMessageQueue::RequestExit() {
 | 
			
		||||
@@ -1229,14 +1232,15 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    gpu_error_detected_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
        kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
 | 
			
		||||
 | 
			
		||||
    friend_invitation_storage_channel_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
        kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent");
 | 
			
		||||
 | 
			
		||||
    health_warning_disappeared_system_event = Kernel::WritableEvent::CreateEventPair(
 | 
			
		||||
        kernel, "IApplicationFunctions:HealthWarningDisappearedSystemEvent");
 | 
			
		||||
    gpu_error_detected_event =
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
 | 
			
		||||
    gpu_error_detected_event->Initialize();
 | 
			
		||||
    friend_invitation_storage_channel_event =
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent");
 | 
			
		||||
    friend_invitation_storage_channel_event->Initialize();
 | 
			
		||||
    health_warning_disappeared_system_event =
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "IApplicationFunctions:HealthWarningDisappearedSystemEvent");
 | 
			
		||||
    health_warning_disappeared_system_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IApplicationFunctions::~IApplicationFunctions() = default;
 | 
			
		||||
@@ -1633,7 +1637,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(gpu_error_detected_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -1641,7 +1645,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(friend_invitation_storage_channel_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
 | 
			
		||||
@@ -1657,7 +1661,7 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(health_warning_disappeared_system_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
 | 
			
		||||
@@ -1693,8 +1697,9 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
 | 
			
		||||
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    pop_from_general_channel_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
        system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent");
 | 
			
		||||
    pop_from_general_channel_event =
 | 
			
		||||
        Kernel::KEvent::Create(system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent");
 | 
			
		||||
    pop_from_general_channel_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
 | 
			
		||||
@@ -1711,7 +1716,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(pop_from_general_channel_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IGlobalStateController::IGlobalStateController(Core::System& system_)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,12 @@
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KernelCore;
 | 
			
		||||
class KEvent;
 | 
			
		||||
class TransferMemory;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
@@ -65,8 +66,8 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::queue<AppletMessage> messages;
 | 
			
		||||
    Kernel::EventPair on_new_message;
 | 
			
		||||
    Kernel::EventPair on_operation_mode_changed;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> on_new_message;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> on_operation_mode_changed;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class IWindowController final : public ServiceFramework<IWindowController> {
 | 
			
		||||
@@ -153,8 +154,8 @@ private:
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    NVFlinger::NVFlinger& nvflinger;
 | 
			
		||||
    Kernel::EventPair launchable_event;
 | 
			
		||||
    Kernel::EventPair accumulated_suspended_tick_changed_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> launchable_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> accumulated_suspended_tick_changed_event;
 | 
			
		||||
 | 
			
		||||
    u32 idle_time_detection_extension = 0;
 | 
			
		||||
    u64 num_fatal_sections_entered = 0;
 | 
			
		||||
@@ -295,9 +296,9 @@ private:
 | 
			
		||||
    bool launch_popped_application_specific = false;
 | 
			
		||||
    bool launch_popped_account_preselect = false;
 | 
			
		||||
    s32 previous_program_index{-1};
 | 
			
		||||
    Kernel::EventPair gpu_error_detected_event;
 | 
			
		||||
    Kernel::EventPair friend_invitation_storage_channel_event;
 | 
			
		||||
    Kernel::EventPair health_warning_disappeared_system_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> gpu_error_detected_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> friend_invitation_storage_channel_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> health_warning_disappeared_system_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
 | 
			
		||||
@@ -309,7 +310,7 @@ private:
 | 
			
		||||
    void RequestToGetForeground(Kernel::HLERequestContext& ctx);
 | 
			
		||||
    void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair pop_from_general_channel_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> pop_from_general_channel_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/frontend/applets/controller.h"
 | 
			
		||||
@@ -11,6 +12,7 @@
 | 
			
		||||
#include "core/frontend/applets/profile_select.h"
 | 
			
		||||
#include "core/frontend/applets/software_keyboard.h"
 | 
			
		||||
#include "core/frontend/applets/web_browser.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/server_session.h"
 | 
			
		||||
@@ -27,11 +29,13 @@ namespace Service::AM::Applets {
 | 
			
		||||
 | 
			
		||||
AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) {
 | 
			
		||||
    state_changed_event =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:StateChangedEvent");
 | 
			
		||||
    pop_out_data_event =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:PopDataOutEvent");
 | 
			
		||||
    pop_interactive_out_data_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
        kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:StateChangedEvent");
 | 
			
		||||
    state_changed_event->Initialize();
 | 
			
		||||
    pop_out_data_event = Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopDataOutEvent");
 | 
			
		||||
    pop_out_data_event->Initialize();
 | 
			
		||||
    pop_interactive_out_data_event =
 | 
			
		||||
        Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
 | 
			
		||||
    pop_interactive_out_data_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AppletDataBroker::~AppletDataBroker() = default;
 | 
			
		||||
@@ -58,7 +62,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
 | 
			
		||||
 | 
			
		||||
    auto out = std::move(out_channel.front());
 | 
			
		||||
    out_channel.pop_front();
 | 
			
		||||
    pop_out_data_event.writable->Clear();
 | 
			
		||||
    pop_out_data_event->GetWritableEvent()->Clear();
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -77,7 +81,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
 | 
			
		||||
 | 
			
		||||
    auto out = std::move(out_interactive_channel.front());
 | 
			
		||||
    out_interactive_channel.pop_front();
 | 
			
		||||
    pop_interactive_out_data_event.writable->Clear();
 | 
			
		||||
    pop_interactive_out_data_event->GetWritableEvent()->Clear();
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -96,7 +100,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
 | 
			
		||||
 | 
			
		||||
void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
 | 
			
		||||
    out_channel.emplace_back(std::move(storage));
 | 
			
		||||
    pop_out_data_event.writable->Signal();
 | 
			
		||||
    pop_out_data_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
 | 
			
		||||
@@ -105,23 +109,23 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
 | 
			
		||||
 | 
			
		||||
void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
 | 
			
		||||
    out_interactive_channel.emplace_back(std::move(storage));
 | 
			
		||||
    pop_interactive_out_data_event.writable->Signal();
 | 
			
		||||
    pop_interactive_out_data_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppletDataBroker::SignalStateChanged() const {
 | 
			
		||||
    state_changed_event.writable->Signal();
 | 
			
		||||
    state_changed_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
 | 
			
		||||
    return pop_out_data_event.readable;
 | 
			
		||||
    return pop_out_data_event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
 | 
			
		||||
    return pop_interactive_out_data_event.readable;
 | 
			
		||||
    return pop_interactive_out_data_event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
 | 
			
		||||
    return state_changed_event.readable;
 | 
			
		||||
    return state_changed_event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Applet::Applet(Kernel::KernelCore& kernel_) : broker{kernel_} {}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <queue>
 | 
			
		||||
 | 
			
		||||
#include "common/swap.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
 | 
			
		||||
union ResultCode;
 | 
			
		||||
@@ -29,7 +29,9 @@ class WebBrowserApplet;
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KernelCore;
 | 
			
		||||
}
 | 
			
		||||
class KEvent;
 | 
			
		||||
class KReadableEvent;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
namespace Service::AM {
 | 
			
		||||
 | 
			
		||||
@@ -106,13 +108,13 @@ private:
 | 
			
		||||
    // PopInteractiveDataToGame and PushInteractiveDataFromApplet
 | 
			
		||||
    std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair state_changed_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> state_changed_event;
 | 
			
		||||
 | 
			
		||||
    // Signaled on PushNormalDataFromApplet
 | 
			
		||||
    Kernel::EventPair pop_out_data_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> pop_out_data_event;
 | 
			
		||||
 | 
			
		||||
    // Signaled on PushInteractiveDataFromApplet
 | 
			
		||||
    Kernel::EventPair pop_interactive_out_data_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> pop_interactive_out_data_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Applet {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <numeric>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/file_sys/common_funcs.h"
 | 
			
		||||
@@ -14,8 +15,8 @@
 | 
			
		||||
#include "core/file_sys/patch_manager.h"
 | 
			
		||||
#include "core/file_sys/registered_cache.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/service/aoc/aoc_u.h"
 | 
			
		||||
@@ -62,8 +63,9 @@ public:
 | 
			
		||||
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        purchased_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            system.Kernel(), "IPurchaseEventManager:PurchasedEvent");
 | 
			
		||||
        purchased_event =
 | 
			
		||||
            Kernel::KEvent::Create(system.Kernel(), "IPurchaseEventManager:PurchasedEvent");
 | 
			
		||||
        purchased_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -96,10 +98,10 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(purchased_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(purchased_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair purchased_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> purchased_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AOC_U::AOC_U(Core::System& system_)
 | 
			
		||||
@@ -124,8 +126,8 @@ AOC_U::AOC_U(Core::System& system_)
 | 
			
		||||
    RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    aoc_change_event =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, "GetAddOnContentListChanged:Event");
 | 
			
		||||
    aoc_change_event = Kernel::KEvent::Create(kernel, "GetAddOnContentListChanged:Event");
 | 
			
		||||
    aoc_change_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AOC_U::~AOC_U() = default;
 | 
			
		||||
@@ -252,7 +254,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.PushCopyObjects(aoc_change_event.readable);
 | 
			
		||||
    rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KWritableEvent;
 | 
			
		||||
class KEvent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service::AOC {
 | 
			
		||||
@@ -31,7 +31,7 @@ private:
 | 
			
		||||
    void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
 | 
			
		||||
 | 
			
		||||
    std::vector<u64> add_on_content;
 | 
			
		||||
    Kernel::EventPair aoc_change_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> aoc_change_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Registers all AOC services with the specified service manager.
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/hle_ipc.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
@@ -66,13 +67,13 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        // This is the event handle used to check if the audio buffer was released
 | 
			
		||||
        buffer_event =
 | 
			
		||||
            Kernel::KWritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased");
 | 
			
		||||
        buffer_event = Kernel::KEvent::Create(system.Kernel(), "IAudioOutBufferReleased");
 | 
			
		||||
        buffer_event->Initialize();
 | 
			
		||||
 | 
			
		||||
        stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
 | 
			
		||||
                                       audio_params.channel_count, std::move(unique_name), [this] {
 | 
			
		||||
                                           const auto guard = LockService();
 | 
			
		||||
                                           buffer_event.writable->Signal();
 | 
			
		||||
                                           buffer_event->GetWritableEvent()->Signal();
 | 
			
		||||
                                       });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -125,7 +126,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(buffer_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(buffer_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -219,7 +220,7 @@ private:
 | 
			
		||||
    [[maybe_unused]] AudoutParams audio_params{};
 | 
			
		||||
 | 
			
		||||
    /// This is the event handle used to check if the audio buffer was released
 | 
			
		||||
    Kernel::EventPair buffer_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> buffer_event;
 | 
			
		||||
    Core::Memory::Memory& main_memory;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/hle_ipc.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
@@ -47,13 +48,13 @@ public:
 | 
			
		||||
        // clang-format on
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        system_event =
 | 
			
		||||
            Kernel::KWritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent");
 | 
			
		||||
        system_event = Kernel::KEvent::Create(system.Kernel(), "IAudioRenderer:SystemEvent");
 | 
			
		||||
        system_event->Initialize();
 | 
			
		||||
        renderer = std::make_unique<AudioCore::AudioRenderer>(
 | 
			
		||||
            system.CoreTiming(), system.Memory(), audren_params,
 | 
			
		||||
            [this]() {
 | 
			
		||||
                const auto guard = LockService();
 | 
			
		||||
                system_event.writable->Signal();
 | 
			
		||||
                system_event->GetWritableEvent()->Signal();
 | 
			
		||||
            },
 | 
			
		||||
            instance_number);
 | 
			
		||||
    }
 | 
			
		||||
@@ -126,7 +127,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(system_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(system_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -160,7 +161,7 @@ private:
 | 
			
		||||
        rb.Push(ERR_NOT_SUPPORTED);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair system_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> system_event;
 | 
			
		||||
    std::unique_ptr<AudioCore::AudioRenderer> renderer;
 | 
			
		||||
    u32 rendering_time_limit_percent = 100;
 | 
			
		||||
};
 | 
			
		||||
@@ -187,17 +188,19 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        auto& kernel = system.Kernel();
 | 
			
		||||
        buffer_event =
 | 
			
		||||
            Kernel::KWritableEvent::CreateEventPair(kernel, "IAudioOutBufferReleasedEvent");
 | 
			
		||||
        buffer_event = Kernel::KEvent::Create(kernel, "IAudioOutBufferReleasedEvent");
 | 
			
		||||
        buffer_event->Initialize();
 | 
			
		||||
 | 
			
		||||
        // Should be similar to audio_output_device_switch_event
 | 
			
		||||
        audio_input_device_switch_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent");
 | 
			
		||||
        audio_input_device_switch_event =
 | 
			
		||||
            Kernel::KEvent::Create(kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent");
 | 
			
		||||
        audio_input_device_switch_event->Initialize();
 | 
			
		||||
 | 
			
		||||
        // Should only be signalled when an audio output device has been changed, example: speaker
 | 
			
		||||
        // to headset
 | 
			
		||||
        audio_output_device_switch_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
 | 
			
		||||
        audio_output_device_switch_event =
 | 
			
		||||
            Kernel::KEvent::Create(kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
 | 
			
		||||
        audio_output_device_switch_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -286,11 +289,11 @@ private:
 | 
			
		||||
    void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        LOG_WARNING(Service_Audio, "(STUBBED) called");
 | 
			
		||||
 | 
			
		||||
        buffer_event.writable->Signal();
 | 
			
		||||
        buffer_event->GetWritableEvent()->Signal();
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(buffer_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(buffer_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -307,7 +310,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(audio_input_device_switch_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(audio_input_device_switch_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -315,13 +318,13 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(audio_output_device_switch_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(audio_output_device_switch_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u32_le revision = 0;
 | 
			
		||||
    Kernel::EventPair buffer_event;
 | 
			
		||||
    Kernel::EventPair audio_input_device_switch_event;
 | 
			
		||||
    Kernel::EventPair audio_output_device_switch_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> buffer_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> audio_input_device_switch_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> audio_output_device_switch_event;
 | 
			
		||||
 | 
			
		||||
}; // namespace Audio
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,9 @@
 | 
			
		||||
#include "common/hex_util.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/lock.h"
 | 
			
		||||
#include "core/hle/service/bcat/backend/backend.h"
 | 
			
		||||
 | 
			
		||||
@@ -12,12 +15,13 @@ namespace Service::BCAT {
 | 
			
		||||
 | 
			
		||||
ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
 | 
			
		||||
                                               std::string_view event_name) {
 | 
			
		||||
    event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
        kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
 | 
			
		||||
    event = Kernel::KEvent::Create(kernel,
 | 
			
		||||
                                   "ProgressServiceBackend:UpdateEvent:" + std::string(event_name));
 | 
			
		||||
    event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> ProgressServiceBackend::GetEvent() const {
 | 
			
		||||
    return event.readable;
 | 
			
		||||
    return event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() {
 | 
			
		||||
@@ -85,9 +89,9 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) {
 | 
			
		||||
void ProgressServiceBackend::SignalUpdate() const {
 | 
			
		||||
    if (need_hle_lock) {
 | 
			
		||||
        std::lock_guard lock(HLE::g_hle_lock);
 | 
			
		||||
        event.writable->Signal();
 | 
			
		||||
        event->GetWritableEvent()->Signal();
 | 
			
		||||
    } else {
 | 
			
		||||
        event.writable->Signal();
 | 
			
		||||
        event->GetWritableEvent()->Signal();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,6 @@
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/file_sys/vfs_types.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/result.h"
 | 
			
		||||
 | 
			
		||||
namespace Core {
 | 
			
		||||
@@ -21,7 +19,9 @@ class System;
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KernelCore;
 | 
			
		||||
}
 | 
			
		||||
class KEvent;
 | 
			
		||||
class KReadableEvent;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
namespace Service::BCAT {
 | 
			
		||||
 | 
			
		||||
@@ -104,7 +104,7 @@ private:
 | 
			
		||||
    void SignalUpdate() const;
 | 
			
		||||
 | 
			
		||||
    DeliveryCacheProgressImpl impl{};
 | 
			
		||||
    Kernel::EventPair event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> event;
 | 
			
		||||
    bool need_hle_lock = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/hle_ipc.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/service/btdrv/btdrv.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
@@ -35,7 +35,8 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        auto& kernel = system.Kernel();
 | 
			
		||||
        register_event = Kernel::KWritableEvent::CreateEventPair(kernel, "BT:RegisterEvent");
 | 
			
		||||
        register_event = Kernel::KEvent::Create(kernel, "BT:RegisterEvent");
 | 
			
		||||
        register_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -44,10 +45,10 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(register_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(register_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair register_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> register_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BtDrv final : public ServiceFramework<BtDrv> {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,8 @@
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/hle_ipc.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/service/btm/btm.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
@@ -58,12 +58,14 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        auto& kernel = system.Kernel();
 | 
			
		||||
        scan_event = Kernel::KWritableEvent::CreateEventPair(kernel, "IBtmUserCore:ScanEvent");
 | 
			
		||||
        connection_event =
 | 
			
		||||
            Kernel::KWritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConnectionEvent");
 | 
			
		||||
        service_discovery =
 | 
			
		||||
            Kernel::KWritableEvent::CreateEventPair(kernel, "IBtmUserCore:Discovery");
 | 
			
		||||
        config_event = Kernel::KWritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConfigEvent");
 | 
			
		||||
        scan_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ScanEvent");
 | 
			
		||||
        scan_event->Initialize();
 | 
			
		||||
        connection_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConnectionEvent");
 | 
			
		||||
        connection_event->Initialize();
 | 
			
		||||
        service_discovery = Kernel::KEvent::Create(kernel, "IBtmUserCore:Discovery");
 | 
			
		||||
        service_discovery->Initialize();
 | 
			
		||||
        config_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConfigEvent");
 | 
			
		||||
        config_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -72,7 +74,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(scan_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(scan_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -80,7 +82,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(connection_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(connection_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -88,7 +90,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(service_discovery.readable);
 | 
			
		||||
        rb.PushCopyObjects(service_discovery->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -96,13 +98,13 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(config_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(config_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair scan_event;
 | 
			
		||||
    Kernel::EventPair connection_event;
 | 
			
		||||
    Kernel::EventPair service_discovery;
 | 
			
		||||
    Kernel::EventPair config_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> scan_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> connection_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> service_discovery;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> config_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BTM_USR final : public ServiceFramework<BTM_USR> {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
#include "common/uuid.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/service/friend/errors.h"
 | 
			
		||||
@@ -183,8 +184,9 @@ public:
 | 
			
		||||
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        notification_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            system.Kernel(), "INotificationService:NotifyEvent");
 | 
			
		||||
        notification_event =
 | 
			
		||||
            Kernel::KEvent::Create(system.Kernel(), "INotificationService:NotifyEvent");
 | 
			
		||||
        notification_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -193,7 +195,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(notification_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(notification_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Clear(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -258,7 +260,7 @@ private:
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Common::UUID uuid{Common::INVALID_UUID};
 | 
			
		||||
    Kernel::EventPair notification_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> notification_event;
 | 
			
		||||
    std::queue<SizedNotificationInfo> notifications;
 | 
			
		||||
    States states{};
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/core_timing.h"
 | 
			
		||||
#include "core/frontend/input.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
@@ -153,7 +154,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
 | 
			
		||||
    const auto controller_type = connected_controllers[controller_idx].type;
 | 
			
		||||
    auto& controller = shared_memory_entries[controller_idx];
 | 
			
		||||
    if (controller_type == NPadControllerType::None) {
 | 
			
		||||
        styleset_changed_events[controller_idx].writable->Signal();
 | 
			
		||||
        styleset_changed_events[controller_idx]->GetWritableEvent()->Signal();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    controller.joy_styles.raw = 0; // Zero out
 | 
			
		||||
@@ -233,8 +234,9 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
 | 
			
		||||
void Controller_NPad::OnInit() {
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
 | 
			
		||||
        styleset_changed_events[i] = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
 | 
			
		||||
        styleset_changed_events[i] =
 | 
			
		||||
            Kernel::KEvent::Create(kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
 | 
			
		||||
        styleset_changed_events[i]->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!IsControllerActivated()) {
 | 
			
		||||
@@ -875,11 +877,11 @@ bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_dev
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> Controller_NPad::GetStyleSetChangedEvent(
 | 
			
		||||
    u32 npad_id) const {
 | 
			
		||||
    const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)];
 | 
			
		||||
    return styleset_event.readable;
 | 
			
		||||
    return styleset_event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller_NPad::SignalStyleSetChangedEvent(u32 npad_id) const {
 | 
			
		||||
    styleset_changed_events[NPadIdToIndex(npad_id)].writable->Signal();
 | 
			
		||||
    styleset_changed_events[NPadIdToIndex(npad_id)]->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,11 +9,15 @@
 | 
			
		||||
#include "common/bit_field.h"
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/frontend/input.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
#include "core/hle/service/hid/controllers/controller_base.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KEvent;
 | 
			
		||||
class KReadableEvent;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
namespace Service::HID {
 | 
			
		||||
 | 
			
		||||
constexpr u32 NPAD_HANDHELD = 32;
 | 
			
		||||
@@ -452,7 +456,7 @@ private:
 | 
			
		||||
    // NpadCommunicationMode is unknown, default value is 1
 | 
			
		||||
    NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1};
 | 
			
		||||
    // Each controller should have their own styleset changed event
 | 
			
		||||
    std::array<Kernel::EventPair, 10> styleset_changed_events;
 | 
			
		||||
    std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;
 | 
			
		||||
    std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
 | 
			
		||||
    std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
 | 
			
		||||
    bool permit_vibration_session_enabled{false};
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_thread.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
@@ -25,7 +26,8 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst
 | 
			
		||||
                             const char* name)
 | 
			
		||||
    : ServiceFramework{system_, name}, module{std::move(module_)} {
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    nfc_tag_load = Kernel::KWritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected");
 | 
			
		||||
    nfc_tag_load = Kernel::KEvent::Create(kernel, "IUser:NFCTagDetected");
 | 
			
		||||
    nfc_tag_load->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Module::Interface::~Interface() = default;
 | 
			
		||||
@@ -64,9 +66,10 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        auto& kernel = system.Kernel();
 | 
			
		||||
        deactivate_event = Kernel::KWritableEvent::CreateEventPair(kernel, "IUser:DeactivateEvent");
 | 
			
		||||
        availability_change_event =
 | 
			
		||||
            Kernel::KWritableEvent::CreateEventPair(kernel, "IUser:AvailabilityChangeEvent");
 | 
			
		||||
        deactivate_event = Kernel::KEvent::Create(kernel, "IUser:DeactivateEvent");
 | 
			
		||||
        deactivate_event->Initialize();
 | 
			
		||||
        availability_change_event = Kernel::KEvent::Create(kernel, "IUser:AvailabilityChangeEvent");
 | 
			
		||||
        availability_change_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -164,7 +167,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(deactivate_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(deactivate_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void StopDetection(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -173,7 +176,7 @@ private:
 | 
			
		||||
        switch (device_state) {
 | 
			
		||||
        case DeviceState::TagFound:
 | 
			
		||||
        case DeviceState::TagNearby:
 | 
			
		||||
            deactivate_event.writable->Signal();
 | 
			
		||||
            deactivate_event->GetWritableEvent()->Signal();
 | 
			
		||||
            device_state = DeviceState::Initialized;
 | 
			
		||||
            break;
 | 
			
		||||
        case DeviceState::SearchingForTag:
 | 
			
		||||
@@ -262,7 +265,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(availability_change_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(availability_change_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GetRegisterInfo(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -316,8 +319,8 @@ private:
 | 
			
		||||
    const u32 npad_id{0};       // Player 1 controller
 | 
			
		||||
    State state{State::NonInitialized};
 | 
			
		||||
    DeviceState device_state{DeviceState::Initialized};
 | 
			
		||||
    Kernel::EventPair deactivate_event;
 | 
			
		||||
    Kernel::EventPair availability_change_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> deactivate_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> availability_change_event;
 | 
			
		||||
    const Module::Interface& nfp_interface;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -336,12 +339,12 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::memcpy(&amiibo, buffer.data(), sizeof(amiibo));
 | 
			
		||||
    nfc_tag_load.writable->Signal();
 | 
			
		||||
    nfc_tag_load->GetWritableEvent()->Signal();
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::shared_ptr<Kernel::KReadableEvent>& Module::Interface::GetNFCEvent() const {
 | 
			
		||||
    return nfc_tag_load.readable;
 | 
			
		||||
    return nfc_tag_load->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,13 @@
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KEvent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service::NFP {
 | 
			
		||||
 | 
			
		||||
class Module final {
 | 
			
		||||
@@ -39,7 +42,7 @@ public:
 | 
			
		||||
        const AmiiboFile& GetAmiiboBuffer() const;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        Kernel::EventPair nfc_tag_load{};
 | 
			
		||||
        std::shared_ptr<Kernel::KEvent> nfc_tag_load;
 | 
			
		||||
        AmiiboFile amiibo{};
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,8 @@
 | 
			
		||||
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/service/nifm/nifm.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
@@ -158,8 +158,11 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        auto& kernel = system.Kernel();
 | 
			
		||||
        event1 = Kernel::KWritableEvent::CreateEventPair(kernel, "IRequest:Event1");
 | 
			
		||||
        event2 = Kernel::KWritableEvent::CreateEventPair(kernel, "IRequest:Event2");
 | 
			
		||||
 | 
			
		||||
        event1 = Kernel::KEvent::Create(kernel, "IRequest:Event1");
 | 
			
		||||
        event1->Initialize();
 | 
			
		||||
        event2 = Kernel::KEvent::Create(kernel, "IRequest:Event2");
 | 
			
		||||
        event2->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -195,7 +198,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 2};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(event1.readable, event2.readable);
 | 
			
		||||
        rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Cancel(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -226,7 +229,7 @@ private:
 | 
			
		||||
        rb.Push<u32>(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Kernel::EventPair event1, event2;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> event1, event2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class INetworkProfile final : public ServiceFramework<INetworkProfile> {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
@@ -301,17 +302,18 @@ public:
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        auto& kernel = system.Kernel();
 | 
			
		||||
        finished_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent");
 | 
			
		||||
        finished_event =
 | 
			
		||||
            Kernel::KEvent::Create(kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent");
 | 
			
		||||
        finished_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Kernel::EventPair finished_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> finished_event;
 | 
			
		||||
 | 
			
		||||
    void StartTask(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        // No need to connect to the internet, just finish the task straight away.
 | 
			
		||||
        LOG_DEBUG(Service_NIM, "called");
 | 
			
		||||
        finished_event.writable->Signal();
 | 
			
		||||
        finished_event->GetWritableEvent()->Signal();
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    }
 | 
			
		||||
@@ -321,7 +323,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(finished_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(finished_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void GetResult(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -333,7 +335,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    void Cancel(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        LOG_DEBUG(Service_NIM, "called");
 | 
			
		||||
        finished_event.writable->Clear();
 | 
			
		||||
        finished_event->GetWritableEvent()->Clear();
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
 | 
			
		||||
#include "video_core/gpu.h"
 | 
			
		||||
@@ -103,14 +103,14 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
 | 
			
		||||
    // This is mostly to take into account unimplemented features. As synced
 | 
			
		||||
    // gpu is always synced.
 | 
			
		||||
    if (!gpu.IsAsync()) {
 | 
			
		||||
        event.event.writable->Signal();
 | 
			
		||||
        event.event->GetWritableEvent()->Signal();
 | 
			
		||||
        return NvResult::Success;
 | 
			
		||||
    }
 | 
			
		||||
    auto lock = gpu.LockSync();
 | 
			
		||||
    const u32 current_syncpoint_value = event.fence.value;
 | 
			
		||||
    const s32 diff = current_syncpoint_value - params.threshold;
 | 
			
		||||
    if (diff >= 0) {
 | 
			
		||||
        event.event.writable->Signal();
 | 
			
		||||
        event.event->GetWritableEvent()->Signal();
 | 
			
		||||
        params.value = current_syncpoint_value;
 | 
			
		||||
        std::memcpy(output.data(), ¶ms, sizeof(params));
 | 
			
		||||
        return NvResult::Success;
 | 
			
		||||
@@ -137,7 +137,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
 | 
			
		||||
            params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
 | 
			
		||||
        }
 | 
			
		||||
        params.value |= event_id;
 | 
			
		||||
        event.event.writable->Clear();
 | 
			
		||||
        event.event->GetWritableEvent()->Clear();
 | 
			
		||||
        gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
 | 
			
		||||
        std::memcpy(output.data(), ¶ms, sizeof(params));
 | 
			
		||||
        return NvResult::Timeout;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
#include <fmt/format.h>
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/service/nvdrv/devices/nvdevice.h"
 | 
			
		||||
@@ -42,7 +43,8 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} {
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    for (u32 i = 0; i < MaxNvEvents; i++) {
 | 
			
		||||
        std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
 | 
			
		||||
        events_interface.events[i] = {Kernel::KWritableEvent::CreateEventPair(kernel, event_label)};
 | 
			
		||||
        events_interface.events[i] = {Kernel::KEvent::Create(kernel, std::move(event_label))};
 | 
			
		||||
        events_interface.events[i].event->Initialize();
 | 
			
		||||
        events_interface.status[i] = EventState::Free;
 | 
			
		||||
        events_interface.registered[i] = false;
 | 
			
		||||
    }
 | 
			
		||||
@@ -166,17 +168,17 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) {
 | 
			
		||||
        if (events_interface.assigned_syncpt[i] == syncpoint_id &&
 | 
			
		||||
            events_interface.assigned_value[i] == value) {
 | 
			
		||||
            events_interface.LiberateEvent(i);
 | 
			
		||||
            events_interface.events[i].event.writable->Signal();
 | 
			
		||||
            events_interface.events[i].event->GetWritableEvent()->Signal();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> Module::GetEvent(const u32 event_id) const {
 | 
			
		||||
    return events_interface.events[event_id].event.readable;
 | 
			
		||||
    return events_interface.events[event_id].event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KWritableEvent> Module::GetEventWriteable(const u32 event_id) const {
 | 
			
		||||
    return events_interface.events[event_id].event.writable;
 | 
			
		||||
    return events_interface.events[event_id].event->GetWritableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Nvidia
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,8 @@
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/service/nvdrv/nvdata.h"
 | 
			
		||||
#include "core/hle/service/nvdrv/syncpoint_manager.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
@@ -17,6 +17,10 @@ namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KEvent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service::NVFlinger {
 | 
			
		||||
class NVFlinger;
 | 
			
		||||
}
 | 
			
		||||
@@ -31,7 +35,7 @@ class nvdevice;
 | 
			
		||||
 | 
			
		||||
/// Represents an Nvidia event
 | 
			
		||||
struct NvEvent {
 | 
			
		||||
    Kernel::EventPair event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> event;
 | 
			
		||||
    Fence fence{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/service/nvflinger/buffer_queue.h"
 | 
			
		||||
@@ -16,7 +16,8 @@ namespace Service::NVFlinger {
 | 
			
		||||
 | 
			
		||||
BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
 | 
			
		||||
    : id(id), layer_id(layer_id) {
 | 
			
		||||
    buffer_wait_event = Kernel::KWritableEvent::CreateEventPair(kernel, "BufferQueue NativeHandle");
 | 
			
		||||
    buffer_wait_event = Kernel::KEvent::Create(kernel, "BufferQueue:WaitEvent");
 | 
			
		||||
    buffer_wait_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BufferQueue::~BufferQueue() = default;
 | 
			
		||||
@@ -41,7 +42,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
 | 
			
		||||
        .multi_fence = {},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    buffer_wait_event.writable->Signal();
 | 
			
		||||
    buffer_wait_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
 | 
			
		||||
@@ -119,7 +120,7 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult
 | 
			
		||||
    }
 | 
			
		||||
    free_buffers_condition.notify_one();
 | 
			
		||||
 | 
			
		||||
    buffer_wait_event.writable->Signal();
 | 
			
		||||
    buffer_wait_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
 | 
			
		||||
@@ -154,7 +155,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
 | 
			
		||||
    }
 | 
			
		||||
    free_buffers_condition.notify_one();
 | 
			
		||||
 | 
			
		||||
    buffer_wait_event.writable->Signal();
 | 
			
		||||
    buffer_wait_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferQueue::Connect() {
 | 
			
		||||
@@ -169,7 +170,7 @@ void BufferQueue::Disconnect() {
 | 
			
		||||
        std::unique_lock lock{queue_sequence_mutex};
 | 
			
		||||
        queue_sequence.clear();
 | 
			
		||||
    }
 | 
			
		||||
    buffer_wait_event.writable->Signal();
 | 
			
		||||
    buffer_wait_event->GetWritableEvent()->Signal();
 | 
			
		||||
    is_connect = false;
 | 
			
		||||
    free_buffers_condition.notify_one();
 | 
			
		||||
}
 | 
			
		||||
@@ -189,11 +190,11 @@ u32 BufferQueue::Query(QueryType type) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KWritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
 | 
			
		||||
    return buffer_wait_event.writable;
 | 
			
		||||
    return buffer_wait_event->GetWritableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> BufferQueue::GetBufferWaitEvent() const {
 | 
			
		||||
    return buffer_wait_event.readable;
 | 
			
		||||
    return buffer_wait_event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::NVFlinger
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,15 @@
 | 
			
		||||
#include "common/common_funcs.h"
 | 
			
		||||
#include "common/math_util.h"
 | 
			
		||||
#include "common/swap.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/object.h"
 | 
			
		||||
#include "core/hle/service/nvdrv/nvdata.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KernelCore;
 | 
			
		||||
}
 | 
			
		||||
class KEvent;
 | 
			
		||||
class KReadableEvent;
 | 
			
		||||
class KWritableEvent;
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
namespace Service::NVFlinger {
 | 
			
		||||
 | 
			
		||||
@@ -127,7 +129,7 @@ private:
 | 
			
		||||
    std::list<u32> free_buffers;
 | 
			
		||||
    std::array<Buffer, buffer_slots> buffers;
 | 
			
		||||
    std::list<u32> queue_sequence;
 | 
			
		||||
    Kernel::EventPair buffer_wait_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> buffer_wait_event;
 | 
			
		||||
 | 
			
		||||
    std::mutex free_buffers_mutex;
 | 
			
		||||
    std::condition_variable free_buffers_condition;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
@@ -31,27 +32,28 @@ public:
 | 
			
		||||
 | 
			
		||||
        RegisterHandlers(functions);
 | 
			
		||||
 | 
			
		||||
        state_change_event = Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
            system_.Kernel(), "IPsmSession::state_change_event");
 | 
			
		||||
        state_change_event =
 | 
			
		||||
            Kernel::KEvent::Create(system_.Kernel(), "IPsmSession::state_change_event");
 | 
			
		||||
        state_change_event->Initialize();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~IPsmSession() override = default;
 | 
			
		||||
 | 
			
		||||
    void SignalChargerTypeChanged() {
 | 
			
		||||
        if (should_signal && should_signal_charger_type) {
 | 
			
		||||
            state_change_event.writable->Signal();
 | 
			
		||||
            state_change_event->GetWritableEvent()->Signal();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SignalPowerSupplyChanged() {
 | 
			
		||||
        if (should_signal && should_signal_power_supply) {
 | 
			
		||||
            state_change_event.writable->Signal();
 | 
			
		||||
            state_change_event->GetWritableEvent()->Signal();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SignalBatteryVoltageStateChanged() {
 | 
			
		||||
        if (should_signal && should_signal_battery_voltage) {
 | 
			
		||||
            state_change_event.writable->Signal();
 | 
			
		||||
            state_change_event->GetWritableEvent()->Signal();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -63,7 +65,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2, 1};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
        rb.PushCopyObjects(state_change_event.readable);
 | 
			
		||||
        rb.PushCopyObjects(state_change_event->GetReadableEvent());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
@@ -112,7 +114,7 @@ private:
 | 
			
		||||
    bool should_signal_power_supply{};
 | 
			
		||||
    bool should_signal_battery_voltage{};
 | 
			
		||||
    bool should_signal{};
 | 
			
		||||
    Kernel::EventPair state_change_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> state_change_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class PSM final : public ServiceFramework<PSM> {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/service/time/standard_local_system_clock_core.h"
 | 
			
		||||
#include "core/hle/service/time/standard_network_system_clock_core.h"
 | 
			
		||||
#include "core/hle/service/time/standard_user_system_clock_core.h"
 | 
			
		||||
@@ -18,8 +18,10 @@ StandardUserSystemClockCore::StandardUserSystemClockCore(
 | 
			
		||||
      local_system_clock_core{local_system_clock_core},
 | 
			
		||||
      network_system_clock_core{network_system_clock_core}, auto_correction_enabled{},
 | 
			
		||||
      auto_correction_time{SteadyClockTimePoint::GetRandom()},
 | 
			
		||||
      auto_correction_event{Kernel::KWritableEvent::CreateEventPair(
 | 
			
		||||
          system.Kernel(), "StandardUserSystemClockCore:AutoCorrectionEvent")} {}
 | 
			
		||||
      auto_correction_event{Kernel::KEvent::Create(
 | 
			
		||||
          system.Kernel(), "StandardUserSystemClockCore:AutoCorrectionEvent")} {
 | 
			
		||||
    auto_correction_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system,
 | 
			
		||||
                                                                      bool value) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/service/time/clock_types.h"
 | 
			
		||||
#include "core/hle/service/time/system_clock_core.h"
 | 
			
		||||
 | 
			
		||||
@@ -12,6 +11,10 @@ namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KEvent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service::Time::Clock {
 | 
			
		||||
 | 
			
		||||
class StandardLocalSystemClockCore;
 | 
			
		||||
@@ -51,7 +54,7 @@ private:
 | 
			
		||||
    StandardNetworkSystemClockCore& network_system_clock_core;
 | 
			
		||||
    bool auto_correction_enabled{};
 | 
			
		||||
    SteadyClockTimePoint auto_correction_time;
 | 
			
		||||
    Kernel::EventPair auto_correction_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> auto_correction_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Time::Clock
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,9 @@
 | 
			
		||||
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/k_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_readable_event.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
#include "core/hle/service/vi/display/vi_display.h"
 | 
			
		||||
#include "core/hle/service/vi/layer/vi_layer.h"
 | 
			
		||||
 | 
			
		||||
@@ -17,8 +19,8 @@ namespace Service::VI {
 | 
			
		||||
 | 
			
		||||
Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} {
 | 
			
		||||
    auto& kernel = system.Kernel();
 | 
			
		||||
    vsync_event =
 | 
			
		||||
        Kernel::KWritableEvent::CreateEventPair(kernel, fmt::format("Display VSync Event {}", id));
 | 
			
		||||
    vsync_event = Kernel::KEvent::Create(kernel, fmt::format("Display VSync Event {}", id));
 | 
			
		||||
    vsync_event->Initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Display::~Display() = default;
 | 
			
		||||
@@ -32,11 +34,11 @@ const Layer& Display::GetLayer(std::size_t index) const {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::KReadableEvent> Display::GetVSyncEvent() const {
 | 
			
		||||
    return vsync_event.readable;
 | 
			
		||||
    return vsync_event->GetReadableEvent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Display::SignalVSyncEvent() {
 | 
			
		||||
    vsync_event.writable->Signal();
 | 
			
		||||
    vsync_event->GetWritableEvent()->Signal();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Display::CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue) {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,10 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "core/hle/kernel/k_writable_event.h"
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
class KEvent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Service::NVFlinger {
 | 
			
		||||
class BufferQueue;
 | 
			
		||||
@@ -99,7 +102,7 @@ private:
 | 
			
		||||
    std::string name;
 | 
			
		||||
 | 
			
		||||
    std::vector<std::shared_ptr<Layer>> layers;
 | 
			
		||||
    Kernel::EventPair vsync_event;
 | 
			
		||||
    std::shared_ptr<Kernel::KEvent> vsync_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::VI
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user