| 362 | } |
| 363 | |
| 364 | void gspEventThreadMain(void *arg) |
| 365 | { |
| 366 | while (gspRunEvents) |
| 367 | { |
| 368 | svcWaitSynchronization(gspEvent, U64_MAX); |
| 369 | svcClearEvent(gspEvent); |
| 370 | |
| 371 | if (!gspRunEvents) |
| 372 | break; |
| 373 | |
| 374 | while (true) |
| 375 | { |
| 376 | int curEvt = popInterrupt(); |
| 377 | |
| 378 | if (curEvt == -1) |
| 379 | break; |
| 380 | |
| 381 | if (curEvt < GSPGPU_EVENT_MAX) |
| 382 | { |
| 383 | gxCmdQueueInterrupt((GSPGPU_Event)curEvt); |
| 384 | if (gspEventCb[curEvt]) |
| 385 | { |
| 386 | ThreadFunc func = gspEventCb[curEvt]; |
| 387 | if (gspEventCbOneShot[curEvt]) |
| 388 | gspEventCb[curEvt] = NULL; |
| 389 | func(gspEventCbData[curEvt]); |
| 390 | } |
| 391 | LightEvent_Signal(&gspEvents[curEvt]); |
| 392 | do |
| 393 | __ldrex(&gspLastEvent); |
| 394 | while (__strex(&gspLastEvent, curEvt)); |
| 395 | syncArbitrateAddress(&gspLastEvent, ARBITRATION_SIGNAL, 1); |
| 396 | } |
| 397 | } |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | //essentially : get commandIndex and totalCommands, calculate offset of new command, copy command and update totalCommands |
| 402 | //use LDREX/STREX because this data may also be accessed by the GSP module and we don't want to break stuff |
nothing calls this directly
no test coverage detected