void testThreadsEnded() { int thread1, thread2, thread3, thread4; // Thread1 will stop returning the function and sceKernelWaitThreadEnd will be executed after the thread have ended. thread1 = sceKernelCreateThread("threadEndedFunction1", (void *)&threadEndedFunction1, 0x12, 0x10000, 0, NULL); // Thread1 will stop with sceKernelExitThread and sceKernelWaitThreadEnd will be executed after the thread have ended. thread2 = sceKernelCreateThread("threadEndedFunction2", (void *)&threadEndedFunction2, 0x12, 0x10000, 0, NULL); // Thread3 will stop after a while so it will allow to execute sceKernelWaitThreadEnd before it ends. thread3 = sceKernelCreateThread("threadEndedFunction3", (void *)&threadEndedFunction3, 0x12, 0x10000, 0, NULL); // Thread4 won't start never, so sceKernelWaitThreadEnd can be executed before thread is started. thread4 = sceKernelCreateThread("threadEndedFunction4", NULL, 0x12, 0x10000, 0, NULL); sceKernelStartThread(thread1, 0, NULL); sceKernelStartThread(thread2, 0, NULL); sceKernelStartThread(thread3, 0, NULL); // This waits 5ms and supposes both threads (1 and 2) have ended. Thread 3 should have not ended. Thread 4 is not going to be started. sceKernelDelayThread(2 * 1000); printf("Threads.EndedExpected\n"); sceKernelWaitThreadEnd(thread1, NULL); printf("Thread1.Ended\n"); sceKernelWaitThreadEnd(thread2, NULL); printf("Thread2.Ended\n"); sceKernelWaitThreadEnd(thread3, NULL); printf("Thread3.Ended\n"); sceKernelWaitThreadEnd(thread4, NULL); printf("Thread4.NotStartedSoEnded\n"); }
Psp2Audio::~Psp2Audio() { // Just to be sure to clean up before exiting SE_Stop(); BGM_Stop(); // Closing BGM streaming thread termStream = true; sceKernelWaitThreadEnd(BGM_Thread, NULL, NULL); if (BGM != NULL){ free(BGM->audiobuf); audio_decoder.reset(); free(BGM); } // Starting exit procedure for sfx threads mustExit = true; sceKernelSignalSema(SFX_Mutex, 1); for (int i=0;i<AUDIO_CHANNELS;i++){ sceKernelWaitThreadEnd(sfx_threads[i], NULL, NULL); } sfx_exited = 0; // Deleting mutexs sceKernelDeleteSema(BGM_Mutex); sceKernelDeleteSema(SFX_Mutex); sceKernelDeleteSema(SFX_Mutex_ID); }
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); } }
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); }
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; }
static void client_list_thread_end() { ClientInfo *it, *next; SceUID client_thid; sceKernelLockMutex(client_list_mtx, 1, NULL); it = client_list; /* Iterate over the client list and close their sockets */ while (it) { next = it->next; client_thid = it->thid; /* Shutdown the client's control socket */ sceNetShutdown(it->ctrl_sockfd, PSP2_NET_SHUT_RDWR); /* Wait until the client threads ends */ sceKernelWaitThreadEnd(client_thid, NULL, NULL); it = next; } sceKernelUnlockMutex(client_list_mtx, 1); }
int MP3ME_Stop(){ MP3ME_isPlaying = 0; MP3ME_threadActive = 0; sceKernelWaitThreadEnd(MP3ME_thid, NULL); sceKernelDeleteThread(MP3ME_thid); return 0; }
void ftp_fini() { if (ftp_initialized) { /* In order to "stop" the blocking sceNetAccept, * we have to close the server socket; this way * the accept call will return an error */ sceNetSocketClose(server_sockfd); /* Wait until the server threads ends */ sceKernelWaitThreadEnd(server_thid, NULL, NULL); /* To close the clients we have to do the same: * we have to iterate over all the clients * and shutdown their sockets */ client_list_thread_end(); /* Delete the client list mutex */ sceKernelDeleteMutex(client_list_mtx); client_list = NULL; sceNetCtlTerm(); sceNetTerm(); if (net_memory) { free(net_memory); net_memory = NULL; } ftp_initialized = 0; } }
int module_stop(void) { if (sysbutton_thread >= 0) { thread_active = 0; sceKernelWaitThreadEnd(sysbutton_thread, NULL); } return 0; }
int module_stop(void) { if (main_thread_id >= 0) { thread_active = 0; sceKernelWaitThreadEnd(main_thread_id, NULL); } return 0; }
void CDAudio_Shutdown(void) { mustExit = true; sceKernelSignalSema(Audio_Mutex, 1); sceKernelWaitThreadEnd(thread, NULL, NULL); sceKernelDeleteSema(Audio_Mutex); sceKernelDeleteSema(Talk_Mutex); sceKernelDeleteThread(thread); }
static void psp_audio_free(void *data) { SceUInt timeout = 100000; psp_audio_t* psp = (psp_audio_t*)data; if(!psp) return; psp->running = false; #if defined(VITA) sceKernelWaitThreadEnd(psp->thread, NULL, &timeout); #else sceKernelWaitThreadEnd(psp->thread, &timeout); #endif sceKernelDeleteThread(psp->thread); free(psp->buffer); free(psp->zeroBuffer); free(psp); }
void OSPC_StopPlay(){ if (OSPC_thread<0) return; OSPC_exit=1; sceKernelWaitThreadEnd( OSPC_thread, NULL ); sceKernelDeleteThread( OSPC_thread ); OSPC_thread=-1; sceAudioChRelease( OSPC_sound_fd ); OSPC_Stop(); OSPC_Close(); if (OSPC_id) free(OSPC_id); }
static void psp_audio_free(void *data) { SceUInt timeout = 100000; psp_audio_t* psp = (psp_audio_t*)data; if(!psp) return; psp->running = false; #if defined(VITA) sceKernelWaitThreadEnd(psp->thread, NULL, &timeout); sceKernelDeleteLwMutex((struct SceKernelLwMutexWork*)&psp->lock); sceKernelDeleteLwMutex((struct SceKernelLwMutexWork*)&psp->cond_lock); sceKernelDeleteLwCond(&psp->cond); #else sceKernelWaitThreadEnd(psp->thread, &timeout); #endif free(psp->buffer); sceKernelDeleteThread(psp->thread); free(psp->zeroBuffer); free(psp); }
static bool psp_audio_stop(void *data) { SceUInt timeout = 100000; psp_audio_t* psp = (psp_audio_t*)data; #if defined(VITA) SceKernelThreadInfo info; info.size = sizeof(SceKernelThreadInfo); if (sceKernelGetThreadInfo( psp->thread, &info) < 0) /* Error */ return false; if (info.status == PSP2_THREAD_STOPPED) return false; #else SceKernelThreadRunStatus runStatus; runStatus.size = sizeof(SceKernelThreadRunStatus); if (sceKernelReferThreadRunStatus( psp->thread, &runStatus) < 0) /* Error */ return false; if (runStatus.status == PSP_THREAD_STOPPED) return false; #endif psp->running = false; #if defined(VITA) sceKernelWaitThreadEnd(psp->thread, NULL, &timeout); #else sceKernelWaitThreadEnd(psp->thread, &timeout); #endif return true; }
void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr) { // Dunno what these three defaults should be... u32 priority = 0x20; u32 stacksize = 0x40000; u32 attr = 0; int stackPartition = 0; if (optionAddr) { SceKernelSMOption smoption; Memory::ReadStruct(optionAddr, &smoption);; priority = smoption.priority; attr = smoption.attribute; stacksize = smoption.stacksize; stackPartition = smoption.mpidstack; } u32 error; Module *module = kernelObjects.Get<Module>(moduleId, error); if (!module) { RETURN(error); return; } else if (module->isFake) { INFO_LOG(HLE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x,%08x): faked (undecryptable module)", moduleId,argsize,argAddr,returnValueAddr,optionAddr); } else { WARN_LOG(HLE, "UNIMPL sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x,%08x)", moduleId,argsize,argAddr,returnValueAddr,optionAddr); u32 entryAddr = module->nm.entry_addr; if (entryAddr == (u32)-1 || entryAddr == module->memoryBlockAddr - 1) { // TODO: Do these always take effect, or do they not override optionAddr? if (module->nm.module_start_func != 0 && module->nm.module_start_func != (u32)-1) { entryAddr = module->nm.module_start_func; priority = module->nm.module_start_thread_priority; attr = module->nm.module_start_thread_attr; stacksize = module->nm.module_start_thread_stacksize; } else { // TODO: Fix, check return value? Or do we call nothing? RETURN(moduleId); return; } } SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attr, 0); sceKernelStartThread(threadID, argsize, argAddr); // TODO: This will probably return the wrong value? sceKernelWaitThreadEnd(threadID, 0); } // TODO: Is this the correct return value? RETURN(moduleId); }
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); }
void OSPC_PlayBuffer(char *buff,int len,int release,int vol) { int i,j,pollcpt; char str[256]; SPC_ID666 *id; char *emulator[3]={"Unknown","Zsnes","Snes9x"}; uint8 *scr; OSPC_Init(); if (i=OSPC_LoadBuffer(buff,len)) { sprintf(str,"Error at SPC loading, code : %d",i); msgBoxLines(str,60); //gp32_pause(); //GpAppExit(); return; } OSPC_id=OSPC_GetID666(spc_data); OSPC_sound_fd = sceAudioChReserve( -1, 1024, 0 ); OSPC_exit=0; OSPC_volume=vol; OSPC_thread = sceKernelCreateThread( "OSPC Thread", (SceKernelThreadEntry)OSPC_PlayThread, 0x8, 256*1024, 0, 0 ); if (OSPC_thread<0) { msgBoxLines("Cannot create OSPC playback thread",60); } else { //init start time sceKernelLibcGettimeofday( &OSPC_start_time, 0 ); sceKernelStartThread( OSPC_thread, 0, 0 ); if (release) return; for (;;) { pgWaitV(); if (get_pad()) break; } OSPC_exit=1; sceKernelWaitThreadEnd( OSPC_thread, NULL ); sceKernelDeleteThread( OSPC_thread ); OSPC_thread=-1; } sceAudioChRelease( OSPC_sound_fd ); OSPC_Stop(); OSPC_Close(); if (OSPC_id) free(OSPC_id); }
Psp2Ui::~Psp2Ui() { sceKernelWaitSema(GPU_Cleanup_Mutex, 1, NULL); for (int i = 0; i < SHADERS_NUM; i++){ vita2d_free_shader(shaders[i]); } vita2d_free_texture(main_texture); main_texture = NULL; sceKernelSignalSema(GPU_Cleanup_Mutex, 1); sceKernelWaitThreadEnd(GPU_Thread, NULL, NULL); vita2d_free_texture(next_texture); vita2d_free_texture(gpu_texture); sceKernelDeleteSema(GPU_Mutex); sceKernelDeleteSema(GPU_Cleanup_Mutex); vita2d_fini(); }
static void psp_audio_free(void *data) { SceUInt timeout = 100000; psp1_audio_t* psp = (psp1_audio_t*)data; if(!psp) return; psp->running = false; sceKernelWaitThreadEnd(psp->thread, &timeout); sceKernelDeleteThread(psp->thread); free(psp->buffer); free(psp->zeroBuffer); free(psp); }
/********************************************//** * \brief Loads a executable at path * * Starts a new thread with the homebrew * loaded. Waits until the homebrew exits and * returns. * \returns Thread ID on success, otherwise error ***********************************************/ int uvl_load (const char *path) { char data_blob[LOADED_INFO_SIZE]; uvl_loaded_t *loaded; int (*start)(int, void *); int ret_value; PsvUID tid; int i; loaded = (uvl_loaded_t *)data_blob; IF_DEBUG LOG ("Loading homebrew"); if (uvl_load_exe (path, (void**)&start, loaded) < 0) { LOG ("Cannot load homebrew."); return -1; } IF_DEBUG LOG ("Starting homebrew: entry at 0x%08X", start); tid = sceKernelCreateThread ("homebrew", start, 0, 0x00040000, 0, 0x00070000, NULL); if (tid < 0) { LOG ("Cannot create thread."); return -1; } loaded->tid = tid; IF_DEBUG LOG ("Starting new thread."); if (sceKernelStartThread (tid, 0, NULL) < 0) { LOG ("Cannot start thread."); return -1; } IF_DEBUG LOG ("Homebrew running..."); if (sceKernelWaitThreadEnd (tid, &ret_value, NULL) < 0) { LOG ("Failed to wait for thread to exit."); } IF_DEBUG LOG ("Homebrew exited with value 0x%08X", ret_value); // free segments for (i = 0; i < loaded->numsegs; i++) { sceKernelFreeMemBlock (loaded->segs[i]); } return 0; }
/*---------------------------------------------------------------------- | NPT_PSPThread::Wait +---------------------------------------------------------------------*/ NPT_Result NPT_PSPThread::Wait() { // check that we're not detached if (m_ThreadId <= 0 || m_Detached) { return NPT_FAILURE; } // wait for the thread to finish NPT_Debug(NPT_LOG_LEVEL_1, ":: NPT_PSPThread::Wait - joining thread id %d\n", m_ThreadId); int result = sceKernelWaitThreadEnd(m_ThreadId, NULL); if (result < 0) { return NPT_FAILURE; } else { return NPT_SUCCESS; } }
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; } }
void audio_Term(void) { int i; audio_ready = 0; audio_terminate = 1; for (i=0; i<CHANNELS; i++) { if (audio_thread_handle[i] != -1) { sceKernelWaitThreadEnd(audio_thread_handle[i], NULL); sceKernelDeleteThread(audio_thread_handle[i]); } audio_thread_handle[i] = -1; } for (i=0; i<CHANNELS; i++) { if (audio_handles[i] != -1) { sceAudioChRelease(audio_handles[i]); audio_handles[i] = -1; } } }
void multipleTest() { int threads[N_THREADS]; int n; semaid = sceKernelCreateSema("sema1", 0, 0, 255, NULL); mutexid = sceKernelCreateMutex("mutex", PSP_MUTEX_ATTR_FIFO | PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0); { for (n = 0; n < N_THREADS; n++) { sceKernelStartThread(threads[n] = sceKernelCreateThread("multipleTestThread", (void *)&multipleTestThread, 0x12, 0x10000, 0, NULL), sizeof(int), &n); } sceKernelSignalSema(semaid, N_THREADS); for (n = 0; n < N_THREADS; n++) { sceKernelWaitThreadEnd(threads[n], NULL); } } sceKernelDeleteMutex(mutexid); }
static bool psp_audio_stop(void *data) { SceKernelThreadRunStatus runStatus; SceUInt timeout = 100000; psp1_audio_t* psp = (psp1_audio_t*)data; runStatus.size = sizeof(SceKernelThreadRunStatus); if (sceKernelReferThreadRunStatus( psp->thread, &runStatus) < 0) /* Error */ return false; if (runStatus.status == PSP_THREAD_STOPPED) return false; psp->running = false; sceKernelWaitThreadEnd(psp->thread, &timeout); return true; }
int main(int argc, char *argv[]) { SceUID thid; int error; void *data; pspDebugScreenInit(); if (argc > 0) { printf("Bootpath: %s\n", argv[0]); } SetupCallbacks(); /* Create a messagebox */ myMessagebox = sceKernelCreateMbx("pspSDK-testMBX", 0, 0); printf("MAIN: created messagebox %08x\n", myMessagebox); /* Create a task that will post in the messagebox */ thid = sceKernelCreateThread("subthread", SubThread, 17, 8192, THREAD_ATTR_USER, 0); sceKernelStartThread(thid, 0, NULL); printf("MAIN: started task %08x\n", thid); /* Wait for a message */ printf("MAIN: waiting for message\n"); error = sceKernelReceiveMbx(myMessagebox, &data, NULL); if(error < 0) printf("MAIN: ERROR %08x\n", error); else printf("MAIN: got message: \"%s\"\n", ((MyMessage *)data)->text); /* Wait for a message with timeout */ printf("MAIN: waiting with timeout (will fail the first couple of times)\n"); for(;;) { SceUInt timeout = 300000; /* microseconds */ error = sceKernelReceiveMbx(myMessagebox, &data, &timeout); if(error < 0) printf("MAIN: ERROR %08x\n", error); else { printf("MAIN: got message: \"%s\" (timeout remaining %d us)\n", ((MyMessage *)data)->text, timeout); break; } } /* Poll for messages */ printf("MAIN: polling for message (non-blocking)\n"); for(;;) { error = sceKernelPollMbx(myMessagebox, &data); if(error < 0) { printf("MAIN: ERROR %08x\n", error); /* Sleep for a little while to give the message a chance to arrive */ sceKernelDelayThread(300000); } else { printf("MAIN: got message: \"%s\"\n", ((MyMessage *)data)->text); break; } } /* This call to sceKernelReceiveMbx() will be interrupted by the sub task without a message being sent */ printf("MAIN: waiting for a message that will not arrive\n"); error = sceKernelReceiveMbx(myMessagebox, &data, NULL); if(error < 0) printf("MAIN: ERROR %08x\n", error); else printf("MAIN: got message: \"%s\"\n", ((MyMessage *)data)->text); /* Prepare to shutdown */ printf("MAIN: waiting for sub task to exit\n"); sceKernelWaitThreadEnd(thid, NULL); printf("MAIN: sub task exited, deleting messagebox\n"); error = sceKernelDeleteMbx(myMessagebox); if(error < 0) printf("MAIN: ERROR %08x\n", error); else printf("MAIN: all done\n"); sceKernelSleepThread(); return 0; }
void SDL_SYS_WaitThread(SDL_Thread *thread) { sceKernelWaitThreadEnd(thread->handle, NULL); sceKernelDeleteThread(thread->handle); }
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 MP3_Stop (void){ mp3_play = 0; sceKernelWaitThreadEnd(mp3_audio_thread,0); return 1; }