#include "stdinc.h" #include "uth.h" // // Purpose: Like mileB.c except main calls uth_join to detect thread // termination. // 2 threads independently compute fibonacci numbers but yield // to each other after every every other iteration // (i.e., no preemption) // Usage: mileB // Notes: none // Functions: uth_init, uth_create, uth_yield, uth_exit, uth_join, uth_self // 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 |-- const int nworkers = 2; // # fibFiber const int TickSz = 0; // tick size (msec); 0 ==> no clock // --| globals |-- int debug = 0; // --| 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 (tid %d), n = %d\n", whoami, uth_self(), 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 ) { Tab(1+whoami); 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 ); uth_exit( b ); } // --| root of all evil |-- int main(void) { th_arg_t fibArg[nworkers]; uth_tid_t tid[nworkers]; int result; int debug; setlinebuf(stdout); printf( "+ BEGIN: Parent fiber\n" ); uth_init( nworkers+1, TickSz, debug = 1 ); for (int i=0; i