#include #include #include "minithread_md.h" #include "minithread.h" #include "minithread_public.h" int atomic_test_and_set(tas_lock_t *l) { int k; disable_interrupts(); k = *l; *l = 1; enable_interrupts(); return k; } void atomic_clear(tas_lock_t *l) { *l = 0; } /* * Internal routine to allocate a stack. */ #ifndef STACKALIGN #define STACKALIGN 03 #endif void minithread_allocate_stack(stackbase, stacktop) stack_pointer_t *stackbase; stack_pointer_t *stacktop; { *stackbase = (stack_pointer_t)malloc(STACKSIZE); if (!*stackbase) { return; } if (STACK_GROWS_DOWN) { /* Stacks grow down, but malloc grows up. Compensate and word align (turn off low 2 bits by anding with ~3). */ *stacktop = (stack_pointer_t) ((ADDR_TO_INT(*stackbase) + STACKSIZE - 1)&~STACKALIGN); } else { /* Word align (turn off low 2 bits by anding with ~3) */ *stacktop = (stack_pointer_t)(( ADDR_TO_INT(*stackbase) + 3)&~STACKALIGN); } } void minithread_free_stack(stackbase) stack_pointer_t stackbase; { free(stackbase); } /* * See the architecture assembly file. */ extern int minithread_root(); /* * Initialize a stack. * Stack frame is set up so that thread calls: * initial_proc(initial_arg); * body_proc(body_arg); * finally_proc(finally_arg); */ void minithread_initialize_stack(stacktop, initial_proc, initial_arg, body_proc, body_arg, finally_proc, finally_arg) stack_pointer_t *stacktop; proc_t initial_proc; arg_t initial_arg; proc_t body_proc; arg_t body_arg; proc_t finally_proc; arg_t finally_arg; { initial_stack_state_t ss; /* * Configure initial machine state so that this thread starts * running inside a wrapper procedure named minithread_root. * minithread_root will invoke the procedures in order, and * then halt. */ *((char **) stacktop) -= sizeof (struct initial_stack_state); ss = (initial_stack_state_t) *stacktop; ss->initial_proc = (void *) initial_proc; ss->initial_arg = (void *) initial_arg; ss->body_proc = (void *) body_proc; ss->body_arg = (void *) body_arg; ss->finally_proc = (void *) finally_proc; ss->finally_arg = (void *) finally_arg; ss->root_proc = (void *) MINITHREAD_ROOT; }