/* video worker thread */ void videoWorker ( void *arg ) { static s32 frames ; static time_t starttime ; dbgprintf ( "video thread starting" ) ; /* cast the void *arg to rsxData */ videoData* vdata = ( videoData* )arg ; /* signal main thread is ready */ sysCondSignal ( vdata->cond ) ; /* lock mutex */ sysMutexLock ( vdata->mutex, NO_TIMEOUT ) ; dbgprintf ( "video thread waiting" ) ; /* wait for main to be ready */ sysCondWait ( vdata->cond, NO_TIMEOUT ) ; /* release lock */ sysMutexUnlock ( vdata->mutex ) ; starttime = time( NULL ) ; dbgprintf ( "video thread entering loop" ) ; /* render frames until exit */ while ( *vdata->exitapp ) { /* render frame */ videoDrawFrame ( vdata ) ; frames++ ; } dbgprintf ( "video thread left loop" ) ; /* lock mutex */ sysMutexLock ( vdata->mutex, NO_TIMEOUT ) ; /* signal main before exit */ sysCondSignal ( vdata->cond ) ; /* release lock */ sysMutexUnlock ( vdata->mutex ) ; argprintf ( "frame rate: %g frames/sec", ( ( double ) frames ) / difftime ( time ( NULL ) , starttime ) ) ; dbgprintf ( "video thread exiting" ) ; /* exit thread */ sysThreadExit ( 0 ) ; }
/* pad worker thread */ void padWorker ( void *arg ) { dbgprintf ( "pad thread starting" ) ; /* cast the void *arg to rsxData */ padBtnData* pdata = ( padBtnData* )arg ; /* signal main thread is ready */ sysCondSignal ( pdata->cond ) ; /* lock mutex */ sysMutexLock ( pdata->mutex, NO_TIMEOUT ) ; dbgprintf ( "pad thread waiting" ) ; /* wait for main to be ready */ sysCondWait ( pdata->cond, NO_TIMEOUT ) ; /* release lock */ sysMutexUnlock ( pdata->mutex ) ; dbgprintf ( "pad thread entering loop" ) ; /* render frames until exit */ while ( *pdata->exitapp ) { /* check pads */ padCheckState ( pdata ) ; } dbgprintf ( "pad thread left loop" ) ; /* lock mutex */ sysMutexLock ( pdata->mutex, NO_TIMEOUT ) ; /* signal main before exit */ sysCondSignal ( pdata->cond ) ; /* release lock */ sysMutexUnlock ( pdata->mutex ) ; dbgprintf ( "pad thread exiting" ) ; /* exit thread */ sysThreadExit ( 0 ) ; }
void handle_interrupt(void *arg) { uint64_t stat; int ret; // Create a tag to handle class 2 interrupt, because PPU Interrupt MB is // handled by class 2. #ifdef USE_ISOSELF ret = sys_isoself_spu_get_int_stat(sa->id, SPU_INTR_CLASS_2, &stat); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_get_int_stat failed %d\n", ret)); sysInterruptThreadEOI(); } #else ret = sysSpuRawGetIntStat(sa->id, SPU_INTR_CLASS_2, &stat); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_raw_spu_get_int_stat failed %d\n", ret)); sysInterruptThreadEOI(); } #endif // If the caught class 2 interrupt includes mailbox interrupt, handle it. if ((stat & INTR_PPU_MB_MASK) == INTR_PPU_MB_MASK) { #ifdef USE_ISOSELF ret = sys_isoself_spu_read_puint_mb(sa->id, &sa->error_code); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_read_puint_mb failed %d\n", ret)); sysMutexUnlock(sa->mmio_mutex); sysInterruptThreadEOI(); } // Reset the PPU_INTR_MB interrupt status bit. ret = sys_isoself_spu_set_int_stat(sa->id, SPU_INTR_CLASS_2, INTR_PPU_MB_MASK); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_isoself_spu_set_int_stat failed %d\n", ret)); sysMutexUnlock(sa->mmio_mutex); sysInterruptThreadEOI(); } #else ret = sysSpuRawReadPuintMb(sa->id, &sa->error_code); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_raw_spu_read_puint_mb failed %d\n", ret)); sysMutexUnlock(sa->mmio_mutex); sysInterruptThreadEOI(); } // Reset the PPU_INTR_MB interrupt status bit. ret = sysSpuRawSetIntStat(sa->id, SPU_INTR_CLASS_2, INTR_PPU_MB_MASK); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sys_raw_spu_set_int_stat failed %d\n", ret)); sysMutexUnlock(sa->mmio_mutex); sysInterruptThreadEOI(); } #endif ret = sysMutexLock(sa->mmio_mutex, 0); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sysMutexLock() failed. (%d)\n", ret)); sysInterruptThreadEOI(); } ret = sysCondSignal(sa->mmio_cond); if (ret != 0) { sysMutexUnlock(sa->mmio_mutex); sysInterruptThreadEOI(); } ret = sysMutexUnlock(sa->mmio_mutex); if (ret != 0) { sysInterruptThreadEOI(); } } sysInterruptThreadEOI(); }