void mp3_pause(int pause) { if (mp3_thread >= 0) { if (mp3_running) { if (pause) { if (mp3_status == MP3_PLAY) { mp3_status = MP3_PAUSE; sceKernelSuspendThread(mp3_thread); memset(mp3_out[0], 0, MP3_BUFFER_SIZE); memset(mp3_out[1], 0, MP3_BUFFER_SIZE); sceAudioOutputPannedBlocking(mp3_handle, 0, 0, mp3_out[0]); } } else { if (mp3_status == MP3_PAUSE) { mp3_status = MP3_PLAY; sceKernelResumeThread(mp3_thread); } else if (mp3_status == MP3_SLEEP) { mp3_status = MP3_PLAY; sceKernelWakeupThread(mp3_thread); } } } } }
void mp3_seek_start(void) { if (mp3_thread >= 0) { mp3_set_volume(); sceKernelWakeupThread(mp3_thread); } }
void flip_buffers(void) { pollAudio(); sceKernelWakeupThread(sound_thid); graphic_paint(); if (!running()) { game_exit(); } }
int disconnectSocket() { int i; for ( i = 0; i < 4; i ++ ) { if ( ctrl_opts.sock[i].thid >= 0 ) { ctrl_opts.sock[i].operation = S_TERM; sceKernelWakeupThread( ctrl_opts.sock[i].thid ); } sceNetInetClose( ctrl_opts.sock[i].server ); ctrl_opts.sock[i].server = -1; } return 0; }
void pspAudioSetChannelCallback(int channel, pspAudioCallback_t callback, void *pdata) { volatile psp_audio_channelinfo *pci = &AudioStatus[channel]; if (callback == 0) { deletingthread = sceKernelGetThreadId();; pci->callback = 0; sceKernelSleepThread(); } else { pci->callback=callback; sceKernelWakeupThread(pci->threadhandle); } }
void mp3_thread_stop(void) { if (mp3_thread >= 0) { mp3_active = 0; mp3_stop(); sceKernelWakeupThread(mp3_thread); sceKernelWaitThreadEnd(mp3_thread, NULL); sceKernelDeleteThread(mp3_thread); mp3_thread = -1; sceAudioChRelease(mp3_handle); mp3_handle = -1; } }
static int AudioChannelThread(int args, void *argp) { volatile int bufidx=0; int channel=*(int *)argp; while (audio_terminate==0) { void *bufptr=&audio_sndbuf[channel][bufidx]; pspAudioCallback_t callback; callback=AudioStatus[channel].callback; if (callback) { char*c = bufptr; c[0]='s'; c[1]='I'; c[2]='b'; c[3]='E'; callback(bufptr, PSP_NUM_AUDIO_SAMPLES, AudioStatus[channel].pdata); if (c[0] != 's'+10 || c[1] != 'I'+10 || c[2] != 'b'+10 || c[3] != 'E'+10 ) pspAudioOutBlocking(channel,AudioStatus[channel].volumeleft,AudioStatus[channel].volumeright,bufptr); } else { sceKernelWakeupThread(deletingthread); sceKernelSleepThread(); // pspAudioOutBlocking(channel,AudioStatus[channel].volumeleft,AudioStatus[channel].volumeright,audio_zerobuf); } bufidx=(bufidx?0:1); } sceKernelExitThread(0); return 0; }
int mp3_play(const char *name) { if (mp3_thread >= 0) { strcpy(MP3_file, name); mp3_stop(); if ((mp3_fd = sceIoOpen(MP3_file, PSP_O_RDONLY, 0777)) >= 0) { MP3_get_filesize(); mp3_status = MP3_PLAY; mp3_newfile = 1; mp3_set_volume(); sceKernelWakeupThread(mp3_thread); return 0; } } return 1; }
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(); }
int main(int argc, char *argv[]) { SceCtrlData pad; int oldButtons = 0; #define SECOND 1000000 #define REPEAT_START (1 * SECOND) #define REPEAT_DELAY (SECOND / 5) struct timeval repeatStart; struct timeval repeatDelay; repeatStart.tv_sec = 0; repeatStart.tv_usec = 0; repeatDelay.tv_sec = 0; repeatDelay.tv_usec = 0; pspDebugScreenInit(); pspDebugScreenPrintf("Press Cross to start the Task Scheduler Test\n"); pspDebugScreenPrintf("Press Circle to start the CpuSuspendIntr/CpuResumeIntr Test\n"); pspDebugScreenPrintf("Press Square to start the Task with thread of same priority\n"); pspDebugScreenPrintf("Press Left to start the Task Dispatcher Test\n"); pspDebugScreenPrintf("Press Triangle to Exit\n"); while(!done) { sceCtrlReadBufferPositive(&pad, 1); int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons; if (pad.Buttons == oldButtons) { struct timeval now; gettimeofday(&now, NULL); if (repeatStart.tv_sec == 0) { repeatStart.tv_sec = now.tv_sec; repeatStart.tv_usec = now.tv_usec; repeatDelay.tv_sec = 0; repeatDelay.tv_usec = 0; } else { long usec = (now.tv_sec - repeatStart.tv_sec) * SECOND; usec += (now.tv_usec - repeatStart.tv_usec); if (usec >= REPEAT_START) { if (repeatDelay.tv_sec != 0) { usec = (now.tv_sec - repeatDelay.tv_sec) * SECOND; usec += (now.tv_usec - repeatDelay.tv_usec); if (usec >= REPEAT_DELAY) { repeatDelay.tv_sec = 0; } } if (repeatDelay.tv_sec == 0) { buttonDown = pad.Buttons; repeatDelay.tv_sec = now.tv_sec; repeatDelay.tv_usec = now.tv_usec; } } } } else { repeatStart.tv_sec = 0; } if (buttonDown & PSP_CTRL_CROSS) { SceUID lowThid = sceKernelCreateThread("Low Prio Thread", threadLowPrio, 0x70, 0x1000, 0, 0); SceUID mediumThid = sceKernelCreateThread("Medium Prio Thread", threadMediumPrio, 0x30, 0x1000, 0, 0); SceUID highThid = sceKernelCreateThread("High Prio Thread", threadHighPrio, 0x10, 0x1000, 0, 0); SceUID busyThid = sceKernelCreateThread("Busy Thread", threadBusy, 0x30, 0x1000, 0, 0); testDone = 0; highPrioCounter = 0; mediumPrioCounter = 0; lowPrioCounter = 0; sceKernelStartThread(lowThid, 0, 0); sceKernelStartThread(mediumThid, 0, 0); sceKernelStartThread(busyThid, 0, 0); sceKernelStartThread(highThid, 0, 0); int totalDelay = 5000000; sceKernelDelayThread(totalDelay); testDone = 1; sceKernelWaitThreadEnd(busyThid, NULL); sceKernelWaitThreadEnd(mediumThid, NULL); sceKernelWaitThreadEnd(highThid, NULL); sceKernelWaitThreadEnd(lowThid, NULL); pspDebugScreenPrintf("Counters: high=%d (%d us), medium=%d, low=%d\n", highPrioCounter, (totalDelay / highPrioCounter), mediumPrioCounter, lowPrioCounter); } if (buttonDown & PSP_CTRL_CIRCLE) { msg = buffer; strcpy(msg, ""); SceUID sleepingThid = sceKernelCreateThread("Sleeping Thread", sleepingThread, 0x10, 0x1000, 0, 0); sceKernelStartThread(sleepingThid, 0, 0); sceKernelDelayThread(100000); int intr = sceKernelCpuSuspendIntr(); sceKernelWakeupThread(sleepingThid); strcat(msg, "Main Thread with disabled interrupts\n"); sceKernelCpuResumeIntr(intr); strcat(msg, "Main Thread with enabled interrupts\n"); pspDebugScreenPrintf("%s", msg); } if (buttonDown & PSP_CTRL_SQUARE) { msg = buffer; strcpy(msg, ""); // Two threads having the same priority SceUID thread1 = sceKernelCreateThread("Thread 1", threadPrio_1, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0); SceUID thread2 = sceKernelCreateThread("Thread 2", threadPrio_2, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0); // Test that thread1 will be scheduled before thread2 sceKernelStartThread(thread1, 0, 0); sceKernelStartThread(thread2, 0, 0); strcat(msg, "1 "); sceKernelDelayThread(10000); strcat(msg, "4"); sceKernelWaitThreadEnd(thread1, NULL); sceKernelWaitThreadEnd(thread2, NULL); pspDebugScreenPrintf("Starting 2 threads at same priority: %s\n", msg); // Now with a different order for create & start strcpy(msg, ""); SceUID thread3 = sceKernelCreateThread("Thread 3", threadPrio_3, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0); SceUID thread4 = sceKernelCreateThread("Thread 4", threadPrio_4, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0); // Test that thread4 will be scheduled before thread3 sceKernelStartThread(thread4, 0, 0); sceKernelStartThread(thread3, 0, 0); strcat(msg, "1 "); sceKernelDelayThread(10000); strcat(msg, "4"); sceKernelWaitThreadEnd(thread3, NULL); sceKernelWaitThreadEnd(thread4, NULL); pspDebugScreenPrintf("Starting 2 threads with a different order create/start: %s\n", msg); } if (buttonDown & PSP_CTRL_LEFT) { msg = buffer; strcpy(msg, ""); int state = sceKernelSuspendDispatchThread(); // High priority thread SceUID thread = sceKernelCreateThread("Thread 1", threadHello, 0x10, 0x1000, 0, 0); strcat(msg, "1 "); // sceKernelStartThread resumes the thread dispatcher sceKernelStartThread(thread, 0, 0); strcat(msg, "2 "); sceKernelDelayThread(10000); strcat(msg, "3 "); sceKernelResumeDispatchThread(state); sceKernelWaitThreadEnd(thread, NULL); pspDebugScreenPrintf("Starting high prio thread with a disabled dispatcher (state=0x%X): %s\n", state, msg); msg = buffer; strcpy(msg, ""); state = sceKernelSuspendDispatchThread(); // Low priority thread thread = sceKernelCreateThread("Thread 1", threadHello, 0x70, 0x1000, 0, 0); strcat(msg, "1 "); // sceKernelStartThread resumes the thread dispatcher sceKernelStartThread(thread, 0, 0); strcat(msg, "2 "); sceKernelDelayThread(10000); strcat(msg, "3 "); sceKernelResumeDispatchThread(state); sceKernelWaitThreadEnd(thread, NULL); pspDebugScreenPrintf("Starting low prio thread with a disabled dispatcher (state=0x%X): %s\n", state, msg); } if (buttonDown & PSP_CTRL_TRIANGLE) { done = 1; } oldButtons = pad.Buttons; } sceGuTerm(); sceKernelExitGame(); return 0; }
int main_thread(SceSize args, void *argp) { struct PsplinkContext *ctx; int ret; SceUInt timeout; SceUID thids[20]; int count; int intc; printf("PSPLink USB GDBServer (c) 2k7 TyRaNiD\n"); if(!initialise(args, argp)) { printf("Usage: usbgdb.prx program [args]\n"); sceKernelExitDeleteThread(0); } if(usbAsyncRegister(ASYNC_GDB, &g_endp) < 0) { printf("Could not register GDB provider\n"); sceKernelExitDeleteThread(0); } usbWaitForConnect(); memset(&g_handler, 0, sizeof(g_handler)); g_handler.size = sizeof(g_handler); g_handler.membase = g_context.info.text_addr; g_handler.memtop = g_context.info.text_addr + g_context.info.text_size; g_handler.mbox = sceKernelCreateMbx("GDBMbx", 0, NULL); if(g_handler.mbox < 0) { printf("Could not create message box\n"); sceKernelExitDeleteThread(0); } if(debugRegisterEventHandler(&g_handler) < 0) { printf("Could not register event handler\n"); sceKernelExitDeleteThread(0); } if(GdbHandleException(&g_context.ctx)) { while(1) { timeout = GDB_POLL_TIMEOUT; ret = debugWaitDebugEvent(&g_handler, &ctx, &timeout); if(ret == 0) { DEBUG_PRINTF("ctx %p, epc 0x%08X\n", ctx, ctx->regs.epc); ret = GdbHandleException(ctx); sceKernelWakeupThread(ctx->thid); if(ret == 0) { break; } } else if(ret == SCE_KERNEL_ERROR_WAIT_TIMEOUT) { unsigned char ch; if(peekDebugChar(&ch) && (ch == 3)) { DEBUG_PRINTF("Break Issued\n"); intc = pspSdkDisableInterrupts(); count = psplinkReferThreadsByModule(SCE_KERNEL_TMID_Thread, g_context.uid, thids, 20); if(count > 0) { /* We just break the first thread */ /* Could in theory break on the thread which we are interested in ? */ debugBreakThread(thids[0]); } pspSdkEnableInterrupts(intc); /* Should have a fallback if it just wont stop GdbHandleException(&g_context.ctx); */ } continue; } else { printf("Error waiting for debug event 0x%08X\n", ret); break; } } } debugUnregisterEventHandler(&g_handler); sceKernelExitDeleteThread(0); return 0; }
int main(int argc, char *argv[]) { SceCtrlData pad; int oldButtons = 0; #define SECOND 1000000 #define REPEAT_START (1 * SECOND) #define REPEAT_DELAY (SECOND / 5) struct timeval repeatStart; struct timeval repeatDelay; int result; int msgCount = 0; repeatStart.tv_sec = 0; repeatStart.tv_usec = 0; repeatDelay.tv_sec = 0; repeatDelay.tv_usec = 0; printHeader(); int receiveThreadId = sceKernelCreateThread("ReceiveMbx", receiveMbxThread, 0x50, 0x1000, 0, 0); sceKernelStartThread(receiveThreadId, 0, 0); while (!done) { sceCtrlReadBufferPositive(&pad, 1); int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons; if (pad.Buttons == oldButtons) { struct timeval now; gettimeofday(&now, NULL); if (repeatStart.tv_sec == 0) { repeatStart.tv_sec = now.tv_sec; repeatStart.tv_usec = now.tv_usec; repeatDelay.tv_sec = 0; repeatDelay.tv_usec = 0; } else { long usec = (now.tv_sec - repeatStart.tv_sec) * SECOND; usec += (now.tv_usec - repeatStart.tv_usec); if (usec >= REPEAT_START) { if (repeatDelay.tv_sec != 0) { usec = (now.tv_sec - repeatDelay.tv_sec) * SECOND; usec += (now.tv_usec - repeatDelay.tv_usec); if (usec >= REPEAT_DELAY) { repeatDelay.tv_sec = 0; } } if (repeatDelay.tv_sec == 0) { buttonDown = pad.Buttons; repeatDelay.tv_sec = now.tv_sec; repeatDelay.tv_usec = now.tv_usec; } } } } else { repeatStart.tv_sec = 0; } if (buttonDown & PSP_CTRL_CROSS) { printHeader(); mbxId = sceKernelCreateMbx("Mbx", 0, NULL); pspDebugScreenPrintf("sceKernelCreateMbx = 0x%08X\n", mbxId); printMbxStatus(mbxId); } if (buttonDown & PSP_CTRL_CIRCLE) { printHeader(); msgCount++; MyMessage *msg = malloc(sizeof(MyMessage)); msg->header.next = (void *) 0x12345678; msg->header.msgPriority = 1; msg->header.dummy[0] = 2; msg->header.dummy[1] = 3; msg->header.dummy[2] = 4; sprintf(msg->text, "Hello %d", msgCount); result = sceKernelSendMbx(mbxId, msg); pspDebugScreenPrintf("sceKernelSendMbx msg=0x%08X, msgCount=%d: 0x%08X\n", (int) msg, msgCount, result); printMbxStatus(mbxId); } if (buttonDown & PSP_CTRL_SQUARE) { printHeader(); printMbxStatus(mbxId); } if (buttonDown & PSP_CTRL_LEFT) { sceKernelWakeupThread(receiveThreadId); printHeader(); } if (buttonDown & PSP_CTRL_TRIANGLE) { done = 1; } oldButtons = pad.Buttons; } sceGuTerm(); sceKernelExitGame(); return 0; }
static inline void switch_to_cpu_thread(void) { sceKernelWakeupThread(cpu_thread); sceKernelSleepThread(); }
void switch_to_main_thread(void) { sceKernelWakeupThread(main_thread); sceKernelSleepThread(); }