void checkLwMutex(int doDispatch) { SceLwMutexWorkarea workarea; dispatchCheckpoint("sceKernelCreateLwMutex: %08x", sceKernelCreateLwMutex(&workarea, "lwmutex", 0, 1, NULL)); dispatchCheckpoint("sceKernelUnlockLwMutex: %08x", sceKernelUnlockLwMutex(&workarea, 1)); dispatchCheckpoint("sceKernelLockLwMutex: %08x", sceKernelLockLwMutex(&workarea, 1, NULL)); dispatchCheckpoint("sceKernelLockLwMutex invalid: %08x", sceKernelLockLwMutex(&workarea, -1, NULL)); dispatchCheckpoint("sceKernelDeleteLwMutex: %08x", sceKernelDeleteLwMutex(&workarea)); dispatchCheckpoint("sceKernelCreateLwMutex: %08x", sceKernelCreateLwMutex(&workarea, "lwmutex", 0, 1, NULL)); startLockThreadLwMutex(&workarea); int state; if (doDispatch) { ++ignoreResched; state = sceKernelSuspendDispatchThread(); dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state); } SceUInt timeout = 300; dispatchCheckpoint("sceKernelLockLwMutex: %08x", sceKernelLockLwMutex(&workarea, 1, &timeout)); dispatchCheckpoint("sceKernelUnlockLwMutex: %08x", sceKernelUnlockLwMutex(&workarea, 1)); if (doDispatch) { dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state)); --ignoreResched; } endLockThreadLwMutex(&workarea); dispatchCheckpoint("sceKernelTryLockLwMutex: %08x", sceKernelTryLockLwMutex_600(&workarea, 1)); dispatchCheckpoint("sceKernelDeleteLwMutex: %08x", sceKernelDeleteLwMutex(&workarea)); }
void execPriorityTests(int attr, int deleteInstead) { SceUID threads[5]; int test[5] = {1, 2, 3, 4, 5}; int result; sceKernelCreateLwMutex(&workarea, "mutex1", attr, 1, NULL); int i; for (i = 0; i < 5; i++) { threads[i] = CREATE_PRIORITY_THREAD(threadFunction, 0x16 - i); sceKernelStartThread(threads[i], sizeof(int), (void*)&test[i]); } // This one intentionally is an invalid unlock. sceKernelDelayThread(1000); printf("Unlocking...\n"); result = sceKernelUnlockLwMutex(&workarea, 2); sceKernelDelayThread(5000); printf("Unlocked 2? %08X\n", result); if (!deleteInstead) { sceKernelDelayThread(1000); printf("Unlocking...\n"); result = sceKernelUnlockLwMutex(&workarea, 1); sceKernelDelayThread(5000); printf("Unlocked 1? %08X\n", result); } sceKernelDelayThread(1000); printf("Delete: %08X\n", sceKernelDeleteLwMutex(&workarea)); printf("\n\n"); }
int main(int argc, char **argv) { SceLwMutexWorkarea workarea, workarea1, workarea2; int result1, result2; // Crash. //CREATE_TEST("NULL workarea", NULL, "test", 0, 0, NULL); CREATE_TEST("NULL name", &workarea, NULL, 0, 0, NULL); CREATE_TEST("Blank name", &workarea, "", 0, 0, NULL); CREATE_TEST("Long name", &workarea, "1234567890123456789012345678901234567890123456789012345678901234", 0, 0, NULL); CREATE_TEST("Weird attr", &workarea, "create", 1, 0, NULL); CREATE_TEST("0x100 attr", &workarea, "create", 0x100, 0, NULL); CREATE_TEST("0x200 attr", &workarea, "create", 0x200, 0, NULL); CREATE_TEST("0x300 attr", &workarea, "create", 0x300, 0, NULL); CREATE_TEST("0x3FF attr", &workarea, "create", 0x3FF, 0, NULL); CREATE_TEST("0x400 attr", &workarea, "create", 0x400, 0, NULL); CREATE_TEST("Positive count", &workarea, "create", 0, 1, NULL); CREATE_TEST("Negative count", &workarea, "create", 0, -1, NULL); CREATE_TEST("Count = -5", &workarea, "create", 0, -5, NULL); CREATE_TEST("Count = 2", &workarea, "create", 0, 2, NULL); CREATE_TEST("Negative count (recursive)", &workarea, "create", 0x200, -1, NULL); CREATE_TEST("Count = -5 (recursive)", &workarea, "create", 0x200, -5, NULL); CREATE_TEST("Count = 2 (recursive)", &workarea, "create", 0x200, 2, NULL); CREATE_TEST("Medium count (recursive)", &workarea, "create", 0x200, 255, NULL); CREATE_TEST("Large count (recursive)", &workarea, "create", 0x200, 65537, NULL); result1 = sceKernelCreateLwMutex(&workarea1, "create", 0, 0, NULL); result2 = sceKernelCreateLwMutex(&workarea2, "create", 0, 0, NULL); if (result1 == 0 && result2 == 0) { printf("Two with same name: OK\n"); } else { printf("Two with same name: Failed (%X, %X)\n", result1, result2); } sceKernelDeleteLwMutex(&workarea1); sceKernelDeleteLwMutex(&workarea2); sceKernelCreateLwMutex(&workarea, "create1", 0, 0, NULL); CREATE_TEST("Two with same workarea", &workarea, "create2", 0, 0, NULL); // Leaks. BASIC_SCHED_TEST("NULL name", result = sceKernelCreateLwMutex(&workarea, NULL, 0, 0, NULL); );
static void *psp_audio_init(const char *device, unsigned rate, unsigned latency) { psp_audio_t *psp = (psp_audio_t*)calloc(1, sizeof(psp_audio_t)); if (!psp) return NULL; (void)device; (void)latency; /* Cache aligned, not necessary but helpful. */ psp->buffer = (uint32_t*) memalign(64, AUDIO_BUFFER_SIZE * sizeof(uint32_t)); memset(psp->buffer, 0, AUDIO_BUFFER_SIZE * sizeof(uint32_t)); psp->zeroBuffer = (uint32_t*) memalign(64, AUDIO_OUT_COUNT * sizeof(uint32_t)); memset(psp->zeroBuffer, 0, AUDIO_OUT_COUNT * sizeof(uint32_t)); psp->readPos = 0; psp->writePos = 0; psp->rate = rate; #if defined(VITA) sceKernelCreateLwMutex((struct SceKernelLwMutexWork*)&psp->lock, "audio_get_lock", 0, 0, 0); sceKernelCreateLwMutex((struct SceKernelLwMutexWork*)&psp->cond_lock, "audio_get_cond_lock", 0, 0, 0); sceKernelCreateLwCond(&psp->cond, "audio_get_cond", 0, &psp->cond_lock, 0); psp->thread = sceKernelCreateThread ("audioMainLoop", audioMainLoop, 0x10000100, 0x10000, 0, 0, NULL); #else psp->thread = sceKernelCreateThread ("audioMainLoop", audioMainLoop, 0x08, 0x10000, 0, NULL); #endif psp->nonblocking = false; psp->running = true; sceKernelStartThread(psp->thread, sizeof(psp_audio_t*), &psp); return psp; }
int main(int argc, char **argv) { SceLwMutexWorkarea workarea, workarea1, workarea2; sceKernelCreateLwMutex(&workarea, "delete", 0, 0, NULL); DELETE_TEST("Normal", &workarea); // Crash. //DELETE_TEST("NULL", 0); DELETE_TEST("Invalid", (void*) 0xDEADBEEF); DELETE_TEST("Deleted", &workarea); sceKernelCreateLwMutex(&workarea1, "delete", 0, 0, NULL); memcpy(&workarea2, &workarea1, sizeof(SceLwMutexWorkarea)); sceKernelDeleteLwMutex(&workarea1); DELETE_TEST("Copy", &workarea2); FAKE_LWMUTEX(workarea, 0, 0); DELETE_TEST("Fake", &workarea2); BASIC_SCHED_TEST("Delete other", result = sceKernelDeleteLwMutex(&workarea2); );
int main(int argc, char **argv) { LOCK_TEST("Lock 0 => 0", PSP_MUTEX_ATTR_FIFO, 0, 0); LOCK_TEST("Lock 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1); LOCK_TEST("Lock 0 => 2", PSP_MUTEX_ATTR_FIFO, 0, 2); LOCK_TEST("Lock 0 => -1", PSP_MUTEX_ATTR_FIFO, 0, -1); LOCK_TEST("Lock 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1); LOCK_TEST("Lock 0 => 2 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 2); LOCK_TEST("Lock 0 => -1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, -1); LOCK_TEST("Lock 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1); LOCK_TEST("Lock 1 => INT_MAX - 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, INT_MAX - 1); LOCK_TEST("Lock 1 => INT_MAX (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, INT_MAX); LOCK_TEST("Lock INT_MAX => INT_MAX (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, INT_MAX, INT_MAX); LOCK_TEST_TIMEOUT("Lock 0 => 0", PSP_MUTEX_ATTR_FIFO, 0, 0, 500); LOCK_TEST_TIMEOUT("Lock 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1, 500); LOCK_TEST_TIMEOUT("Lock 0 => 2", PSP_MUTEX_ATTR_FIFO, 0, 2, 500); LOCK_TEST_TIMEOUT("Lock 0 => -1", PSP_MUTEX_ATTR_FIFO, 0, -1, 500); LOCK_TEST_TIMEOUT("Lock 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1, 500); LOCK_TEST_TIMEOUT("Lock 0 => 2 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 2, 500); LOCK_TEST_TIMEOUT("Lock 0 => -1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, -1, 500); LOCK_TEST_TIMEOUT("Lock 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1, 500); LOCK_TEST_TIMEOUT("Zero timeout", PSP_MUTEX_ATTR_FIFO, 0, 1, 0); SceUID lockThread = CREATE_SIMPLE_THREAD(lockFunc); LOCK_TEST_TIMEOUT_THREAD("Locked 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1, 500); LOCK_TEST_TIMEOUT_THREAD("Locked 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1, 500); LOCK_TEST_TIMEOUT_THREAD("Locked 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1, 500); LOCK_TEST_TIMEOUT_THREAD("Locked 0 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 1, 500); LOCK_TEST_TIMEOUT_THREAD("Locked zero timeout", PSP_MUTEX_ATTR_FIFO, 0, 1, 0); SceUID deleteThread = CREATE_SIMPLE_THREAD(deleteMeFunc); SceLwMutexWorkarea workarea; void *workareaPtr = &workarea; sceKernelCreateLwMutex(&workarea, "lock", 0, 1, NULL); sceKernelStartThread(deleteThread, sizeof(void*), &workareaPtr); sceKernelDelayThread(500); sceKernelDeleteLwMutex(&workarea); // Crash. //LOCK_TEST_SIMPLE("NULL => 0", 0, 0); //LOCK_TEST_SIMPLE("NULL => 1", 0, 1); //LOCK_TEST_SIMPLE("Invalid => 1", (void*) 0xDEADBEEF, 1); LOCK_TEST_SIMPLE("Deleted => 1", &workarea, 1); BASIC_SCHED_TEST("Zero", result = sceKernelLockLwMutex(&workarea2, 0, NULL); );
void _init_vita_heap(void) { int _newlib_vm_size = 0; if (&_newlib_vm_size_user != NULL) { _newlib_vm_size = _newlib_vm_size_user; _newlib_vm_memblock = sceKernelAllocMemBlockForVM("code", _newlib_vm_size_user); if (_newlib_vm_memblock < 0){ //sceClibPrintf("sceKernelAllocMemBlockForVM failed\n"); goto failure; } }else{ _newlib_vm_memblock = 0; } // Create a mutex to use inside _sbrk_r if (sceKernelCreateLwMutex((struct SceKernelLwMutexWork*)_newlib_sbrk_mutex, "sbrk mutex", 0, 0, 0) < 0) { goto failure; } _newlib_heap_size = _newlib_heap_size_user; _newlib_heap_size -= _newlib_vm_size; _newlib_heap_memblock = sceKernelAllocMemBlock("Newlib heap", 0x0c20d060, _newlib_heap_size, 0); if (_newlib_heap_memblock < 0) { goto failure; } if (sceKernelGetMemBlockBase(_newlib_heap_memblock, (void**)&_newlib_heap_base) < 0) { goto failure; } _newlib_heap_end = _newlib_heap_base + _newlib_heap_size; _newlib_heap_cur = _newlib_heap_base; return; failure: _newlib_vm_memblock = 0; _newlib_heap_memblock = 0; _newlib_heap_base = 0; _newlib_heap_cur = 0; }
int main(int argc, char **argv) { LOCK_TEST("Lock 0 => 0", PSP_MUTEX_ATTR_FIFO, 0, 0); LOCK_TEST("Lock 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1); LOCK_TEST("Lock 0 => 2", PSP_MUTEX_ATTR_FIFO, 0, 2); LOCK_TEST("Lock 0 => -1", PSP_MUTEX_ATTR_FIFO, 0, -1); LOCK_TEST("Lock 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1); LOCK_TEST("Lock 0 => 2 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 2); LOCK_TEST("Lock 0 => -1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, -1); LOCK_TEST("Lock 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1); LOCK_TEST("Lock 1 => INT_MAX - 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, INT_MAX - 1); LOCK_TEST("Lock 1 => INT_MAX (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, INT_MAX); LOCK_TEST("Lock INT_MAX => INT_MAX (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, INT_MAX, INT_MAX); flushschedf(); SceUID lockThread = CREATE_SIMPLE_THREAD(lockFunc); LOCK_TEST_THREAD("Locked 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1); LOCK_TEST_THREAD("Locked 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1); LOCK_TEST_THREAD("Locked 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1); LOCK_TEST_THREAD("Locked 0 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 1); // Probably we can't manage to delete it at the same time. SceUID deleteThread = CREATE_SIMPLE_THREAD(deleteMeFunc); SceLwMutexWorkarea workarea; sceKernelCreateLwMutex(&workarea, "lock", 0, 1, NULL); void *workareaPtr = &workarea; sceKernelStartThread(deleteThread, sizeof(int), &workareaPtr); sceKernelDeleteLwMutex(&workarea); flushschedf(); // Crashes. //LOCK_TEST_SIMPLE("NULL => 0", 0, 0); //LOCK_TEST_SIMPLE("NULL => 1", 0, 1); //LOCK_TEST_SIMPLE("Invalid => 1", (void*) 0xDEADBEEF, 1); LOCK_TEST_SIMPLE("Deleted => 1", &workarea, 1); BASIC_SCHED_TEST("Zero", result = sceKernelTryLockLwMutex(&workarea2, 0); );