mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-07 00:29:23 +02:00
kernel/event.h: several fixes, including autoclear support
This commit is contained in:
parent
f2f59c75c0
commit
88e9d3bb83
@ -7,13 +7,13 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
Handle revent;
|
Handle revent;
|
||||||
Handle wevent;
|
Handle wevent;
|
||||||
|
bool autoclear;
|
||||||
} Event;
|
} Event;
|
||||||
|
|
||||||
Result eventCreate(Event* t);
|
Result eventCreate(Event* t, bool autoclear);
|
||||||
void eventLoadRemote(Event* t, Handle handle);
|
void eventLoadRemote(Event* t, Handle handle, bool autoclear);
|
||||||
void eventClose(Event* t);
|
void eventClose(Event* t);
|
||||||
|
|
||||||
Result eventWait(Event* t, u64 timeout);
|
Result eventWait(Event* t, u64 timeout);
|
||||||
Result eventFire(Event* t);
|
Result eventFire(Event* t);
|
||||||
Result eventClear(Event* t);
|
Result eventClear(Event* t);
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
// Copyright 2018 plutoo
|
// Copyright 2018 plutoo
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
|
#include "arm/counter.h"
|
||||||
#include "kernel/svc.h"
|
#include "kernel/svc.h"
|
||||||
#include "kernel/event.h"
|
#include "kernel/event.h"
|
||||||
|
|
||||||
Result eventCreate(Event* t)
|
Result eventCreate(Event* t, bool autoclear)
|
||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
|
|
||||||
rc = svcCreateEvent(&t->revent, &t->wevent);
|
rc = svcCreateEvent(&t->revent, &t->wevent);
|
||||||
|
t->autoclear = autoclear;
|
||||||
|
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
t->revent = INVALID_HANDLE;
|
t->revent = INVALID_HANDLE;
|
||||||
@ -18,24 +20,49 @@ Result eventCreate(Event* t)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventLoadRemote(Event* t, Handle handle) {
|
void eventLoadRemote(Event* t, Handle handle, bool autoclear)
|
||||||
|
{
|
||||||
t->revent = handle;
|
t->revent = handle;
|
||||||
|
t->wevent = INVALID_HANDLE;
|
||||||
|
t->autoclear = autoclear;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result eventWait(Event* t, u64 timeout)
|
Result eventWait(Event* t, u64 timeout)
|
||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
|
u64 deadline = 0;
|
||||||
|
|
||||||
rc = svcWaitSynchronizationSingle(t->revent, timeout);
|
if (t->revent == INVALID_HANDLE)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (timeout != U64_MAX)
|
||||||
rc = svcResetSignal(t->revent);
|
deadline = armGetSystemTick() + timeout * 12 / 625; // timeout: ns->ticks
|
||||||
}
|
|
||||||
|
do {
|
||||||
|
do {
|
||||||
|
s64 this_timeout = -1;
|
||||||
|
if (deadline) {
|
||||||
|
this_timeout = deadline - armGetSystemTick();
|
||||||
|
this_timeout = (this_timeout >= 0 ? this_timeout : 0) * 625 / 12; // ticks->ns
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = svcWaitSynchronizationSingle(t->revent, this_timeout);
|
||||||
|
if (deadline && (rc & 0x3FFFFF) == 0xEA01)
|
||||||
|
return rc; // timeout.
|
||||||
|
} while (R_FAILED(rc));
|
||||||
|
|
||||||
|
if (t->autoclear)
|
||||||
|
rc = svcResetSignal(t->revent);
|
||||||
|
} while ((rc & 0x3FFFFF) == 0xFA01);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result eventFire(Event* t) {
|
Result eventFire(Event* t)
|
||||||
|
{
|
||||||
|
if (t->wevent == INVALID_HANDLE)
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
return svcSignalEvent(t->wevent);
|
return svcSignalEvent(t->wevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +72,7 @@ Result eventClear(Event* t)
|
|||||||
return svcClearEvent(t->wevent);
|
return svcClearEvent(t->wevent);
|
||||||
|
|
||||||
if (t->revent != INVALID_HANDLE)
|
if (t->revent != INVALID_HANDLE)
|
||||||
return svcClearEvent(t->revent);
|
return svcResetSignal(t->revent);
|
||||||
|
|
||||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ Result nvErrorNotifierCreate(NvErrorNotifier* t, NvGpu* parent)
|
|||||||
parent->gpu_channel.fd, NvEventId_Gpu_ErrorNotifier, &handle);
|
parent->gpu_channel.fd, NvEventId_Gpu_ErrorNotifier, &handle);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
eventLoadRemote(&t->event, handle);
|
eventLoadRemote(&t->event, handle, true);
|
||||||
rc = nvioctlChannel_SetErrorNotifier(parent->gpu_channel.fd, 1);
|
rc = nvioctlChannel_SetErrorNotifier(parent->gpu_channel.fd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,6 @@ void audrenExit(void)
|
|||||||
void audrenWaitFrame(void)
|
void audrenWaitFrame(void)
|
||||||
{
|
{
|
||||||
eventWait(&g_audrenEvent, U64_MAX);
|
eventWait(&g_audrenEvent, U64_MAX);
|
||||||
eventClear(&g_audrenEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result _audrenOpenAudioRenderer(Service* audren_mgr, const AudioRendererParameter* param, u64 aruid)
|
Result _audrenOpenAudioRenderer(Service* audren_mgr, const AudioRendererParameter* param, u64 aruid)
|
||||||
@ -373,7 +372,7 @@ Result _audrenQuerySystemEvent(void)
|
|||||||
rc = resp->result;
|
rc = resp->result;
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc))
|
if (R_SUCCEEDED(rc))
|
||||||
eventLoadRemote(&g_audrenEvent, r.Handles[0]);
|
eventLoadRemote(&g_audrenEvent, r.Handles[0], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
Loading…
Reference in New Issue
Block a user