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"); }
void * _sbrk_r(struct _reent *reent, ptrdiff_t incr) { if (sceKernelLockLwMutex((struct SceKernelLwMutexWork*)_newlib_sbrk_mutex, 1, 0) < 0) goto fail; if (!_newlib_heap_base || _newlib_heap_cur + incr >= _newlib_heap_end) { sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)_newlib_sbrk_mutex, 1); fail: reent->_errno = ENOMEM; return (void*)-1; } char *prev_heap_end = _newlib_heap_cur; _newlib_heap_cur += incr; sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)_newlib_sbrk_mutex, 1); return (void*) prev_heap_end; }
int lockThreadLwMutex(SceSize argc, void *argp) { void *mutex = *(void **)argp; dispatchCheckpoint("T sceKernelLockLwMutex: %08x", sceKernelLockLwMutex(mutex, 2, NULL)); dispatchCheckpoint("T sceKernelDelayThread: %08x", sceKernelDelayThread(3000)); dispatchCheckpoint("T sceKernelUnlockLwMutex: %08x", sceKernelUnlockLwMutex(mutex, 1)); return 0; }
static int lockFunc(SceSize argSize, void* argPointer) { SceUInt timeout = 1000; schedulingResult = sceKernelLockLwMutex(*(void**) argPointer, 1, &timeout); schedulingLogPos += sprintf(schedulingLog + schedulingLogPos, "L1 "); \ sceKernelDelayThread(1000); if (schedulingResult == 0) sceKernelUnlockLwMutex(*(void**) argPointer, 1); return 0; }
static int threadFunction(SceSize argSize, void* argPointer) { int num = argPointer ? *((int*)argPointer) : 0; printf("A%d\n", num); sceKernelLockLwMutexCB(&workarea, 1, NULL); printf("B%d\n", num); sceKernelUnlockLwMutex(&workarea, 1); return 0; }
static size_t psp_write_avail(void *data) { psp_audio_t* psp = (psp_audio_t*)data; #ifdef VITA size_t val; sceKernelLockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1, 0); val = AUDIO_BUFFER_SIZE - ((uint16_t) (psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK); sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1); return val; #else /* TODO */ return AUDIO_BUFFER_SIZE - ((uint16_t) (psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK); #endif }
static int audioMainLoop(SceSize args, void* argp) { psp_audio_t* psp = *((psp_audio_t**)argp); #ifdef VITA int port = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT, psp->rate, SCE_AUDIO_OUT_MODE_STEREO); #else sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2); #endif while (psp->running) { #ifdef VITA //sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT); sceKernelLockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1, 0); uint16_t readPos = psp->readPos; uint16_t readPos2 = psp->readPos; bool cond = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2); if (!cond) { readPos += AUDIO_OUT_COUNT; readPos &= AUDIO_BUFFER_SIZE_MASK; psp->readPos = readPos; } sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1); sceKernelSignalLwCond(&psp->cond); sceAudioOutOutput(port, cond ? (psp->zeroBuffer) : (psp->buffer + readPos2)); #else /* Get a non-volatile copy. */ uint16_t readPos = psp->readPos; bool cond = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2); sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer) : (psp->buffer + readPos)); if (!cond) { readPos += AUDIO_OUT_COUNT; readPos &= AUDIO_BUFFER_SIZE_MASK; psp->readPos = readPos; } #endif } #ifdef VITA sceAudioOutReleasePort(port); #else sceAudioSRCChRelease(); sceKernelExitThread(0); #endif return 0; }
static ssize_t psp_audio_write(void *data, const void *buf, size_t size) { psp_audio_t* psp = (psp_audio_t*)data; uint16_t sampleCount; uint16_t writePos = psp->writePos; sampleCount= size / sizeof(uint32_t); #ifdef VITA if (psp->nonblocking) { if (AUDIO_BUFFER_SIZE - ((uint16_t) (psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK) < size) return 0; } while (AUDIO_BUFFER_SIZE - ((uint16_t) (psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK) < size){ sceKernelWaitLwCond(&psp->cond, 0); } sceKernelLockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1, 0); if((writePos + sampleCount) > AUDIO_BUFFER_SIZE) { memcpy(psp->buffer + writePos, buf, (AUDIO_BUFFER_SIZE - writePos) * sizeof(uint32_t)); memcpy(psp->buffer, (uint32_t*) buf + (AUDIO_BUFFER_SIZE - writePos), (writePos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t)); } else memcpy(psp->buffer + writePos, buf, size); writePos += sampleCount; writePos &= AUDIO_BUFFER_SIZE_MASK; psp->writePos = writePos; sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1); return size; #else #if 0 if (psp->nonblocking) { /* TODO */ } #endif if((writePos + sampleCount) > AUDIO_BUFFER_SIZE) { memcpy(psp->buffer + writePos, buf, (AUDIO_BUFFER_SIZE - writePos) * sizeof(uint32_t)); memcpy(psp->buffer, (uint32_t*) buf + (AUDIO_BUFFER_SIZE - writePos), (writePos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t)); } else memcpy(psp->buffer + writePos, buf, size); writePos += sampleCount; writePos &= AUDIO_BUFFER_SIZE_MASK; psp->writePos = writePos; return sampleCount; #endif }