u16 ndspFrameId, ndspBufferCurId, ndspBufferId;
void* ndspVars[16][2];
-static bool bComponentLoaded = false, bDspReady = false, bSleeping = false, bNeedsSync = false;
+static bool bComponentLoaded = false, bDspReady = false, bSleeping = false, bActuallySleeping = false, bNeedsSync = false;
static u32 droppedFrames, frameCount;
static const void* componentBin;
static aptHookCookie aptCookie;
-static Handle irqEvent, dspSem, sleepEvent;
+static Handle irqEvent, dspSem;
+static LightEvent sleepEvent;
static LightLock ndspMutex;
static u8 dspVar5Backup[0x1080];
case APTHOOK_ONWAKEUP:
bSleeping = false;
ndspInitialize(true);
- svcSignalEvent(sleepEvent);
+ if (bActuallySleeping)
+ {
+ bActuallySleeping = false;
+ LightEvent_Signal(&sleepEvent);
+ }
break;
case APTHOOK_ONSUSPEND:
{
if (bSleeping)
{
- svcWaitSynchronization(sleepEvent, U64_MAX);
- svcClearEvent(sleepEvent);
+ bActuallySleeping = true;
+ LightEvent_Wait(&sleepEvent);
}
ndspWaitForIrq();
if (!componentBin && !ndspFindAndLoadComponent())
{
- rc = MAKERESULT(RL_PERMANENT, RS_NOTFOUND, 41, RD_NOT_FOUND);
+ rc = MAKERESULT(RL_PERMANENT, RS_NOTFOUND, RM_DSP, RD_NOT_FOUND);
goto _fail0;
}
rc = ndspInitialize(false);
if (R_FAILED(rc)) goto _fail1;
- rc = svcCreateEvent(&sleepEvent, RESET_STICKY);
- if (R_FAILED(rc)) goto _fail2;
+ LightEvent_Init(&sleepEvent, RESET_ONESHOT);
ndspThread = threadCreate(ndspThreadMain, 0x0, NDSP_THREAD_STACK_SIZE, 0x18, -2, true);
- if (!ndspThread) goto _fail3;
+ if (!ndspThread) goto _fail2;
aptHook(&aptCookie, ndspAptHook, NULL);
return 0;
-_fail3:
- svcCloseHandle(sleepEvent);
_fail2:
ndspFinalize(false);
_fail1:
if (AtomicDecrement(&ndspRefCount)) return;
if (!bDspReady) return;
ndspThreadRun = false;
- if (bSleeping)
- svcSignalEvent(sleepEvent);
+ if (bActuallySleeping)
+ {
+ bActuallySleeping = false;
+ LightEvent_Signal(&sleepEvent);
+ }
threadJoin(ndspThread, U64_MAX);
- svcCloseHandle(sleepEvent);
aptUnhook(&aptCookie);
if (!bSleeping)
ndspFinalize(false);
Handle gspGpuHandle;
static int gspRefCount;
-Handle gspEvents[GSPGPU_EVENT_MAX];
-vu32 gspEventCounts[GSPGPU_EVENT_MAX];
-ThreadFunc gspEventCb[GSPGPU_EVENT_MAX];
-void* gspEventCbData[GSPGPU_EVENT_MAX];
-bool gspEventCbOneShot[GSPGPU_EVENT_MAX];
-volatile bool gspRunEvents;
-Thread gspEventThread;
+static s32 gspLastEvent = -1;
+static LightEvent gspEvents[GSPGPU_EVENT_MAX];
+static vu32 gspEventCounts[GSPGPU_EVENT_MAX];
+static ThreadFunc gspEventCb[GSPGPU_EVENT_MAX];
+static void* gspEventCbData[GSPGPU_EVENT_MAX];
+static bool gspEventCbOneShot[GSPGPU_EVENT_MAX];
+static volatile bool gspRunEvents;
+static Thread gspEventThread;
static Handle gspEvent;
static vu8* gspEventData;
static void gspEventThreadMain(void *arg);
+Handle __sync_get_arbiter(void);
+
Result gspInit(void)
{
Result res=0;
Result gspInitEventHandler(Handle _gspEvent, vu8* _gspSharedMem, u8 gspThreadId)
{
- // Create events
+ // Initialize events
int i;
for (i = 0; i < GSPGPU_EVENT_MAX; i ++)
- {
- Result rc = svcCreateEvent(&gspEvents[i], RESET_STICKY);
- if (rc != 0)
- {
- // Destroy already created events due to failure
- int j;
- for (j = 0; j < i; j ++)
- svcCloseHandle(gspEvents[j]);
- return rc;
- }
- }
+ LightEvent_Init(&gspEvents[i], RESET_STICKY);
// Start event thread
gspEvent = _gspEvent;
gspRunEvents = false;
svcSignalEvent(gspEvent);
threadJoin(gspEventThread, U64_MAX);
-
- // Free events
- int i;
- for (i = 0; i < GSPGPU_EVENT_MAX; i ++)
- svcCloseHandle(gspEvents[i]);
}
void gspWaitForEvent(GSPGPU_Event id, bool nextEvent)
if(id>= GSPGPU_EVENT_MAX)return;
if (nextEvent)
- svcClearEvent(gspEvents[id]);
- svcWaitSynchronization(gspEvents[id], U64_MAX);
+ LightEvent_Clear(&gspEvents[id]);
+ LightEvent_Wait(&gspEvents[id]);
if (!nextEvent)
- svcClearEvent(gspEvents[id]);
+ LightEvent_Clear(&gspEvents[id]);
}
GSPGPU_Event gspWaitForAnyEvent(void)
{
- s32 which = 0;
- Result rc = svcWaitSynchronizationN(&which, gspEvents, GSPGPU_EVENT_MAX, false, U64_MAX);
- if (R_FAILED(rc)) return -1;
- svcClearEvent(gspEvents[which]);
- return which;
+ s32 x;
+ do
+ {
+ do
+ {
+ x = __ldrex(&gspLastEvent);
+ if (x < 0)
+ {
+ __clrex();
+ break;
+ }
+ } while (__strex(&gspLastEvent, -1));
+ if (x < 0)
+ svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
+ } while (x < 0);
+ return (GSPGPU_Event)x;
}
static int popInterrupt()
gspEventCb[curEvt] = NULL;
func(gspEventCbData[curEvt]);
}
- svcSignalEvent(gspEvents[curEvt]);
+ LightEvent_Signal(&gspEvents[curEvt]);
+ do
+ __ldrex(&gspLastEvent);
+ while (__strex(&gspLastEvent, curEvt));
+ svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_SIGNAL, 1, 0);
gspEventCounts[curEvt]++;
}
}