/* 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 ) ; }
static bool Lock() { if( sysMutexLock( rsxMutex, 1000 * 1000 ) ) return false; return true; }
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 ) ; }
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; }
pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs) { pte_osResult result; u64 timeoutUsecs = timeoutMsecs*1000; s32 status = sysMutexLock(handle, timeoutUsecs); if (status != 0) { // Assume that any error from sysMutexLock was due to a timeout result = PTE_OS_TIMEOUT; } else { result = PTE_OS_OK; } return result; }
u8 *Alloc( u32 bytes, u32* off ) { if( !Lock() ) return NULL; sysMutexLock( rsxMutex, 0 ); //align bytes = RU( bytes, 4 ); //printf("ptrs.size(): %i\n", (int)ptrs.size() ); //find the first available chunk of memory big enough u32 offset = 0; u32 i = 0; vector<MemItr>::iterator ptr = ptrs.begin(); while( ptr < ptrs.end() ) { //if there is another chunk of allocated memory after this one, check the space between them if( i + 1 < ptrs.size() ) { if( ( ptrs.at( i + 1 ).start - (*ptr).end ) >= bytes ) { //printf("%08x - %08x >= %08x 2\n", ptrs.at( i + 1 ).start, (*ptr).end, bytes ); offset = ptrs.at( i ).end; i++; break; } } //if this is the last texture else if( i == ptrs.size() - 1 ) { if( ( memSize - (*ptr).end ) >= bytes ) { //printf("%08x - %08x >= %08x 1\n", memSize, (*ptr).end, bytes ); offset = (*ptr).end; i++; } else { printf("RsxMem::Alloc() :didnt find enough free space for %08x\n", bytes ); UnLock(); return NULL; } break; } ++ptr; ++i; } MemItr newPtr; newPtr.start = offset; newPtr.end = offset + bytes; ptrs.insert( ptrs.begin() + i, newPtr ); //printf("inserting new chunk in list @ %u\n", i ); if( off ) { *off = tiny3d_TextureOffset( (u8*)memStart + offset ); } u8 *ret = ((u8*)memStart) + offset; UnLock(); return ret; }
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_osMutexLock(pte_osMutexHandle handle) { sysMutexLock(handle, 0); return PTE_OS_OK; }