/* ---------------------------------------------------------------- */ /* FILE bridge.c */ /* This program solves the bridge-crossing problem using monitor */ /* ---------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <thread.h> #include "bridge-m.h" #define MAX_CROSSING 20 #define BIG ((double) 0x7FFF) #define MAX_THREADS 20 mutex_t Screen; mutex_t RandomNumber; int Max_Run; /* ---------------------------------------------------------------- */ /* FUNCTION Filler(): */ /* This function fills a char array with spaces. */ /* ---------------------------------------------------------------- */ void Filler(char x[], int n) { int i; for (i = 0; i < n*2; i++) x[i] = ' '; x[i] = '\0'; } /* ---------------------------------------------------------------- */ /* FUNCTION OneVehicle(): */ /* This function simulates a vehicle crossing the bridge. */ /* ---------------------------------------------------------------- */ void *OneVehicle(void *voidPTR) { int *intPTR = (int *) voidPTR; int ID = *intPTR; int Direction; char *Dir[2] = { "<--", "-->" }; char space[200]; int i; double D; Filler(space, ID); mutex_lock(&Screen); printf("%sVehicle %d started ...\n", space, ID); mutex_unlock(&Screen); for (i = 1; i <= Max_Run; i++) { /* for each crossing */ thr_yield(); /* rest for a while */ mutex_lock(&RandomNumber); /* lock random # generator */ D = rand() / BIG; /* generate a random number */ mutex_unlock(&RandomNumber); /* release random # gen. */ Direction = (D <= 0.5) ? 0 : 1; /* which direction? */ mutex_lock(&Screen); printf("%sVehicle %d (%d) arrives at the bridge in " "direction %s\n", space, ID, i, Dir[Direction]); mutex_unlock(&Screen); ArriveBridge(Direction); /* arrive at the bridge */ mutex_lock(&Screen); printf("%sVehicle %d (%d) crosses the bridge\n", space, ID, i); mutex_unlock(&Screen); thr_yield(); /* crossing the bridge */ ExitBridge(Direction); /* exit the bridge */ mutex_lock(&Screen); printf("%sVehicle %d (%d) is done\n", space, ID, i); mutex_unlock(&Screen); } mutex_lock(&Screen); printf("%sVehicle %d is gone forever ...\n", space, ID); mutex_unlock(&Screen); thr_exit(0); } /* ----------------------------------------------------------------- */ /* The main program */ /* ----------------------------------------------------------------- */ void main(int argc, char *argv[]) { thread_t ID[MAX_THREADS]; /* vehicle ID */ size_t Status[MAX_THREADS]; /* vehicle status */ int Arg[MAX_THREADS]; /* vehicle argument */ int Threads; /* # of vehicles */ int i; if (argc != 3) { printf("Use %s #-of-iterations #-of-vehicles\n", argv[0]); exit(0); } Max_Run = abs(atoi(argv[1])); Threads = abs(atoi(argv[2])); if (Threads > MAX_THREADS) { printf("The no. of vehicles is too large. Reset to %d\n", MAX_THREADS); Threads = MAX_THREADS; } printf("Parent started ...\n"); mutex_init(&Screen, USYNC_THREAD, (void *) NULL); BridgeInit(); srand((unsigned) time(NULL)); for (i = 0; i < Threads; i++) { /* start vehicles */ Arg[i] = i+1; thr_create(NULL, 0, OneVehicle, (void *) &(Arg[i]), 0, (void *) &(ID[i])); } for (i = 0; i < Threads; i++) /* wait for vehicles */ thr_join(ID[i], 0, (void *) &(Status[i])); printf("Parent exits ...\n"); }