AmendHub

Download:

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; }