Using threads and Classes

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

Moderators: cheriff, TyRaNiD

Post Reply
smartie_on_computer
Posts: 28
Joined: Wed May 09, 2007 12:35 pm

Using threads and Classes

Post by smartie_on_computer »

Hey,

Im back again with another annoying problem of mine...

i've created a thread in my program and a class that has private and public members.
the thread is created like this:

Code: Select all

class Camera
{
public:
	Camera();
	~Camera();
	int stop();
	int start();
	int fillBuffer(bool blitToScreen);
	void Init(u8* c_buf,u8* c_work,u32* c_fbuf);
	void destroy();
	bool Started;
	bool Error;
	
	u8* buffer;
private:
	PspUsbCamSetupVideoParam videoparam;
	int LoadModules();
	int UnloadModules();
	int InitCamera();
	int StartUsb();
	int StopUsb();
	int InitJpegDecoder();
	int FinishJpegDecoder();
	bool initiated;

	u8*  work;//[68*1024] __attribute__((aligned(64)));
	u32* framebuffer;//[480*272] __attribute__((aligned(64)));
};

Code: Select all

video_thid = sceKernelCreateThread("video_thread", video_thread, 16, 16*1024, 0, NULL);
	if &#40;video_thid < 0&#41;
	&#123;
		printf&#40;"Cannot create video thread.\n"&#41;;
		//return -1;
	&#125;
	
	if &#40;sceKernelStartThread&#40;video_thid, 0, NULL&#41; < 0&#41;
	&#123;
		printf&#40;"Cannot start video thread.\n"&#41;;
		//return -1;
	&#125;
that works fine, but in the thread, when i call a class member, my psp freezes:

Code: Select all

int video_thread&#40;SceSize args, void *argp&#41;&#123;
	while&#40;true&#41;&#123;
		if&#40;!WebCam.Error && WebCam.Started&#41;&#123;
				if&#40;WebCam.FillBuffer&#40;true&#41;<0&#41;&#123;
					printf&#40;"There was an error filling the buffer...\n"&#41;;  
				&#125;
			&#125;
    	&#125;else if&#40;WebCam.Error&#41;&#123;
			printf&#40;"Webcam Error...\n"&#41;;
			sceKernelDelayThread&#40;50000&#41;;
		&#125;
	&#125;
	sceKernelExitDeleteThread&#40;0&#41;;
	return 0;
&#125;
the program freezes the moment it tries to access 'WebCam.Error' or 'WebCam.Started', i've even tried calling 'WebCam.FillBuffer(true)' and still nothing.

im not 100% clear with threads yet, but i cant see anything going wrong here.

Maybe you guys can see what im doing wrong?
Cheers
Roman
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

You're creating a kernel thread. If you want a user thread, be sure to use PSP_THREAD_ATTR_USER when creating the thread instead of 0. Kernel level stuff can't access user level stuff without setting k1.

Code: Select all

	unsigned int k1;
	k1 = pspSdkSetK1&#40;0&#41;;

	// do stuff here

	pspSdkSetK1&#40;k1&#41;;
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

so if i make a kernel thread in my main eboot does that mean i can access kernel functions
smartie_on_computer
Posts: 28
Joined: Wed May 09, 2007 12:35 pm

Post by smartie_on_computer »

J.F. wrote:You're creating a kernel thread. If you want a user thread, be sure to use PSP_THREAD_ATTR_USER when creating the thread instead of 0. Kernel level stuff can't access user level stuff without setting k1.

Code: Select all

	unsigned int k1;
	k1 = pspSdkSetK1&#40;0&#41;;

	// do stuff here

	pspSdkSetK1&#40;k1&#41;;
i've tried setting K1 and tried PSP_THREAD_ATTR_USER. and my psp still crashes...
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

no you have to do either or not both pspSdkSetK1 if in kernel thread or set the thread to a user thread not both or else your calling a kernel funct in a user thread
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

do you have enoph heap allocated for this thread
smartie_on_computer
Posts: 28
Joined: Wed May 09, 2007 12:35 pm

Post by smartie_on_computer »

yeah i figured that part, but no i didnt do both things at once, im not that stupid to do that lol
smartie_on_computer
Posts: 28
Joined: Wed May 09, 2007 12:35 pm

Post by smartie_on_computer »

coolkehon wrote:do you have enoph heap allocated for this thread
Heap?
smartie_on_computer
Posts: 28
Joined: Wed May 09, 2007 12:35 pm

Post by smartie_on_computer »

im pretty sure the heap size is fine...
the has a small amount of memory because the buffers are pointers to byte arrays defined in the main code. so the heap size should be fine.
smartie_on_computer
Posts: 28
Joined: Wed May 09, 2007 12:35 pm

Post by smartie_on_computer »

Sorry, i will have to excuse myself here.

its working perfectly now, the reason why it was freezing was because i was not delaying the thread so it was looping the thread but not executing anything else.

so it works wonderfully now and thanks for your help J.F. and coolkehon!

Cheers
Roman
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

I just remembered something - creating a thread from a user thread never creates a kernel thread. That's in an old thread too. I was going to suggest bumping the size of the thread's stack. When you create a thread, many people just do it like the examples... which tend to use tiny stacks as the examples don't do much. If you have functions called by the thread with large local arrays, it would be easy to overflow the stack and create a fault. Good to hear you have it working, but check your stack size anyway to make sure it doesn't cause trouble later. :)
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

could you explain what a stack is for me i've seen on other sites but it would be helpful if described in noobs term
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Anytime you call a function, the return address and arguments have to be stored somewhere. The stack is a last-in, first-out buffer (or first-in, last-out) where such things are stored. The function in turn needs a place to save registers that are used by the function, and a place for temporary (local) variables. The stack is used for that as well. So the stack is a block of memory somewhere that is used by the thread for this temporary storage of addresses and registers and arguments and local variables.

The majority of the space is used by local variables. Consider this:

Code: Select all

int foo&#40;int bar&#41;
&#123;
    int myarray&#91;1000&#93;;
    int i;

    for &#40;i=0; i<1000; i++&#41;
        myarray&#91;i&#93; = i*i + 35;

    return myarray&#91;bar&#93;;
&#125;
It's not how you would write such a function, but I'm making a point. The point is that function foo() has a local variable called myarray that needs memory for 1000 ints (4000 bytes). Local variables are on the stack, so when foo() is called, 4000 bytes are taken from the stack for that array. Now suppose you only allocated a block of memory that is 1024 bytes for the stack - you don't have 4000 bytes for myarray.

One of the values you pass to the CreateThread function is the size of the block of memory to allocate for the stack. It is up to you to make sure it's big enough to hold everything needed by the functions called. So if you have arrays as local variables (in particular), be sure to make the stack bigger than the total space they occupy.
Post Reply