Index: include/sthread.h =================================================================== RCS file: /homes/gws/rick/cvs/cse451/simplethreads/include/sthread.h,v retrieving revision 1.3 retrieving revision 1.4 diff -c -r1.3 -r1.4 *** include/sthread.h 17 Jan 2004 21:21:35 -0000 1.3 --- include/sthread.h 29 Jan 2004 03:45:34 -0000 1.4 *************** *** 26,34 **** /* Return the implementation that was selected at compile time. */ sthread_impl_t sthread_get_impl(void); ! /* Choose the implementation to use: pthreads or user-level threads. ! * Perform any initialization needed. Should be called before any ! * other sthread functions (sthread_print_impl is excepted). */ void sthread_init(); --- 26,35 ---- /* Return the implementation that was selected at compile time. */ sthread_impl_t sthread_get_impl(void); ! /* ! * Perform any initialization needed. Should be called exactly ! * once, before any other sthread functions (sthread_get_impl ! * excepted). */ void sthread_init(); Index: lib/sthread_ctx.c =================================================================== RCS file: /homes/gws/rick/cvs/cse451/simplethreads/lib/sthread_ctx.c,v retrieving revision 1.8 retrieving revision 1.9 diff -c -r1.8 -r1.9 *** lib/sthread_ctx.c 17 Jan 2004 21:17:34 -0000 1.8 --- lib/sthread_ctx.c 29 Jan 2004 03:45:04 -0000 1.9 *************** *** 88,104 **** free(ctx); } /* Save the currently running thread context into old, and * start running the context new. Old may be uninitialized, * but new must contain a valid saved context. */ void sthread_switch(sthread_ctx_t *old, sthread_ctx_t *new) { /* Call the assembly */ ! Xsthread_switch(&(old->sp), new->sp); ! ! /* Do not put anything here. In some cases (namely, the * first time a new thread is run), _sthread_switch does * not return to this line. (It instead returns to the * start function set when the stack was initialized.) */ } - --- 88,114 ---- free(ctx); } + /* Avoid allowing the compiler to optimize the call to + * Xsthread_switch as a tail-call on architectures that support + * that (powerpc). */ + void sthread_anti_optimize(void) __attribute__ ((noinline)); + void sthread_anti_optimize() { + } + /* Save the currently running thread context into old, and * start running the context new. Old may be uninitialized, * but new must contain a valid saved context. */ void sthread_switch(sthread_ctx_t *old, sthread_ctx_t *new) { /* Call the assembly */ ! if (old != new) ! Xsthread_switch(&(old->sp), new->sp); ! /* Do not put anything useful here. In some cases (namely, the * first time a new thread is run), _sthread_switch does * not return to this line. (It instead returns to the * start function set when the stack was initialized.) + * + * sthread_anti_optimize just forces gcc not to optimize + * the call to Xsthread_switch. */ + sthread_anti_optimize(); }