Keep freezing on exit

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

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Keep freezing on exit

Post by wich »

Hi people,

I keep having problems with my app hanging on exit, I get the "Please wait..." screen and it just never quits. I am running 3.03OE-C and FileAssistant++ to launch my elf binary. When I press the start button to quit everything works fine, though I get a screen with some white vertical bars on the left hand side before I get dropped back to FileAssistant++. However when I try to quit the application through the home button exit callback my PSP freezes in the "Please wait..." screen.

I have tried adding the sceKernelDisplayWaitVblankStart() and sceKernelDelayThread(0) before and after sceKernelExitGame() but that didn't change anything. I've tried putting sceKernelExitGame in the exit callback function, but that didn't help. Now I've been trying to gracefully clean up the callback function and threads, but that doesn't seem to relieve the problem either. I've included the code I currently have below, I have run out of ideas and after much searching around on the forums and on google I've concluded I've come to a dead end.

Could anybody say what I'm doing wrong, or what I could do to resolve the issue? Is it a problem of running the program from FileAssistant, or with the 3.03OE-C firmware or am I just missing something completely here?

Code: Select all

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <pspctrl.h>

PSP_MODULE_INFO&#40;"Test v1.0", 0, 1, 1&#41;;
PSP_MAIN_THREAD_ATTR&#40;THREAD_ATTR_USER&#41;;

int done = false;

int exit_callback&#40;int arg1, int arg2, void* common&#41; &#123;
	done = true;
	return 0;
&#125;

int callback_thread&#40;SceSize args, void* argp&#41; &#123;
	int cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, 0&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;

	sceKernelSleepThreadCB&#40;&#41;;

	return cbid;
&#125;

int setup_callbacks&#40;&#41; &#123;
	int thid = sceKernelCreateThread&#40;"update_thread", callback_thread, 0x11, 0xFA0, THREAD_ATTR_USER, 0&#41;;
	if &#40;0 <= thid&#41;
		sceKernelStartThread&#40;thid, 0, 0&#41;;

	return thid;
&#125;

void deinit_callbacks&#40;int thid&#41; &#123;
	sceKernelWakeupThread&#40;thid&#41;;
	sceKernelWaitThreadEnd&#40;thid, 0&#41;;
	int cbid = sceKernelGetThreadExitStatus&#40;thid&#41;;
	//sceKernelUnregisterExitCallback&#40;&#41;;
	sceKernelDeleteCallback&#40;cbid&#41;;
	sceKernelDeleteThread&#40;thid&#41;;
&#125;

int main&#40;int argc, char** argv&#41; &#123;
	SceCtrlData pad;

	int cb_thread = setup_callbacks&#40;&#41;;

	while &#40;!done&#41; &#123;
		sceCtrlReadBufferPositive&#40;&pad, 1&#41;;

		if &#40;pad.Buttons & PSP_CTRL_START&#41;
			done = true;
	&#125;

	deinit_callbacks&#40;cb_thread&#41;;

	sceDisplayWaitVblankStart&#40;&#41;;
	sceKernelExitGame&#40;&#41;;
	sceKernelDelayThread&#40;0&#41;;
	sceKernelExitThread&#40;0&#41;;

	return 0;
&#125;
psp-g++ -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -I/usr/include/freetype2 -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -fno-exceptions -fno-rtti -c -o main.o main.cc
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -L. -L/usr/local/pspdev/psp/sdk/lib main.o -lstdc++ -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o test.elf
Cy-4AH
Posts: 44
Joined: Wed Jan 31, 2007 9:58 pm
Location: Belarus

Post by Cy-4AH »

try without deinit_callback(cb_thread), sceDisplayWaitVblankStart(), sceKernelDelayThread, sceKernelExitThread(0)
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

I did, that's what I started with, only after I found that the program kept freezing in the "Please wait..." screen did I try and add them in an attempt to resolve it.
Cy-4AH
Posts: 44
Joined: Wed Jan 31, 2007 9:58 pm
Location: Belarus

Post by Cy-4AH »

May be when you jast startet there wasn't sceKernelExitGame();
If I have my development evironment right now right here I'd tryed by myself, but for my look there is all correct and you don't need that strang functions at the and. That is 100%.
You can try compare with my code in topic: http://forums.ps2dev.org/viewtopic.php?t=7704. This program exit on "Please wait."
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

I am sure the sceKernelExitGame() was there and that was the only function there. I based this code on Jason Owens' Random Dot Generator code. When I compile that it doesn't properly exit either, it doesn't freeze however, it crashes.
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

Ah I found the problem. When I compile with debugging symbols (-g in CFLAGS) it quits properly, without debugging symbols it keeps hanging at the "Please wait..." screen.
Cy-4AH
Posts: 44
Joined: Wed Jan 31, 2007 9:58 pm
Location: Belarus

Post by Cy-4AH »

Hm, very strange. My program process ExitCallback even without -g flag.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

deinit_callbacks(cb_thread);

that pretty much tells you your problem :P
10011011 00101010 11010111 10001001 10111010
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

Again, I added that in an attempt to resolve the problem, it didn't work without it, it didn't work with it.
Anissian
Posts: 16
Joined: Fri Jan 26, 2007 8:40 pm

Post by Anissian »

Hi,

I'm unsure about what's causing the freeze, but browsing the code I tend to think that the problem may be due to the fact that the "main_thread" is waiting for thread "update_thread" (the one that setup the exit callback) to terminate.

You may already know / have tried this (apologies then), but as the code in your post seems to show:

deinit_callbacks called from main thread, which waits for update thread:

Code: Select all

void deinit_callbacks&#40;int thid&#41; &#123;
   sceKernelWakeupThread&#40;thid&#41;;
   sceKernelWaitThreadEnd&#40;thid, 0&#41;; 
yet the "update" thread just registers the callbacks, and goes to sleep servicing callbacks if needed (in its own context), but as things are, after it is woken up, returns, but doesn't it still exist? (there is no specific "DeleteThread" call). The main thread wakes it and waits for termination with status.

Would adding a

Code: Select all

sceKernelExitDeleteThread &#40;0&#41; 
in the exit callback help things? when the user select home and exits, the callback is called, serviced by the update thread, which deletes self, after setting the flag to true. The main thread waits for its termination (it should not block), and proceeds.

or a more radical approach, where the main thread kills the update thread
using e.g.:

Code: Select all

sceKernelTerminateDeleteThread&#40;thid&#41;;
Hope this helps,
Ani


Edit: on a side note, I have my doubts about the approach where a thread unregisters/deletes callbacks that he did not register, as your main thread seems to be doing.
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

Ok, apparently I am not clear enough.

The 'weird extra code' in my example program, aka deinit_callbacks, is most definately not the cause of my problem. I encountered the problem way before I added the whole deinit_callbacks function. I added deinit_callbacks after I encountered the problem in an attempt to remedy the situation. This didn't work however hence I am here posting my question. Now the posted code works without a problem, but only when I compile the whole code with debugging symbols enabled (e.g.) the -g flag for gcc. I experience the problem only when I compile without debugging symbols.

Please read my explanation extra carefully and try to understand what my problem is because I am apparently not getting it accross properly. Again please don't think that the 'weird extra code' in my program is the cause of the problem, again the problem started way before I added all that stuff.

Also, the program exits fine if I directly quit the main loop by pressing the Start button, so I know the WakupThread and WaitThreadEnd calls work correctly. Things go wrong when I quit through the callback function by way of the Home button.

@Anissian: Interesting observation on the unregister and delete callback function being called in another thread. I will investigate this, but it cannot be the cause of the freezing on exit on itself, because the freezing already happened before I added these calls to the program.

btw, I tried the TerminateDeleteThread method, but that didn't resolve the problem.
Cy-4AH
Posts: 44
Joined: Wed Jan 31, 2007 9:58 pm
Location: Belarus

Post by Cy-4AH »

Ok, wich. There is source. At my 3.03OE-C all working like you want:
wich.cpp:

Code: Select all

#include <pspkernel.h> 
#include <pspdisplay.h> 
#include <pspdebug.h> 
#include <pspctrl.h> 

PSP_MODULE_INFO&#40;"Test v1.0", 0, 1, 1&#41;; 
PSP_MAIN_THREAD_ATTR&#40;THREAD_ATTR_USER&#41;; 

int done = false; 

int exit_callback&#40;int arg1, int arg2, void* common&#41; &#123; 
   done = true; 
   return 0; 
&#125; 

int callback_thread&#40;SceSize args, void* argp&#41; &#123; 
   int cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, 0&#41;; 
   sceKernelRegisterExitCallback&#40;cbid&#41;; 

   sceKernelSleepThreadCB&#40;&#41;; 

   return cbid; 
&#125; 

int setup_callbacks&#40;&#41; &#123; 
   int thid = sceKernelCreateThread&#40;"update_thread", callback_thread, 0x11, 0xFA0, THREAD_ATTR_USER, 0&#41;; 
   if &#40;0 <= thid&#41; 
      sceKernelStartThread&#40;thid, 0, 0&#41;; 

   return thid; 
&#125; 

/*void deinit_callbacks&#40;int thid&#41; &#123; 
   sceKernelWakeupThread&#40;thid&#41;; 
   sceKernelWaitThreadEnd&#40;thid, 0&#41;; 
   int cbid = sceKernelGetThreadExitStatus&#40;thid&#41;; 
   //sceKernelUnregisterExitCallback&#40;&#41;; 
   sceKernelDeleteCallback&#40;cbid&#41;; 
   sceKernelDeleteThread&#40;thid&#41;; 
&#125;*/ 

int main&#40;int argc, char** argv&#41; &#123; 
   SceCtrlData pad; 

   int cb_thread = setup_callbacks&#40;&#41;; 

   while &#40;!done&#41; &#123; 
      sceCtrlReadBufferPositive&#40;&pad, 1&#41;; 

      if &#40;pad.Buttons & PSP_CTRL_START&#41; 
         done = true; 
   &#125; 

/*   deinit_callbacks&#40;cb_thread&#41;; 

   sceDisplayWaitVblankStart&#40;&#41;;*/ 
   sceKernelExitGame&#40;&#41;; 
/*   sceKernelDelayThread&#40;0&#41;; 
   sceKernelExitThread&#40;0&#41;;*/ 

   return 0; 
&#125;
makefile:

Code: Select all

TARGET = wich
OBJS = wich.o

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = wich

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

Ok, now this is complete voodoo magic...

I compiled the code you posted with the 'weird extra code' commented out, and as I expected, because that was the code I began with, it didn't quit when I ran the elf binary from within File Assistant++. I then tried to run the program as an EBOOT.PBP and again it didn't quit properly.

Then I went back to my original program which now also contains other code besides the basic framework, removed the 'weird extra code' there and tried the elf binary and it worked! There was much rejoicing!

Then I plugged the 'weird extra code' back into my program and it still worked. Then I tried the same elf binary as I tried before of the code you posted and now it works also!

So well, I'm kinda stumped. I'm sort of happy that the callback exit functions seem to work now, but I have no idea what fixed it... Apparently the 'weird extra code' is not the cause of the problem as I expected, because that keeps working happily now in my original program. Somehow running the eboot.pbp changed something, maybe it's the memory stick layout, maybe it's some kernel state, I have no idea what, but something changed and then it suddenly worked.

I am however afraid that if it is something of a state or whatever in the kernel or maybe memory stick layout or whatever, then that means that the problem might come back. I'll keep an eye out for the problem and keep note of what I'm doing with my psp in the meantime. Hopefully this was a onetime deal and I won't see the problem again...
Cy-4AH
Posts: 44
Joined: Wed Jan 31, 2007 9:58 pm
Location: Belarus

Post by Cy-4AH »

Hm. Now all I know, that problem not in code. Problem must be in your PSP. Maybe it's FileAssistant++ or maybe it's becouse of no-umd mode. Is it enabled?
User avatar
wich
Posts: 13
Joined: Wed Feb 14, 2007 6:05 am

Post by wich »

No, No-umd mode is not enabled.
Post Reply