Threading

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Threading

Post by slasher2661996 »

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
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

Then how can i make the psp `freeze`?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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.
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

Well how come Torch can do it in Lockdown?
If you read this Torch can you help :D
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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.
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

the ingame lockdown does `freeze` it cause when you un-sleep your psp it runs while the game is frozen in the background
roe-ur-boat
Posts: 5
Joined: Wed Aug 22, 2007 4:54 am

Post by roe-ur-boat »

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.
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

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.
NoEffex
Posts: 106
Joined: Thu Nov 27, 2008 6:48 am

Post by NoEffex »

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
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

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.
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

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: Select all

 sceKernelGetThreadmanIdList
It's the only function that look like it retrieves the uid's.
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

Anyone?
qbradq
Posts: 4
Joined: Mon May 04, 2009 5:00 am

Post by qbradq »

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: Select all

#include <pspkernel.h>
#include <pspctrl.h>
#include <stdio.h>
#include <pspthreadman.h>

PSP_MODULE_INFO&#40;"pspetext", 0x1000, 0, 0&#41;;
PSP_HEAP_SIZE_KB&#40;64&#41;;

SceUID uids&#91;64&#93;;
int uids_num;
SceUID runingUids&#91;256&#93;;
int runingUids_num;

int main&#40;int argc, char **argv&#41;
&#123;
	int padTime = 0;
	int i, j;
	SceCtrlData pad;

	debugPrintf&#40;"Begining of Main Thread Execution\n"&#41;;

	/*
	 * Here is where I list all running thread IDs.
	 */
	if&#40;sceKernelGetThreadmanIdList&#40;SCE_KERNEL_TMID_Thread,
		uids, 64, &uids_num&#41; < 0&#41;
	&#123;
		printf&#40;"sceKernelGetThreadmanIdList&#40;&#41; failed.\n"&#41;;
	&#125;

	while&#40;1&#41;
	&#123;
		// Read the controls and update the timer
		sceCtrlPeekBufferPositive&#40;&pad, 1&#41;;
		if&#40;pad.Buttons & PSP_CTRL_LTRIGGER &&
			pad.Buttons & PSP_CTRL_RTRIGGER&#41;
		&#123;
			padTime ++;
		&#125;
		else padTime = 0;

		// If the time has come trigger off the application
		if&#40;padTime >= 10&#41;
		&#123;
			// Suspend all game threads &#40;or at least threads that did not exist before we did&#41;
			if&#40;sceKernelGetThreadmanIdList&#40;SCE_KERNEL_TMID_Thread,
				runingUids, 256, &runingUids_num&#41; < 0&#41;
			&#123;
				debugPrintf&#40;"sceKernelGetThreadmanIdList&#40;&#41; failed.\n"&#41;;
			&#125;
			else
			&#123;
				for&#40;i = 0; i < runingUids_num; i ++&#41;
				&#123;
					int found;
					found = 0;
					for&#40;j = 0; j < uids_num; j ++&#41;
					&#123;
						if&#40;uids&#91;j&#93; == runingUids&#91;i&#93;&#41; found = 1;
					&#125;
					if&#40;found == 0&#41;
					&#123;
						if&#40;sceKernelSuspendThread&#40;runingUids&#91;i&#93;&#41; < 0&#41;
						&#123;
							debugPrintf&#40;"Unable to suspend thread %d\n", runingUids&#91;i&#93;&#41;;
						&#125;
						else
						&#123;
							debugPrintf&#40;"Suspended thread %d\n", runingUids&#91;i&#93;&#41;;
						&#125;
					&#125;
					else
					&#123;
						debugPrintf&#40;"Skipping thread %d\n", runingUids&#91;i&#93;&#41;;
					&#125;
				&#125;
			&#125;

			// Execute PSPEText main function
			petMain&#40;&#41;;
			padTime = 0;

			// Resume all threads suspended earlier
			for&#40;i = 0; i < runingUids_num; i ++&#41;
			&#123;
				int found;
				found = 0;
				for&#40;j = 0; j < uids_num; j ++&#41;
				&#123;
					if&#40;uids&#91;j&#93; == runingUids&#91;i&#93;&#41; found = 1;
				&#125;
				if&#40;found == 0&#41;
				&#123;
					if&#40;sceKernelResumeThread&#40;runingUids&#91;i&#93;&#41; < 0&#41;
					&#123;
						debugPrintf&#40;"Unable to resume thread %d\n", runingUids&#91;i&#93;&#41;;
					&#125;
					else
					&#123;
						debugPrintf&#40;"Resuming thread %d\n", runingUids&#91;i&#93;&#41;;
					&#125;
				&#125;
				else
				&#123;
					debugPrintf&#40;"Skipping thread %d\n", runingUids&#91;i&#93;&#41;;
				&#125;
			&#125;
		&#125;

		// Sleep
		sceKernelDelayThread&#40;100000&#41;;
	&#125;

	sceKernelSleepThread&#40;&#41;;

	return 0;
&#125;
Post Reply