Merge branch 'master' into great-refactor

This commit is contained in:
fincs 2015-09-15 11:47:55 +02:00
commit 04ed53659a

View File

@ -81,6 +81,50 @@ void gspWaitForEvent(GSP_Event id, bool nextEvent)
svcClearEvent(gspEvents[id]); svcClearEvent(gspEvents[id]);
} }
static int popInterrupt()
{
int curEvt;
u32 strexFailed;
do {
union {
struct {
u8 cur;
u8 count;
u8 err;
u8 unused;
};
u32 as_u32;
} header;
u32* gsp_header_ptr = (u32*)(gspEventData + 0);
// Do a load on all header fields as an atomic unit
__asm__ volatile (
"ldrex %[result], %[addr]" :
[result]"=r"(header.as_u32) :
[addr]"Q"(*gsp_header_ptr));
if (__builtin_expect(header.count == 0, 0)) {
__asm__ volatile ("clrex");
return -1;
}
curEvt = gspEventData[0xC + header.cur];
header.cur += 1;
if (header.cur >= 0x34) header.cur -= 0x34;
header.count -= 1;
header.err = 0; // Should this really be set?
__asm__ volatile (
"strex %[result], %[val], %[addr]" :
[result]"=&r"(strexFailed), [addr]"=Q"(*gsp_header_ptr) :
[val]"r"(header.as_u32));
} while (__builtin_expect(strexFailed, 0));
return curEvt;
}
void gspEventThreadMain(void *arg) void gspEventThreadMain(void *arg)
{ {
while (gspRunEvents) while (gspRunEvents)
@ -88,24 +132,18 @@ void gspEventThreadMain(void *arg)
svcWaitSynchronization(gspEvent, U64_MAX); svcWaitSynchronization(gspEvent, U64_MAX);
svcClearEvent(gspEvent); svcClearEvent(gspEvent);
int count = gspEventData[1]; while (true)
int cur = gspEventData[0];
int last = cur + count;
while (last >= 0x34) last -= 0x34;
int i;
for (i = 0; i < count; i ++)
{ {
int curEvt = gspEventData[0xC + cur]; int curEvt = popInterrupt();
cur ++;
if (cur >= 0x34) cur -= 0x34;
if (curEvt >= GSPEVENT_MAX) continue;
svcSignalEvent(gspEvents[curEvt]);
gspEventCounts[curEvt]++;
}
gspEventData[0] = last; if (curEvt == -1)
gspEventData[1] -= count; break;
gspEventData[2] = 0;
if (curEvt < GSPEVENT_MAX) {
svcSignalEvent(gspEvents[curEvt]);
gspEventCounts[curEvt]++;
}
}
} }
svcExitThread(); svcExitThread();
} }