| View previous topic :: View next topic |
| Author |
Message |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Sat Apr 18, 2009 6:05 pm Post subject: 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 |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Apr 18, 2009 6:08 pm Post subject: |
|
|
The PSP uses cooperative multitasking. As long as the running thread doesn't call something that waits, all other threads are paused.
It's not pausing the threads, but NOT pausing the threads that gets most programmers. :D |
|
| Back to top |
|
 |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Sun Apr 19, 2009 1:34 pm Post subject: |
|
|
| Then how can i make the psp `freeze`? |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Apr 19, 2009 3:50 pm Post subject: |
|
|
| Call the function to disable ints and then don't call anything that waits. Of course, making the PSP "freeze" for an extended period of time may make it crash. The PSP isn't designed for such a thing. At most, you're supposed to merely freeze your own code, not the whole PSP. |
|
| Back to top |
|
 |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Sun Apr 19, 2009 4:23 pm Post subject: |
|
|
Well how come Torch can do it in Lockdown?
If you read this Torch can you help :D |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Mon Apr 20, 2009 2:07 pm Post subject: |
|
|
| Lockdown doesn't "freeze" the PSP, it just runs something before the normal boot or before the normal XMB load. That something runs like normal, but doesn't exit without the correct code. |
|
| Back to top |
|
 |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Mon Apr 20, 2009 4:11 pm Post subject: |
|
|
| the ingame lockdown does `freeze` it cause when you un-sleep your psp it runs while the game is frozen in the background |
|
| Back to top |
|
 |
roe-ur-boat
Joined: 22 Aug 2007 Posts: 5
|
Posted: Mon Apr 20, 2009 6:27 pm Post subject: |
|
|
| I think by freeze you mean pausing all threads but your own. If that's the case then refer to J.Fs post saying how threads are paused. |
|
| Back to top |
|
 |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Mon Apr 20, 2009 7:35 pm Post subject: |
|
|
Yes, but i want to know what functions to use and how to use them.
I have read his posts very thoroughly and they still don't answer my quesitons. |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Tue Apr 21, 2009 11:30 am Post subject: |
|
|
All the documentation is in the pspsdk headers..It's one of the ones that are fully explained, pretty much. _________________ Programming with:
Geany + Latest PSPSDK from svn |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Apr 21, 2009 1:15 pm Post subject: |
|
|
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. |
|
| Back to top |
|
 |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Tue Apr 21, 2009 4:01 pm Post subject: |
|
|
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:
| Code: | | sceKernelGetThreadmanIdList |
It's the only function that look like it retrieves the uid's. |
|
| Back to top |
|
 |
slasher2661996
Joined: 22 Feb 2009 Posts: 91 Location: Melbourne Australia ZOMG
|
Posted: Sat Apr 25, 2009 12:07 pm Post subject: |
|
|
| Anyone? |
|
| Back to top |
|
 |
qbradq
Joined: 04 May 2009 Posts: 4
|
Posted: Mon May 04, 2009 5:12 am Post subject: |
|
|
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.
| Code: |
#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;
}
|
|
|
| Back to top |
|
 |
|