void testCheckStackLayout(const char *title, int argSize, u32 attr) { char argLengthTemp[0x1000]; memset(argLengthTemp, 0xAB, sizeof(argLengthTemp)); // First create the thread to wipe the stack area, that way we can see what it'd look like clean. SceUID stackCheckThread = sceKernelCreateThread("stackCheck", &stackCheckFunc, 0x10, 0x1000, attr, NULL); stackCheckInfo.size = sizeof(stackCheckInfo); sceKernelReferThreadStatus(stackCheckThread, &stackCheckInfo); sceKernelTerminateDeleteThread(stackCheckThread); memset(stackCheckInfo.stack, 0xCC, stackCheckInfo.stackSize); stackCheckName = title; stackCheckThread = sceKernelCreateThread("stackCheck", &stackCheckFunc, 0x10, 0x1000, attr, NULL); sceKernelStartThread(stackCheckThread, argSize, argLengthTemp); sceKernelWaitThreadEnd(stackCheckThread, NULL); u32 *stack = (u32 *) stackCheckInfo.stack; stack[1] = 0xFF1337FF; sceKernelTerminateDeleteThread(stackCheckThread); if (stack[1] != 0xFF1337FF) { schedf(" %s: WARNING: stack cleared to something after delete: %08x.\n", stackCheckName, stack[1]); } checkpoint("%s", title); }
/** * stop_channel: Stop playback from the given playback buffer. * * [Parameters] * buffer_desc: Playback buffer descriptor * [Return value] * None */ void stop_channel(PSPSoundBufferDesc *buffer_desc) { if (!buffer_desc) { DMSG("buffer_desc == NULL"); return; } if (!buffer_desc->started) { DMSG("Buffer has not been started!"); return; } /* Signal the thread to stop, then wait for it (if we try to stop the * thread in the middle of an audio write, we won't be able to free * the hardware channel) */ buffer_desc->stop = 1; int tries; for (tries = (1000 * (2*BUFFER_SIZE)/PLAYBACK_RATE); tries > 0; tries--) { if (sys_delete_thread_if_stopped(buffer_desc->thread, NULL)) { break; } sceKernelDelayThread(1000); // Wait for 1ms before trying again } if (!tries) { /* The thread didn't stop on its own, so terminate it with * extreme prejudice */ sceKernelTerminateDeleteThread(buffer_desc->thread); sceAudioChRelease(buffer_desc->channel); memset(buffer_desc, 0, sizeof(*buffer_desc)); } }
void testTryAllocThread(const char *title, u32 attr, u32 requestBytes, u32 initialBytes) { schedf("%s: ", title); SceUID vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, attr, 0x100, NULL); // This way we have some allocated + free. void *data; sceKernelAllocateVpl(vpl, initialBytes, &data, NULL); SceUID allocThread = sceKernelCreateThread("allocThread", &allocFunc, 0x12, 0x1000, 0, NULL); sceKernelStartThread(allocThread, sizeof(SceUID), &vpl); sceKernelDelayThread(400); int result = sceKernelTryAllocateVpl(vpl, requestBytes, &data); schedf("L2 "); sceKernelDelayThread(600); sceKernelDeleteVpl(vpl); sceKernelWaitThreadEnd(allocThread, NULL); sceKernelTerminateDeleteThread(allocThread); if (result == 0) { schedf("OK (thread=%08X)\n", schedulingResult); } else { schedf("Failed (thread=%08X, main=%08X)\n", schedulingResult, result); } }
int music_free(void) { int ret; unsigned to = 500000; cache_on(false); music_lock(); ret = -1; while (ret != 0) { ret = music_stop(); if (ret != 0) sceKernelDelayThread(100000); } g_list.is_list_playing = 0; g_thread_actived = 0; music_unlock(); if (sceKernelWaitThreadEnd(g_music_thread, &to) != 0) { sceKernelTerminateDeleteThread(g_music_thread); } else { sceKernelDeleteThread(g_music_thread); } xr_lock_destroy(&music_l); return 0; }
FunctionManager::~FunctionManager() { sceKernelTerminateDeleteThread(thid); for (unsigned int i=0; i<size(); i++) { delete functions[i]; } }
triVoid triAt3Free() { triAt3Stop(); AT3_Loaded = 0; sceKernelDelayThread(50000); sceAudioChRelease(AT3_Channel); sceAudiocodecReleaseEDRAM(AT3_Codec_Buffer); sceKernelWaitThreadEnd(AT3_ThreadID, NULL); sceKernelTerminateDeleteThread(AT3_ThreadID); if(Tune) triFree(Tune); }
int main(int argc, char *argv[]) { int result, data; SceCtrlData pad_data[128]; SceCtrlLatch latch; schedulingLogPos = schedulingLog; SceUID thread = sceKernelCreateThread("preempt", &testThread, sceKernelGetThreadCurrentPriority() - 1, 0x500, 0, NULL); sceKernelStartThread(thread, 0, 0); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlSetSamplingMode 1\n"); didPreempt = 0; result = sceCtrlSetSamplingMode(1); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlSetSamplingMode 1: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlSetSamplingMode 0\n"); didPreempt = 0; result = sceCtrlSetSamplingMode(0); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlSetSamplingMode 0: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlSetSamplingCycle 0\n"); didPreempt = 0; result = sceCtrlSetSamplingCycle(0); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlSetSamplingCycle 0: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlGetSamplingMode\n"); didPreempt = 0; result = sceCtrlGetSamplingMode(&data); schedulingLogPos += sprintf(schedulingLogPos, "VALUE: %08x\n", data); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlGetSamplingMode: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadBufferPositive 1\n"); didPreempt = 0; result = sceCtrlReadBufferPositive(&pad_data[0], 1); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadBufferPositive 1: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadBufferPositive 64\n"); didPreempt = 0; result = sceCtrlReadBufferPositive(&pad_data[0], 64); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadBufferPositive 64: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlPeekBufferPositive 64\n"); didPreempt = 0; result = sceCtrlPeekBufferPositive(&pad_data[0], 64); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlPeekBufferPositive 64: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadBufferPositive 96\n"); didPreempt = 0; result = sceCtrlReadBufferPositive(&pad_data[0], 96); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadBufferPositive 96: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlPeekLatch\n"); didPreempt = 0; result = sceCtrlPeekLatch(&latch); // Result is # of reads, which won't match headless. result = result >= 1 ? 1 : 0; outputLatchData(result, &latch); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlPeekLatch: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadLatch\n"); didPreempt = 0; result = sceCtrlReadLatch(&latch); // Result is # of reads, which won't match headless. result = result >= 1 ? 1 : 0; outputLatchData(result, &latch); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadLatch: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlPeekLatch\n"); didPreempt = 0; result = sceCtrlPeekLatch(&latch); outputLatchData(result, &latch); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlPeekLatch: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); sceKernelTerminateDeleteThread(thread); sceKernelDelayThread(300); printf("%s", schedulingLog); return 0; }
void runReferTests() { SceKernelThreadInfo2 info; int i; SceUID delayThread = sceKernelCreateThread("delay", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, PSP_THREAD_ATTR_VFPU, NULL); SceUID deletedThread = sceKernelCreateThread("deleted", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL); sceKernelDeleteThread(deletedThread); info.size = sizeof(info); checkpointNext("Thread IDs:"); checkpoint(" NULL: %08x", sceKernelReferThreadStatus(0, &info)); checkpoint(" Current: %08x", sceKernelReferThreadStatus(sceKernelGetThreadId(), &info)); checkpoint(" Deleted: %08x", sceKernelReferThreadStatus(deletedThread, &info)); checkpoint(" Invalid: %08x", sceKernelReferThreadStatus(0xDEADBEEF, &info)); // Crashes. //checkpointNext("sceKernelReferThreadStatus info ptr:"); //checkpoint(" NULL info: %08x", sceKernelReferThreadStatus(0, NULL)); checkpointNext("Sizes:"); int sizes[] = {-1, 0, 1, 2, 3, 4, 5, 8, 16, 32, 64, 80, 82, 108, 128, 1024}; for (i = 0; i < ARRAY_SIZE(sizes); ++i) { memset(&info, 0xff, sizeof(info)); info.size = sizes[i]; int result = sceKernelReferThreadStatus(0, &info); checkpoint(" %d: %08x => %d (exit: %x)", sizes[i], result, info.size, info.exitStatus); } info.size = sizeof(info); sceKernelStartThread(delayThread, 0, NULL); sceKernelReferThreadStatus(delayThread, &info); checkpointNext("Values:"); schedfThreadInfo(&info, &delayFunc); SceUID slumberThread = sceKernelCreateThread("slumber", &slumberFunc, sceKernelGetThreadCurrentPriority() - 1, 0x1000, 0, NULL); checkpoint(" slumber before start:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelStartThread(slumberThread, 0, NULL); checkpoint(" started slumber"); checkpoint(" slumber after start:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelTerminateThread(slumberThread); checkpoint(" terminated slumber"); checkpoint(" slumber after terminate:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelStartThread(slumberThread, 0, NULL); checkpoint(" started slumber"); checkpoint(" slumber after start:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); checkpoint(" woke slumber: %08x", sceKernelWakeupThread(slumberThread)); checkpoint(" slumber after wake:"); sceKernelReferThreadStatus(slumberThread, &info); schedfThreadInfo(&info, &slumberFunc); sceKernelTerminateDeleteThread(slumberThread); checkpoint(" terminated and deleted slumber"); // TODO: Test more cases. flushschedf(); }
void SDL_SYS_KillThread(SDL_Thread *thread) { sceKernelTerminateDeleteThread(thread->handle); }
int main(int argc, char *argv[]) { int i; char temp[128]; setup(); testAlloc("Normal", PSP_MEMORY_PARTITION_USER, "test", 0, 0x10, NULL); printf("\nNames:\n"); testAlloc(" NULL name", PSP_MEMORY_PARTITION_USER, NULL, 0, 0x1000, NULL); testAlloc(" Blank name", PSP_MEMORY_PARTITION_USER, "", 0, 0x1000, NULL); testAlloc(" Long name", PSP_MEMORY_PARTITION_USER, "1234567890123456789012345678901234567890123456789012345678901234", 0, 0x1000, NULL); printf("\nPartitions:\n"); int parts[] = {-5, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; for (i = 0; i < sizeof(parts) / sizeof(parts[0]); ++i) { sprintf(temp, " Partition %d", parts[i]); testAlloc(temp, parts[i], "part", 0, 0x1000, NULL); } printf("\nTypes:\n"); unsigned int types[] = {-5, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; for (i = 0; i < sizeof(types) / sizeof(types[0]); ++i) { sprintf(temp, " Type %d", types[i]); testAlloc(temp, PSP_MEMORY_PARTITION_USER, "type", types[i], 0x1000, NULL); } printf("\nSizes:\n"); unsigned int sizes[] = { -1, 0, 1, 0x10, 0x20, 0x2F, 0x30, 0x31, 0x32, 0x36, 0x38, 0x39, 0x3A, 0x131, 0x136, 0x139, 0x1000, 0x10000, 0x100000, 0x1000000, 0x10000000, 0x1800000, 0x2000000, }; for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); ++i) { sprintf(temp, " Size 0x%08X", sizes[i]); testAlloc(temp, PSP_MEMORY_PARTITION_USER, "size", 0, sizes[i], NULL); } printf("\nPositions:\n"); testAlloc(" Wrong type", PSP_MEMORY_PARTITION_USER, "pos", 0, 0x1000, high - 0x1000); testAlloc(" Below low", PSP_MEMORY_PARTITION_USER, "pos", 2, 0x1000, low - 0x1000); testAlloc(" At low", PSP_MEMORY_PARTITION_USER, "pos", 2, 0x1000, low); testAlloc(" Above low", PSP_MEMORY_PARTITION_USER, "pos", 2, 0x1000, low + 0x1000); testAlloc(" Near high", PSP_MEMORY_PARTITION_USER, "pos", 2, 0x1000, high - 0x1000); testAlloc(" At high", PSP_MEMORY_PARTITION_USER, "pos", 2, 0x1000, high); testAlloc(" Above high", PSP_MEMORY_PARTITION_USER, "pos", 2, 0x1000, high + 0x1000); SceUID posPart1 = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part1", 2, 0x1000, low); char *pos1 = (char *)sceKernelGetBlockHeadAddr(posPart1); testAlloc(" Second at low", PSP_MEMORY_PARTITION_USER, "part2", 2, 0x1000, low); char *pos2 = testAlloc(" Second type low", PSP_MEMORY_PARTITION_USER, "part2", 0, 0x1000, low); printf(" Difference: %X\n", pos2 - pos1); sceKernelFreePartitionMemory(posPart1); printf("\nAlignment:\n"); SceUID alignbase[0x1000]; int alignbaseCount; for (alignbaseCount = 0; alignbaseCount < 0x1000; ++alignbaseCount) { alignbase[alignbaseCount] = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "alignbase", 0, 0x1, NULL); char *base = (char *)sceKernelGetBlockHeadAddr(alignbase[alignbaseCount]); if (((u32)base & 0xFFF) == 0xF00) break; } SceUID alignLowID = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part1", 3, 0x1000, (void *)0x1000); SceUID alignHighID = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part2", 4, 0x1000, (void *)0x1000); char *alignLow = (char *)sceKernelGetBlockHeadAddr(alignLowID); char *alignHigh = (char *)sceKernelGetBlockHeadAddr(alignHighID); unsigned int aligns[] = { -5, -1, 0, 1, 2, 3, 4, 7, 8, 0x10, 0x11, 0x20, 0x2F, 0x40, 0x60, 0x80, 0x100, 0x1000, 0x2000, 0x1000000, 0x4000000, 0x40000000, 0x80000000, }; for (i = 0; i < sizeof(aligns) / sizeof(aligns[0]); ++i) { sprintf(temp, " Align 0x%08X low", aligns[i]); testAllocDiff(temp, PSP_MEMORY_PARTITION_USER, "part2", 3, 0x1000, (char *)aligns[i], 0, alignLow); sprintf(temp, " Align 0x%08X high", aligns[i]); testAllocDiff(temp, PSP_MEMORY_PARTITION_USER, "part2", 4, 0x1000, (char *)aligns[i], 1, alignHigh); } sceKernelFreePartitionMemory(alignLowID); while (alignbaseCount >= 0) { sceKernelFreePartitionMemory(alignbase[alignbaseCount--]); } sceKernelFreePartitionMemory(alignHighID); printf("\n"); SceUID part1 = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part1", 0, 0x1, NULL); SceUID part2 = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part2", 0, 0x1, NULL); if (part1 > 0 && part2 > 0) { printf("Two with same name: OK\n"); } else { printf("Two with same name: Failed (%08X, %08X)\n", part1, part2); } char *part1Pos = (char *)sceKernelGetBlockHeadAddr(part1); char *part2Pos = (char *)sceKernelGetBlockHeadAddr(part2); printf("Minimum difference: %x\n", part2Pos - part1Pos); sceKernelFreePartitionMemory(part1); sceKernelFreePartitionMemory(part2); part1 = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part1", 3, 0x101, (void *)1); part2 = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part2", 3, 0x101, (void *)1); part1Pos = (char *)sceKernelGetBlockHeadAddr(part1); part2Pos = (char *)sceKernelGetBlockHeadAddr(part2); printf("Offset difference: %x\n", part2Pos - part1Pos); sceKernelFreePartitionMemory(part1); sceKernelFreePartitionMemory(part2); SceUID reschedThread = sceKernelCreateThread("resched", &reschedFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL); sceKernelStartThread(reschedThread, 0, NULL); SceUID reschedPart = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "part", 0, 0x1000, NULL); sceKernelGetBlockHeadAddr(reschedPart); sceKernelFreePartitionMemory(reschedPart); sceKernelTerminateDeleteThread(reschedThread); printf("Reschedule: %s\n", didResched ? "yes" : "no"); SceUID allocs[1024]; int result = 0; for (i = 0; i < 1024; i++) { allocs[i] = sceKernelAllocPartitionMemory(PSP_MEMORY_PARTITION_USER, "create", 0, 0x100, NULL); if (allocs[i] < 0) { result = allocs[i]; break; } } if (result != 0) printf("Create 1024: Failed at %d (%08X)\n", i, result); else printf("Create 1024: OK\n"); while (--i >= 0) sceKernelFreePartitionMemory(allocs[i]); printf("Get deleted: %08X\n", (unsigned int)sceKernelGetBlockHeadAddr(reschedPart)); printf("Get NULL: %08X\n", (unsigned int)sceKernelGetBlockHeadAddr(0)); printf("Get invalid: %08X\n", (unsigned int)sceKernelGetBlockHeadAddr(0xDEADBEEF)); printf("Free deleted: %08X\n", sceKernelFreePartitionMemory(reschedPart)); printf("Free NULL: %08X\n", sceKernelFreePartitionMemory(0)); printf("Free invalid: %08X\n", sceKernelFreePartitionMemory(0xDEADBEEF)); return 0; }
static inline void deinit_context_switch(void) { sceKernelTerminateDeleteThread(cpu_thread); }
void endLockThreadSema(SceUID sema) { SceUInt timeout = 10000; dispatchCheckpoint("E sceKernelWaitThreadEnd: %08x", sceKernelWaitThreadEnd(lockThread, &timeout)); dispatchCheckpoint("E sceKernelTerminateDeleteThread: %08x", sceKernelTerminateDeleteThread(lockThread)); }