In my testing it appears that some calls such as sceDisplayWaitVblankStart and/or sceCtrlReadBufferPositive will give up the timeslice and switch to a different thread.sceKernelCreateThread(const char *name, void *func, int initpriority, int stacksize, int extra1, int extra2). Extra 1 and 2 seem to almost always be zero it seems. Also bear in mind like the ps2 the psp seems to have co-operative threading which means you either need to call sceKernelRotateThreadReadyQueue to switch to the next thread or sleep etc. And priorities are lowest is highest ;)
I've got everything mostly working, but I was wondering if anyone has more information on what is really going on? When I actually try to use the sceKernelThreadSleep functions and such I cannot get it to work, but by the use of sceDisplayWaitVblankStart and/or sceCtrlReadBufferPositive seems to switch threads correctly.
Thanks.