AmendHub

Download:

jcs

/

subtext

/

amendments

/

626

uthread: Add hooks for checking uthread canaries on every function


jcs made amendment 626 8 months ago
--- uthread.c Fri Dec 12 16:41:21 2025 +++ uthread.c Mon Dec 15 21:41:20 2025 @@ -14,6 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#pragma options(!profile) + #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -34,6 +36,8 @@ struct uthread *uthread_current = NULL; unsigned long uthread_main_canary; void uthread_begin(struct uthread *uthread); +void _profile_(unsigned char *); +static void * profile_exit(void); /* * | A5 world | @@ -122,6 +126,7 @@ uthread_add(void *func, void *arg) return NULL; } +#pragma nooptimize(uthread_begin) void uthread_begin(struct uthread *uthread) { @@ -147,6 +152,7 @@ uthread_begin(struct uthread *uthread) longjmp(uthread_coord_env, UTHREAD_SETJMP_YIELDED); } +#pragma nooptimize(uthread_yield) void uthread_yield(void) { @@ -161,15 +167,6 @@ uthread_yield(void) if (uthread_current == NULL) panic("uthread_yield not from a thread!"); - if (_sp > uthread_current->stack_top || - _sp < uthread_current->stack_bottom) - panic("thread %d stack pointer out of bounds [SP=0x%lx] " - "[top=0x%lx] [bottom=0x%lx]", uthread_current->id, _sp, - uthread_current->stack_top, uthread_current->stack_bottom); - - if (uthread_current->stack_top - _sp > ((UTHREAD_STACK_SIZE * 9) / 10)) - warn("thread %d stack usage >= 90%%", uthread_current->id); - if (uthread_current->state != UTHREAD_STATE_SLEEPING) uthread_current->state = UTHREAD_STATE_YIELDING; @@ -259,10 +256,61 @@ uthread_verify(void) if (*(unsigned long *)uthreads[i].stack_canary != UTHREAD_CANARY) warn("thread %d stack canary died", i); - if (uthread_current && uthread_current == &uthreads[i]) { - if (uthread_current->stack_top - _sp > - ((UTHREAD_STACK_SIZE * 9) / 10)) - warn("thread %d stack usage >= 90%%", uthread_current->id); - } } -} \ No newline at end of file +} + +static struct stack { + unsigned long ret[64]; + unsigned depth; +} uthread_stacks[NUM_UTHREADS + 1] = { 0 }; + +void +_profile_(unsigned char *fname) +{ + register struct stack *s; + register unsigned long *ret; + + if (uthread_current) + s = &uthread_stacks[uthread_current->id]; + else + s = &uthread_stacks[NUM_UTHREADS]; + + ret = &s->ret[s->depth++]; + + asm { + movea.l (a6),a0 + move.l 4(a0),(ret) + lea @exit,a1 + move.l a1,4(a0) + } + + return; + + /* the profiled function will return here */ +exit: + asm { + move.l d0,-(sp) ; preserve result + jsr profile_exit + movea.l d0,a0 ; real return address + move.l (sp)+,d0 ; restore result + jmp (a0) ; return + } +} + +static void * +profile_exit(void) +{ + register struct stack *s; + unsigned long *ret; + + if (uthread_current) + s = &uthread_stacks[uthread_current->id]; + else + s = &uthread_stacks[NUM_UTHREADS]; + + ret = &s->ret[--s->depth]; + + uthread_verify(); + + return (void *)*ret; +}