Kernel: Convert Event to not use Handles

This commit is contained in:
Yuri Kunde Schlesner 2015-01-23 03:11:25 -02:00
parent ad80ff1e32
commit d52d859936
10 changed files with 153 additions and 154 deletions

View file

@ -14,78 +14,37 @@
namespace Kernel { namespace Kernel {
class Event : public WaitObject { ResultVal<SharedPtr<Event>> Event::Create(ResetType reset_type, std::string name) {
public: SharedPtr<Event> evt(new Event);
std::string GetTypeName() const override { return "Event"; } // TOOD(yuriks): Don't create Handle (see Thread::Create())
std::string GetName() const override { return name; } CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(evt));
static const HandleType HANDLE_TYPE = HandleType::Event;
HandleType GetHandleType() const override { return HANDLE_TYPE; }
ResetType intitial_reset_type; ///< ResetType specified at Event initialization
ResetType reset_type; ///< Current ResetType
bool signaled; ///< Whether the event has already been signaled
std::string name; ///< Name of event (optional)
bool ShouldWait() override {
return !signaled;
}
void Acquire() override {
_assert_msg_(Kernel, !ShouldWait(), "object unavailable!");
// Release the event if it's not sticky...
if (reset_type != RESETTYPE_STICKY)
signaled = false;
}
};
ResultCode SignalEvent(const Handle handle) {
Event* evt = g_handle_table.Get<Event>(handle).get();
if (evt == nullptr)
return InvalidHandle(ErrorModule::Kernel);
evt->signaled = true;
evt->WakeupAllWaitingThreads();
return RESULT_SUCCESS;
}
ResultCode ClearEvent(Handle handle) {
Event* evt = g_handle_table.Get<Event>(handle).get();
if (evt == nullptr)
return InvalidHandle(ErrorModule::Kernel);
evt->signaled = false;
return RESULT_SUCCESS;
}
/**
* Creates an event
* @param handle Reference to handle for the newly created mutex
* @param reset_type ResetType describing how to create event
* @param name Optional name of event
* @return Newly created Event object
*/
static Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) {
Event* evt = new Event;
// TOOD(yuriks): Fix error reporting
handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE);
evt->signaled = false; evt->signaled = false;
evt->reset_type = evt->intitial_reset_type = reset_type; evt->reset_type = evt->intitial_reset_type = reset_type;
evt->name = name; evt->name = std::move(name);
return evt; return MakeResult<SharedPtr<Event>>(evt);
} }
Handle CreateEvent(const ResetType reset_type, const std::string& name) { bool Event::ShouldWait() {
Handle handle; return !signaled;
Event* evt = CreateEvent(handle, reset_type, name); }
return handle;
void Event::Acquire() {
_assert_msg_(Kernel, !ShouldWait(), "object unavailable!");
// Release the event if it's not sticky...
if (reset_type != RESETTYPE_STICKY)
signaled = false;
}
void Event::Signal() {
signaled = true;
WakeupAllWaitingThreads();
}
void Event::Clear() {
signaled = false;
} }
} // namespace } // namespace

View file

@ -11,26 +11,35 @@
namespace Kernel { namespace Kernel {
/** class Event : public WaitObject {
* Signals an event public:
* @param handle Handle to event to signal /**
* @return Result of operation, 0 on success, otherwise error code * Creates an event
*/ * @param reset_type ResetType describing how to create event
ResultCode SignalEvent(const Handle handle); * @param name Optional name of event
*/
static ResultVal<SharedPtr<Event>> Create(ResetType reset_type, std::string name = "Unknown");
/** std::string GetTypeName() const override { return "Event"; }
* Clears an event std::string GetName() const override { return name; }
* @param handle Handle to event to clear
* @return Result of operation, 0 on success, otherwise error code
*/
ResultCode ClearEvent(Handle handle);
/** static const HandleType HANDLE_TYPE = HandleType::Event;
* Creates an event HandleType GetHandleType() const override { return HANDLE_TYPE; }
* @param reset_type ResetType describing how to create event
* @param name Optional name of event ResetType intitial_reset_type; ///< ResetType specified at Event initialization
* @return Handle to newly created Event object ResetType reset_type; ///< Current ResetType
*/
Handle CreateEvent(const ResetType reset_type, const std::string& name="Unknown"); bool signaled; ///< Whether the event has already been signaled
std::string name; ///< Name of event (optional)
bool ShouldWait() override;
void Acquire() override;
void Signal();
void Clear();
private:
Event() = default;
};
} // namespace } // namespace

View file

@ -30,8 +30,8 @@ static const VAddr SHARED_FONT_VADDR = 0x18000000;
static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem; static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
static Kernel::SharedPtr<Kernel::Mutex> lock; static Kernel::SharedPtr<Kernel::Mutex> lock;
static Handle notification_event_handle = 0; ///< APT notification event handle static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
static Handle pause_event_handle = 0; ///< APT pause event handle static Kernel::SharedPtr<Kernel::Event> pause_event = 0; ///< APT pause event
static std::vector<u8> shared_font; static std::vector<u8> shared_font;
/// Signals used by APT functions /// Signals used by APT functions
@ -68,14 +68,16 @@ enum class AppID : u32 {
void Initialize(Service::Interface* self) { void Initialize(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
notification_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Notification"); // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
pause_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause"); notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification").MoveFrom();
pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause").MoveFrom();
cmd_buff[3] = notification_event_handle; cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
cmd_buff[4] = pause_event_handle; cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
Kernel::ClearEvent(notification_event_handle); // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called.
Kernel::SignalEvent(pause_event_handle); // Fire start event notification_event->Clear();
pause_event->Signal(); // Fire start event
_assert_msg_(KERNEL, (nullptr != lock), "Cannot initialize without lock"); _assert_msg_(KERNEL, (nullptr != lock), "Cannot initialize without lock");
lock->Release(); lock->Release();
@ -94,7 +96,7 @@ void NotifyToWait(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1]; u32 app_id = cmd_buff[1];
// TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further. // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
Kernel::SignalEvent(pause_event_handle); pause_event->Signal();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[1] = RESULT_SUCCESS.raw; // No error
LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id); LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
@ -104,10 +106,6 @@ void GetLockHandle(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
if (nullptr == lock) {
// TODO(bunnei): Verify if this is created here or at application boot?
lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom();
}
cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[1] = RESULT_SUCCESS.raw; // No error
// Not sure what these parameters are used for, but retail apps check that they are 0 after // Not sure what these parameters are used for, but retail apps check that they are 0 after
@ -520,7 +518,7 @@ Interface::Interface() {
shared_font_mem = nullptr; shared_font_mem = nullptr;
} }
lock = nullptr; lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom();
Register(FunctionTable, ARRAY_SIZE(FunctionTable)); Register(FunctionTable, ARRAY_SIZE(FunctionTable));
} }

View file

@ -13,8 +13,8 @@
namespace DSP_DSP { namespace DSP_DSP {
static u32 read_pipe_count = 0; static u32 read_pipe_count = 0;
static Handle semaphore_event = 0; static Kernel::SharedPtr<Kernel::Event> semaphore_event;
static Handle interrupt_event = 0; static Kernel::SharedPtr<Kernel::Event> interrupt_event;
void SignalInterrupt() { void SignalInterrupt() {
// TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
@ -24,7 +24,7 @@ void SignalInterrupt() {
// DSP interrupts, and trigger them at the appropriate times. // DSP interrupts, and trigger them at the appropriate times.
if (interrupt_event != 0) if (interrupt_event != 0)
Kernel::SignalEvent(interrupt_event); interrupt_event->Signal();
} }
/** /**
@ -78,8 +78,8 @@ void LoadComponent(Service::Interface* self) {
void GetSemaphoreEventHandle(Service::Interface* self) { void GetSemaphoreEventHandle(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0; // No error cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[3] = semaphore_event; // Event handle cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).MoveFrom(); // Event handle
LOG_WARNING(Service_DSP, "(STUBBED) called"); LOG_WARNING(Service_DSP, "(STUBBED) called");
} }
@ -96,9 +96,16 @@ void GetSemaphoreEventHandle(Service::Interface* self) {
void RegisterInterruptEvents(Service::Interface* self) { void RegisterInterruptEvents(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
interrupt_event = static_cast<Handle>(cmd_buff[4]); auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
if (evt != nullptr) {
interrupt_event = evt;
cmd_buff[1] = 0; // No error
} else {
LOG_ERROR(Service_DSP, "called with invalid handle=%08X", cmd_buff[4]);
cmd_buff[1] = 0; // No error // TODO(yuriks): An error should be returned from SendSyncRequest, not in the cmdbuf
cmd_buff[1] = -1;
}
LOG_WARNING(Service_DSP, "(STUBBED) called"); LOG_WARNING(Service_DSP, "(STUBBED) called");
} }
@ -194,8 +201,9 @@ const Interface::FunctionInfo FunctionTable[] = {
// Interface class // Interface class
Interface::Interface() { Interface::Interface() {
semaphore_event = Kernel::CreateEvent(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT,
interrupt_event = 0; "DSP_DSP::semaphore_event").MoveFrom();
interrupt_event = nullptr;
read_pipe_count = 0; read_pipe_count = 0;
Register(FunctionTable, ARRAY_SIZE(FunctionTable)); Register(FunctionTable, ARRAY_SIZE(FunctionTable));

View file

@ -22,9 +22,12 @@ GraphicsDebugger g_debugger;
namespace GSP_GPU { namespace GSP_GPU {
Handle g_interrupt_event = 0; ///< Handle to event triggered when GSP interrupt has been signalled /// Event triggered when GSP interrupt has been signalled
Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory; ///< GSP shared memoryings Kernel::SharedPtr<Kernel::Event> g_interrupt_event;
u32 g_thread_id = 1; ///< Thread index into interrupt relay queue, 1 is arbitrary /// GSP shared memoryings
Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory;
/// Thread index into interrupt relay queue, 1 is arbitrary
u32 g_thread_id = 1;
/// Gets a pointer to a thread command buffer in GSP shared memory /// Gets a pointer to a thread command buffer in GSP shared memory
static inline u8* GetCommandBuffer(u32 thread_id) { static inline u8* GetCommandBuffer(u32 thread_id) {
@ -181,10 +184,10 @@ static void FlushDataCache(Service::Interface* self) {
static void RegisterInterruptRelayQueue(Service::Interface* self) { static void RegisterInterruptRelayQueue(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
u32 flags = cmd_buff[1]; u32 flags = cmd_buff[1];
g_interrupt_event = cmd_buff[3];
g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem").MoveFrom();
_assert_msg_(GSP, (g_interrupt_event != 0), "handle is not valid!"); g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]);
_assert_msg_(GSP, (g_interrupt_event != nullptr), "handle is not valid!");
g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem").MoveFrom();
Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
@ -192,7 +195,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
cmd_buff[2] = g_thread_id++; // Thread ID cmd_buff[2] = g_thread_id++; // Thread ID
cmd_buff[4] = shmem_handle; // GSP shared memory cmd_buff[4] = shmem_handle; // GSP shared memory
Kernel::SignalEvent(g_interrupt_event); // TODO(bunnei): Is this correct? g_interrupt_event->Signal(); // TODO(bunnei): Is this correct?
} }
/** /**
@ -234,7 +237,7 @@ void SignalInterrupt(InterruptId interrupt_id) {
info->is_dirty = false; info->is_dirty = false;
} }
} }
Kernel::SignalEvent(g_interrupt_event); g_interrupt_event->Signal();
} }
/// Executes the next GSP command /// Executes the next GSP command

View file

@ -14,11 +14,11 @@ namespace HID {
Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem = nullptr; Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem = nullptr;
Handle g_event_pad_or_touch_1 = 0; Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
Handle g_event_pad_or_touch_2 = 0; Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_2;
Handle g_event_accelerometer = 0; Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
Handle g_event_gyroscope = 0; Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
Handle g_event_debug_pad = 0; Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
// Next Pad state update information // Next Pad state update information
static PadState next_state = {{0}}; static PadState next_state = {{0}};
@ -115,19 +115,21 @@ void PadUpdateComplete() {
} }
// Signal both handles when there's an update to Pad or touch // Signal both handles when there's an update to Pad or touch
Kernel::SignalEvent(g_event_pad_or_touch_1); g_event_pad_or_touch_1->Signal();
Kernel::SignalEvent(g_event_pad_or_touch_2); g_event_pad_or_touch_2->Signal();
} }
void HIDInit() { void HIDInit() {
g_shared_mem = Kernel::SharedMemory::Create("HID:SharedMem").MoveFrom(); using namespace Kernel;
g_shared_mem = SharedMemory::Create("HID:SharedMem").MoveFrom();
// Create event handles // Create event handles
g_event_pad_or_touch_1 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1"); g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1").MoveFrom();
g_event_pad_or_touch_2 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2"); g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2").MoveFrom();
g_event_accelerometer = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventAccelerometer"); g_event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer").MoveFrom();
g_event_gyroscope = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventGyroscope"); g_event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope").MoveFrom();
g_event_debug_pad = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventDebugPad"); g_event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad").MoveFrom();
} }
void HIDShutdown() { void HIDShutdown() {

View file

@ -11,6 +11,7 @@
namespace Kernel { namespace Kernel {
class SharedMemory; class SharedMemory;
class Event;
} }
namespace Service { namespace Service {
@ -20,11 +21,11 @@ namespace HID {
extern Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem; extern Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem;
// Event handles // Event handles
extern Handle g_event_pad_or_touch_1; extern Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
extern Handle g_event_pad_or_touch_2; extern Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_2;
extern Handle g_event_accelerometer; extern Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
extern Handle g_event_gyroscope; extern Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
extern Handle g_event_debug_pad; extern Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
/** /**
* Structure of a Pad controller state. * Structure of a Pad controller state.

View file

@ -5,6 +5,7 @@
#include "common/log.h" #include "common/log.h"
#include "core/hle/hle.h" #include "core/hle/hle.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid.h"
#include "hid_user.h" #include "hid_user.h"
@ -49,11 +50,11 @@ void GetIPCHandles(Service::Interface* self) {
cmd_buff[1] = 0; // No error cmd_buff[1] = 0; // No error
// TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom(); cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom();
cmd_buff[4] = Service::HID::g_event_pad_or_touch_1; cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_1).MoveFrom();
cmd_buff[5] = Service::HID::g_event_pad_or_touch_2; cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_2).MoveFrom();
cmd_buff[6] = Service::HID::g_event_accelerometer; cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::g_event_accelerometer).MoveFrom();
cmd_buff[7] = Service::HID::g_event_gyroscope; cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::g_event_gyroscope).MoveFrom();
cmd_buff[8] = Service::HID::g_event_debug_pad; cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::g_event_debug_pad).MoveFrom();
} }
const Interface::FunctionInfo FunctionTable[] = { const Interface::FunctionInfo FunctionTable[] = {

View file

@ -11,7 +11,7 @@
namespace SRV { namespace SRV {
static Handle g_event_handle = 0; static Kernel::SharedPtr<Kernel::Event> event_handle;
static void Initialize(Service::Interface* self) { static void Initialize(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
@ -23,11 +23,11 @@ static void GetProcSemaphore(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(bunnei): Change to a semaphore once these have been implemented // TODO(bunnei): Change to a semaphore once these have been implemented
g_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "SRV:Event"); event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event").MoveFrom();
Kernel::ClearEvent(g_event_handle); event_handle->Clear();
cmd_buff[1] = 0; // No error cmd_buff[1] = 0; // No error
cmd_buff[3] = g_event_handle; cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom();
} }
static void GetServiceHandle(Service::Interface* self) { static void GetServiceHandle(Service::Interface* self) {

View file

@ -447,11 +447,17 @@ static Result QueryMemory(void* info, void* out, u32 addr) {
} }
/// Create an event /// Create an event
static Result CreateEvent(Handle* evt, u32 reset_type) { static Result CreateEvent(Handle* handle, u32 reset_type) {
*evt = Kernel::CreateEvent((ResetType)reset_type); auto evt_res = Kernel::Event::Create(static_cast<ResetType>(reset_type));
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", if (evt_res.Failed())
reset_type, *evt); return evt_res.Code().raw;
return 0; auto handle_res = Kernel::g_handle_table.Create(evt_res.MoveFrom());
if (handle_res.Failed())
return handle_res.Code().raw;
*handle = handle_res.MoveFrom();
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, *handle);
return RESULT_SUCCESS.raw;
} }
/// Duplicates a kernel handle /// Duplicates a kernel handle
@ -465,16 +471,28 @@ static Result DuplicateHandle(Handle* out, Handle handle) {
} }
/// Signals an event /// Signals an event
static Result SignalEvent(Handle evt) { static Result SignalEvent(Handle handle) {
LOG_TRACE(Kernel_SVC, "called event=0x%08X", evt); LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle);
if (evt == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw;
evt->Signal();
HLE::Reschedule(__func__); HLE::Reschedule(__func__);
return Kernel::SignalEvent(evt).raw; return RESULT_SUCCESS.raw;
} }
/// Clears an event /// Clears an event
static Result ClearEvent(Handle evt) { static Result ClearEvent(Handle handle) {
LOG_TRACE(Kernel_SVC, "called event=0x%08X", evt); LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
return Kernel::ClearEvent(evt).raw;
auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle);
if (evt == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw;
evt->Clear();
return RESULT_SUCCESS.raw;
} }
/// Creates a timer /// Creates a timer