jcs
/subtext
/amendments
/26
uthread: Fix stack issue in uthread_begin
The uthread variable on the stack will get overwritten as soon as
uthread_yield is called, so use uthread_current after the uthread
function returns
Also prevent uthread_yield from being erroneously called from main
loop
jcs made amendment 26 over 2 years ago
--- uthread.c Tue Dec 7 13:47:59 2021
+++ uthread.c Sun Dec 12 13:07:13 2021
@@ -65,6 +65,12 @@ void
uthread_yield(void)
{
volatile long magic = CANARY;
+
+ if (uthread_current == NULL) {
+ printf("uthread_yield not from a thread!\n");
+ ExitToShell();
+ return;
+ }
if (uthread_current->state != UTHREAD_STATE_SLEEPING)
uthread_current->state = UTHREAD_STATE_YIELDING;
@@ -94,18 +100,20 @@ uthread_msleep(unsigned long millis)
void
uthread_begin(struct uthread *uthread)
{
- register long stack = STACK_SIZE * (uthread->id + 2);
+ register long stack_offset = STACK_SIZE * (uthread->id + 2);
asm {
- movea.l stack, a0
+ movea.l stack_offset, a0
sub.w a0, a7
};
-
+
uthread->func(uthread, uthread->arg);
- if (uthread->state == UTHREAD_STATE_REPEAT)
- uthread->state = UTHREAD_STATE_SETUP;
+ /* uthread variable is probably trashed at this point */
+
+ if (uthread_current->state == UTHREAD_STATE_REPEAT)
+ uthread_current->state = UTHREAD_STATE_SETUP;
else
- uthread->state = UTHREAD_STATE_DEAD;
+ uthread_current->state = UTHREAD_STATE_DEAD;
longjmp(uthread_coord_env, UTHREAD_SETJMP_YIELDED);
}
@@ -145,4 +153,6 @@ uthread_coordinate(void)
ExitToShell();
}
}
+
+ uthread_current = NULL;
}