]> Chaos Git - corbenik/ctrulib.git/commitdiff
Take advantage of light events in NDSP and GSPGPU code
authorfincs <fincs.alt1@gmail.com>
Tue, 5 Jul 2016 20:38:44 +0000 (22:38 +0200)
committerfincs <fincs.alt1@gmail.com>
Tue, 5 Jul 2016 20:38:44 +0000 (22:38 +0200)
libctru/source/ndsp/ndsp.c
libctru/source/services/gspgpu.c

index 70c914c7c47f3519869920343ce257290e411441..00b3cdcf094d1d05f067603d628b8793593094d9 100644 (file)
@@ -9,7 +9,7 @@
 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;
@@ -19,7 +19,8 @@ static bool componentFree;
 
 static aptHookCookie aptCookie;
 
-static Handle irqEvent, dspSem, sleepEvent;
+static Handle irqEvent, dspSem;
+static LightEvent sleepEvent;
 static LightLock ndspMutex;
 
 static u8 dspVar5Backup[0x1080];
@@ -305,7 +306,11 @@ static void ndspAptHook(APT_HookType hook, void* param)
                case APTHOOK_ONWAKEUP:
                        bSleeping = false;
                        ndspInitialize(true);
-                       svcSignalEvent(sleepEvent);
+                       if (bActuallySleeping)
+                       {
+                               bActuallySleeping = false;
+                               LightEvent_Signal(&sleepEvent);
+                       }
                        break;
 
                case APTHOOK_ONSUSPEND:
@@ -323,8 +328,8 @@ static void ndspSync(void)
 {
        if (bSleeping)
        {
-               svcWaitSynchronization(sleepEvent, U64_MAX);
-               svcClearEvent(sleepEvent);
+               bActuallySleeping = true;
+               LightEvent_Wait(&sleepEvent);
        }
 
        ndspWaitForIrq();
@@ -455,7 +460,7 @@ Result ndspInit(void)
 
        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;
        }
 
@@ -479,17 +484,14 @@ Result ndspInit(void)
        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:
@@ -509,10 +511,12 @@ void ndspExit(void)
        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);
index 46278dc3883da9e5628f9f13683180efbd1c04d3..af602d89d5e34cd6a8475957eea2c87883368eaf 100644 (file)
 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;
@@ -53,20 +56,10 @@ void gspSetEventCallback(GSPGPU_Event id, ThreadFunc cb, void* data, bool oneSho
 
 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;
@@ -82,11 +75,6 @@ void gspExitEventHandler(void)
        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)
@@ -94,19 +82,30 @@ 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()
@@ -168,7 +167,11 @@ void gspEventThreadMain(void *arg)
                                                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]++;
                        }
                }