Threading
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
Threading
I've looked all over these forums and google, so don't flame me for not searching.
I want to pause all threads, except the one that the pauses are called from. So i can basics `freeze` the psp.
Im not good with threads and all that crap :D
--Slasher
I want to pause all threads, except the one that the pauses are called from. So i can basics `freeze` the psp.
Im not good with threads and all that crap :D
--Slasher
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
-
- Posts: 5
- Joined: Wed Aug 22, 2007 4:54 am
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
I'm not at my dev PC now so I can't give you specifics.
seplugins are loaded by systemctrl.prx after all important kernel modules are loaded. After seplugins is finished, the game module (and subsequent modules loaded by the game) is started.
Make a list of all running threads in module_start using the Threadman enumeration function (giving the type to list as Threads), so you have a list of all the Thread IDs except the game threads. This will also include any seplugins that are placed before yours in the game.txt, so the position of your plugin in game.txt is important.
Then whenever you want to freeze the game, list all the threads again and compare it with your original list of Thread IDs from module_start. Use the SuspendThread function to freeze any thread that's NOT present in the original list.
However in this state, suspend mode may not work if the game has registered a power callback. Another problem is even if the game is frozen the Home screen will still work because its one of the kernel modules loaded before module_start.
To overcome this you need to hook the RegisterPowerCallback and RegitserPowerCallback (its misspelled in earlier firmware and older game use the wrong spelling, so you need to hook both) and keep track of the registrations made by the game. You'll need to unregister the Callback IDs you've logged after freezing the game and restore them before unfreezing if you want suspend to work. If the PSP is suspended while frozen, you need to detect the suspend, restore the callbacks, unfreeze the game, send a fake suspend notice to the game using NotifyCallback.
To block the Home screen while frozen you need to hook that RegisterExitCallback as well and keep track of the Callback IDs. Unregister them after freezing, and restore before unfreezing.
seplugins are loaded by systemctrl.prx after all important kernel modules are loaded. After seplugins is finished, the game module (and subsequent modules loaded by the game) is started.
Make a list of all running threads in module_start using the Threadman enumeration function (giving the type to list as Threads), so you have a list of all the Thread IDs except the game threads. This will also include any seplugins that are placed before yours in the game.txt, so the position of your plugin in game.txt is important.
Then whenever you want to freeze the game, list all the threads again and compare it with your original list of Thread IDs from module_start. Use the SuspendThread function to freeze any thread that's NOT present in the original list.
However in this state, suspend mode may not work if the game has registered a power callback. Another problem is even if the game is frozen the Home screen will still work because its one of the kernel modules loaded before module_start.
To overcome this you need to hook the RegisterPowerCallback and RegitserPowerCallback (its misspelled in earlier firmware and older game use the wrong spelling, so you need to hook both) and keep track of the registrations made by the game. You'll need to unregister the Callback IDs you've logged after freezing the game and restore them before unfreezing if you want suspend to work. If the PSP is suspended while frozen, you need to detect the suspend, restore the callbacks, unfreeze the game, send a fake suspend notice to the game using NotifyCallback.
To block the Home screen while frozen you need to hook that RegisterExitCallback as well and keep track of the Callback IDs. Unregister them after freezing, and restore before unfreezing.
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
THANKYOU =D
now i get it.
the only bit i will have trouble with is the hooking bits, could someone give me further advice?
EDIT
The only thing i can find in the pspsdk docs remotely related is:
It's the only function that look like it retrieves the uid's.
now i get it.
the only bit i will have trouble with is the hooking bits, could someone give me further advice?
EDIT
The only thing i can find in the pspsdk docs remotely related is:
Code: Select all
sceKernelGetThreadmanIdList
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
I have been messing with this very thing recently. My idea is to make a text reader in a PRX so that you can read text while in game.
Here is my (simplified) code to list, suspend, and resume the threads. This is having problems though. When I use it with Grand Theft Auto: Vice City Stories it will sometimes hang the system after suspending one of the threads. I am not sure what is causing that as I have yet to find a way to get exception information from the 4.01 + kernels.
The two things in Torch's instructions that I am not doing:
1) Hooking callbacks - I am not that concerned if the home menu works or if the suspend function works right now, and I am not real sure how to do this yet.
2) I am listing the threads in my main() function because I am too lazy to figure out how to write my own module_start() function. I suspect this has a lot to do with it. I'll get working on it.
Here is my (simplified) code to list, suspend, and resume the threads. This is having problems though. When I use it with Grand Theft Auto: Vice City Stories it will sometimes hang the system after suspending one of the threads. I am not sure what is causing that as I have yet to find a way to get exception information from the 4.01 + kernels.
The two things in Torch's instructions that I am not doing:
1) Hooking callbacks - I am not that concerned if the home menu works or if the suspend function works right now, and I am not real sure how to do this yet.
2) I am listing the threads in my main() function because I am too lazy to figure out how to write my own module_start() function. I suspect this has a lot to do with it. I'll get working on it.
Code: Select all
#include <pspkernel.h>
#include <pspctrl.h>
#include <stdio.h>
#include <pspthreadman.h>
PSP_MODULE_INFO("pspetext", 0x1000, 0, 0);
PSP_HEAP_SIZE_KB(64);
SceUID uids[64];
int uids_num;
SceUID runingUids[256];
int runingUids_num;
int main(int argc, char **argv)
{
int padTime = 0;
int i, j;
SceCtrlData pad;
debugPrintf("Begining of Main Thread Execution\n");
/*
* Here is where I list all running thread IDs.
*/
if(sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread,
uids, 64, &uids_num) < 0)
{
printf("sceKernelGetThreadmanIdList() failed.\n");
}
while(1)
{
// Read the controls and update the timer
sceCtrlPeekBufferPositive(&pad, 1);
if(pad.Buttons & PSP_CTRL_LTRIGGER &&
pad.Buttons & PSP_CTRL_RTRIGGER)
{
padTime ++;
}
else padTime = 0;
// If the time has come trigger off the application
if(padTime >= 10)
{
// Suspend all game threads (or at least threads that did not exist before we did)
if(sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread,
runingUids, 256, &runingUids_num) < 0)
{
debugPrintf("sceKernelGetThreadmanIdList() failed.\n");
}
else
{
for(i = 0; i < runingUids_num; i ++)
{
int found;
found = 0;
for(j = 0; j < uids_num; j ++)
{
if(uids[j] == runingUids[i]) found = 1;
}
if(found == 0)
{
if(sceKernelSuspendThread(runingUids[i]) < 0)
{
debugPrintf("Unable to suspend thread %d\n", runingUids[i]);
}
else
{
debugPrintf("Suspended thread %d\n", runingUids[i]);
}
}
else
{
debugPrintf("Skipping thread %d\n", runingUids[i]);
}
}
}
// Execute PSPEText main function
petMain();
padTime = 0;
// Resume all threads suspended earlier
for(i = 0; i < runingUids_num; i ++)
{
int found;
found = 0;
for(j = 0; j < uids_num; j ++)
{
if(uids[j] == runingUids[i]) found = 1;
}
if(found == 0)
{
if(sceKernelResumeThread(runingUids[i]) < 0)
{
debugPrintf("Unable to resume thread %d\n", runingUids[i]);
}
else
{
debugPrintf("Resuming thread %d\n", runingUids[i]);
}
}
else
{
debugPrintf("Skipping thread %d\n", runingUids[i]);
}
}
}
// Sleep
sceKernelDelayThread(100000);
}
sceKernelSleepThread();
return 0;
}