//Brett Shwom //Homework 3 //for some reason it doesnt work on macs, but on linux its fine #include //Please make sure that your #include statement is the very first of all your include files. //REASON: other include files may have thread-safe features which are turned on only after pthread.h //has been included. #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define DEBUG FALSE typedef struct {int n1; int n2;} Pair; typedef struct {Pair p; int r;} P_Result; void * Run(void*); void * Run_Worker(void*); int modulo(int, int); void compute_gcd(Pair*); int requestModOperation(Pair*); P_Result pr; int worker_continue = TRUE; pthread_mutex_t main_mv = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t wake_thread = PTHREAD_COND_INITIALIZER; int main (int argc, char* argv[]) { int numOfThreads = (argc - 1) / 2; pthread_t threads[numOfThreads ]; pthread_t workerThread; int rc, t; rc = pthread_create(&workerThread, NULL, Run_Worker, NULL); //create the main thread that will if (rc){ printf("ERROR; return code of pthread_create() is %d\n", rc); exit(-1); } pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); //create threads that are joinable for (t = 1; t < argc; t+=2) { Pair* p = malloc(sizeof(Pair)); //malloc uses the freestore and not the stack //Pair p uses the stack --> which can create concurrency issues //in multithreaded apps p->n1 = atoi(argv[t]); p->n2 = atoi(argv[t+1]); rc = pthread_create(&threads[(t-1)/2], &attr, Run, p); if (rc){ printf("ERROR; return code of pthread_create() is %d\n", rc); exit(-1); } } pthread_attr_destroy(&attr); //destroy the attr object for(t=0; tn1, p->n2); compute_gcd(p); pthread_exit(NULL); } void compute_gcd(Pair* p) { int q, mo; Pair orig; orig.n1 = p->n1; orig.n2 = p->n2; mo = 0; q=requestModOperation(p); while (q != 0) { p->n1 = p->n2; p->n2 = q; q=requestModOperation(p); mo++; } printf("Thread %d: gcd(%d,%d)=%d using %d mod operations\n", pthread_self(), orig.n1, orig.n2, p->n2, mo); } pthread_mutex_t mv = PTHREAD_MUTEX_INITIALIZER; int requestModOperation(Pair* p) { if (DEBUG) printf("Thread #%d Requesting Modulus Operation For %d %d\n", pthread_self(), p->n1, p->n2); int result; pthread_mutex_lock(&mv); //critical section: pr.p = *p; pthread_cond_signal(&wake_thread); //wake worker thread pthread_mutex_lock(&main_mv); //take value after main thread unlocks variable result = pr.r; pthread_mutex_unlock(&main_mv); pthread_mutex_unlock(&mv); return result; } int modulo(int x, int y) { while (x - y >= 0) x-=y; return x; }