#include "stdinc.h" #include "uth.h" // // Purpose: 2 threads independently compute fibonacci numbers but yield // to each other after every other iteration (i.e., no preemption) // Usage: mileA // Notes: none // Functions: uth_init, uth_create, uth_yield, uth_exit // Features: no high-priority threads // History: // o 3 Apr 2007 kenw: creation // typedef void (func_t)(void); // 0-arg function struct th_arg { int id; int n; }; typedef struct th_arg th_arg_t; // --| constants |-- //XXX const int nworkers = 1; // # fibFiber const int nworkers = 2; // # fibFiber const int TickSz = 0; // tick size (msec); 0 ==> no clock // --| globals |-- int debug = 0; uth_tid_t worker[nworkers]; int done[nworkers]; // done[i] = 1 when thrd i is done int result[nworkers]; // result[i] = fib from thrd i // --| fib thread |-- // compute fibonacci number // fib(5) = fib(4) + fib(3) // = fib (3) + fib(2) + fib(2) + fib(1) // = fib (2) + fib(1) + fib(2) + fib(2) + fib(1) // = fib (1) + fib(1) + fib(1) + fib(1) + fib(1) + 3 fib(0) // = 5 void fibFiber( void *myarg ) { int whoami = ((th_arg_t *)myarg)->id; int n = ((th_arg_t *)myarg)->n; int ncall = 0; int a, b, tmp; printf( "+ BEGIN fibFiber %d, n = %d\n", whoami, n ); if ( n == 0) b = 0; else { a = 0; b = 1; for (int i=1; i>> fibFiber %d: ncall = %d, i = %d, a = %d, b = %d\n", whoami, ncall, i, a, b ); if ( (++ncall)%2 == 1 ) { printf( "+++ fibFiber %d yielding: ncall = %d, i = %d, a = %d, b = %d\n", whoami, ncall, i, a, b ); uth_yield(); } } } printf( "+ END fibFiber %d with fib(%d) = %d\n", whoami, n, b ); done[whoami] = 1; result[whoami] = b; uth_exit( b ); } // --| root of all evil |-- int main(void) { th_arg_t fibArg[nworkers]; int ndone = 0; int debug; setlinebuf(stdout); uth_init( nworkers+1, TickSz, debug = 1 ); for (int i=0; i