int exchange_data(int func_nr , uint8_t *write_buffer, int write_count , uint8_t *read_buffer, int read_count , uint32_t timeout) { int ret; if (sa == NULL) { return 0; } sa->error_code = 0xfffffff1; if (write_count > 0) { memcpy(sa->buffer, write_buffer, min(write_count, DMA_BUFFER_SIZE)); } ret = sysMutexLock(sa->mmio_mutex, 0); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("sysMutexLock() failed. (%d)\n", ret)); return ret; } sysSpuRawWriteProblemStorage(sa->id, SPU_In_MBox, func_nr); sysSpuRawWriteProblemStorage(sa->id, SPU_In_MBox, read_count); ret = sysCondWait(sa->mmio_cond, timeout); if (ret != 0) { LOG(lm_main, LOG_ERROR, ("exchange_data: [sysCondWait timeout]\n")); sysMutexUnlock(sa->mmio_mutex); return ret; } ret = sysMutexUnlock(sa->mmio_mutex); if (ret != 0) { return ret; } if (sa->error_code == 0xfffffff1) { return -1; } if (read_buffer != NULL && read_count > 0) { memcpy(read_buffer, sa->buffer, min(read_count, DMA_BUFFER_SIZE)); } return sa->error_code; }
/* 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 ) ; }
void PrintInfo( bool verbose ) { sysMutexLock( rsxMutex, 0 ); printf("-------------------------------------------------------------------------\n"); printf("RsxMem::PrintInfo\n"); printf("memSize: %08x (%.2fMiB) memStart: %p numPtrs: %u\n", memSize, (float)((float)memSize/(float)1048576.0f ), memStart, (u32)ptrs.size() ); u32 used = 0; u32 free = 0; u32 i = 0; if( verbose ) printf("[idx] start -> end ( size ) addr\n" ); vector<MemItr>::iterator ptr = ptrs.begin(); while( ptr < ptrs.end() ) { u32 bytes = ( (*ptr).end - (*ptr).start ); if( verbose ) { printf("[ %u ] %08x -> %08x ( %08x ) %p\n",\ i, (*ptr).start, (*ptr).end, bytes, ( ((u8*)memStart) + (*ptr).start ) ); } used += bytes; ++ptr; ++i; } free = memSize - used; printf("used: %08x (%.2fMiB) free: %08x (%.2fMiB)\n", used, (float)((float)used/(float)1048576.0f ), free, (float)((float)free/(float)1048576.0f ) ); printf("-------------------------------------------------------------------------\n"); sysMutexUnlock( rsxMutex ); }
void thread_exit() { sysMutexLock(thread_mutex, TIMEOUT_MUTEX); THREADS_RUNNING--; sysMutexUnlock(thread_mutex); 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 Free( u8 *p ) { if( !Lock() )//better to leak memory than to have the app freeze in a thread deadlock { printf("RsxMem failed to aquire mutex. memory leaking\n"); return; } //printf("RsxMem::Free( %p )\n", p ); u32 offset = p - ((u8*)memStart); //printf("looking for offset: %08x\n", offset ); vector<MemItr>::iterator ptr = ptrs.begin(); while( ptr < ptrs.end() ) { if( (*ptr).start == offset ) { ptrs.erase( ptr ); sysMutexUnlock( rsxMutex ); return; } ++ptr; } printf("RsxMem::Free( %p ) :no entry matched that pointer\n", p ); UnLock(); }
static void UnLock() { sysMutexUnlock( rsxMutex ); }
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(); }
pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle) { sysMutexUnlock(handle); return PTE_OS_OK; }