Thread creation problem
Thread creation problem
I've been having some problems creating threads. It seems that sometimes when a thread is created, the OS will immediately kill it (before it even gets to the thread's entry point as far as I can tell.),
I can reproduce the problem with some pretty straightforward test code, which is included below. Basically, what I'm doing is:
In the main context:
1. Set test value to 0.
2. Create and start thread 'n'
3. Wait for thread 'n' to end.
4. Check that test value was set to 1.
5. Repeat...
In thread context:
1. Set test value to 1.
2. Exit and delete thread.
What eventually happens is that the check in main (#4) fails. Doing a 'thinfo' from PSPLINK gives the following output, which seems to indicate that the OS killed the thread:
UID: 0x04E1F74B - Name: thread29
Attr: 0x800000FF - Status: 32/KILLED - Entry: 89004d8
Stack: 9ff7c00 - StackSize 0x00000400 - GP: 0x08917B80
InitPri: 17 - CurrPri: 17 - WaitType 0
WaitId: 0x00000000 - WakeupCount: 0 - ExitStatus: 0x800201A2
RunClocks: 48155 - IntrPrempt: 1 - ThreadPrempt: 0
ReleaseCount: 0, StackFree: 640
When this happens is fairly unpredictable - sometimes it will die after just a few threads, sometimes it will make it a few hundred. I haven't been able to discern much of a pattern. I've added delays in various places (in case it was caused by some sort of race condition) but this didn't seem to have any effect.
Considering I have zero visibility into the PSP OS (and relatively little experience with it) I'm kinda stuck at this point, so I'm looking for help... Am I doing something incredibly stupid? Has anyone else run into a similar problem?
Thanks!
Test code:
int washere;
int func(SceSize argc,void * argv)
{
printf("func\n");
washere = 1;
sceKernelExitDeleteThread(0);
return 0;
}
int main()
{
int i;
pspDebugScreenInit();
SetupCallbacks();
printf("Starting test\n");
for (i=0; i<1000; i++)
{
char threadName[32];
printf("%d\n",i);
washere = 0;
sprintf(threadName,"thread%d\n",i);
int thid =
sceKernelCreateThread(threadName,
func,
0x11,
1024,
0,
NULL);
sceKernelStartThread(thid, 0, 0);
sceKernelWaitThreadEnd(thid, NULL);
if (washere != 1)
{
printf("Failure!\n");
return 0;
}
}
printf("Done\n");
return 0;
}
I can reproduce the problem with some pretty straightforward test code, which is included below. Basically, what I'm doing is:
In the main context:
1. Set test value to 0.
2. Create and start thread 'n'
3. Wait for thread 'n' to end.
4. Check that test value was set to 1.
5. Repeat...
In thread context:
1. Set test value to 1.
2. Exit and delete thread.
What eventually happens is that the check in main (#4) fails. Doing a 'thinfo' from PSPLINK gives the following output, which seems to indicate that the OS killed the thread:
UID: 0x04E1F74B - Name: thread29
Attr: 0x800000FF - Status: 32/KILLED - Entry: 89004d8
Stack: 9ff7c00 - StackSize 0x00000400 - GP: 0x08917B80
InitPri: 17 - CurrPri: 17 - WaitType 0
WaitId: 0x00000000 - WakeupCount: 0 - ExitStatus: 0x800201A2
RunClocks: 48155 - IntrPrempt: 1 - ThreadPrempt: 0
ReleaseCount: 0, StackFree: 640
When this happens is fairly unpredictable - sometimes it will die after just a few threads, sometimes it will make it a few hundred. I haven't been able to discern much of a pattern. I've added delays in various places (in case it was caused by some sort of race condition) but this didn't seem to have any effect.
Considering I have zero visibility into the PSP OS (and relatively little experience with it) I'm kinda stuck at this point, so I'm looking for help... Am I doing something incredibly stupid? Has anyone else run into a similar problem?
Thanks!
Test code:
int washere;
int func(SceSize argc,void * argv)
{
printf("func\n");
washere = 1;
sceKernelExitDeleteThread(0);
return 0;
}
int main()
{
int i;
pspDebugScreenInit();
SetupCallbacks();
printf("Starting test\n");
for (i=0; i<1000; i++)
{
char threadName[32];
printf("%d\n",i);
washere = 0;
sprintf(threadName,"thread%d\n",i);
int thid =
sceKernelCreateThread(threadName,
func,
0x11,
1024,
0,
NULL);
sceKernelStartThread(thid, 0, 0);
sceKernelWaitThreadEnd(thid, NULL);
if (washere != 1)
{
printf("Failure!\n");
return 0;
}
}
printf("Done\n");
return 0;
}
-
- Posts: 5
- Joined: Sun Dec 10, 2006 3:12 am
I verified that threads were actually getting created.
When it originally stopped at 30 threads, I thought the same thing, that I was running into some kind of limit (possibly because I wasn't deleting threads). However, the point at which it stops is somewhat random, and often goes above 30.
I have figured something out: the problem goes away if I increase the stack size to 4K. I had originally set the stack size to 1K, because I figured it didn't really matter, as I wasn't doing a whole lot in the thread. I am calling printf, which could have a pretty deep call stack, but even then, it still surprises me.
Assuming that the problem was that I was blowing away a thread's stack, a lesson learned (for me at least) is that the thread info display in psplink won't necessarily show this. That is, if you look at the thread that was killed, it showed that only around 300 bytes of the stack was being used...
When it originally stopped at 30 threads, I thought the same thing, that I was running into some kind of limit (possibly because I wasn't deleting threads). However, the point at which it stops is somewhat random, and often goes above 30.
I have figured something out: the problem goes away if I increase the stack size to 4K. I had originally set the stack size to 1K, because I figured it didn't really matter, as I wasn't doing a whole lot in the thread. I am calling printf, which could have a pretty deep call stack, but even then, it still surprises me.
Assuming that the problem was that I was blowing away a thread's stack, a lesson learned (for me at least) is that the thread info display in psplink won't necessarily show this. That is, if you look at the thread that was killed, it showed that only around 300 bytes of the stack was being used...
Yes the problem should come from something like that.
Because there are only two threads running simultanously (so not too many ressources at same time), the exit-deletion is correct, and if you increase the stack size it works properly.
Even the unsecure access of "washere" should not be a problem as the two threads can't access it at the same time.
And moreover, if I remove the printf, it works properly even only with a 512b stack.
Because there are only two threads running simultanously (so not too many ressources at same time), the exit-deletion is correct, and if you increase the stack size it works properly.
Even the unsecure access of "washere" should not be a problem as the two threads can't access it at the same time.
And moreover, if I remove the printf, it works properly even only with a 512b stack.
--pspZorba--
NO to K1.5 !
NO to K1.5 !
Stack overflows... the bane of programmers everywhere. Of course, if it weren't for SOs, we probably wouldn't have homebrew on some consoles. :)pspZorba wrote:Yes the problem should come from something like that.
Because there are only two threads running simultanously (so not too many ressources at same time), the exit-deletion is correct, and if you increase the stack size it works properly.
Even the unsecure access of "washere" should not be a problem as the two threads can't access it at the same time.
And moreover, if I remove the printf, it works properly even only with a 512b stack.
Unfortunately psplink can only report what the kernel knows about, if you lash up an SIO cable and enable serial kprintf you will actually get the kernel's I'm fucked output which gives a clearer indication. You can also try doing thctx @thread which might print out the final registers as the context switch is what triggers the overflow handler (although at this point the thread could have walked over god knows how much memory :P)