#include #include #include #include #include #include #include #define TOTAL_PLATES 10 #define ITEMS_PER_PLATE 20 #define TRIPS_PER_GUEST 5 #define MODE_DEADLOCK 0 #define MODE_SINGLE 1 #define MODE_MULTI 2 #define MODE_FAIR 3 /* mode - The mode of the simulation, either, MODE_DEADLOCK, MODE_SINGLE, and so forth. You need this in order to implement the right behavior in the monitor. */ static int mode; /* nthreads - The total number of threads in the simulation. You might find this value useful for keeping track of threads. */ static int nthreads; /* The plate[] array records the number of items on each plate. */ /* This global variable should be carefully protected by a monitor. */ static int plates[TOTAL_PLATES]; /* buffet_get() is called by each guest to get items from one plate on the buffet. Note that each guest will call buffet_get several times as he/she walks the buffet line. The arguments are as follows: plate - the number of the plate to modify amount - the number of items to get thread_id - the ID of the calling thread */ /* Note that this implementation of buffet_get is terrible. It is broken in three distinct ways: 1 - It doesn't synchronize access to the plate array. 2 - It busy waits when no resources are available. 3 - It doesn't prevent deadlock. */ void buffet_get( int plate, int amount, int thread_id ) { if(mode==MODE_DEADLOCK) { while(plates[plate]5) { fprintf(stderr,"*** THREAD %d DIED OF STARVATION ***\n",threadid); exit(1); } wait_a_while(); } wait_a_while(); for(j=start;j!=stop;j+=direction) { printf("guest %d: returning %d items to plate %d\n",threadid,request[j],j); buffet_put(j,request[j],threadid); } printf("guest %d: all done with trip %d\n",threadid,i); } return 0; } /* The main function examines the command line arguments, selects the running mode, then creates one thread for every guest in the simulation. It knows that the simulation is done when pthread_join succeeds for every thread in the simulation. At the very end, it checks to make sure that all items have been returned to the buffet. */ int main( int argc, char *argv[] ) { const char *modename; pthread_t *threads; int *threadids; int result; int errors=0; int i; if(argc<3) { fprintf(stderr,"use: %s \n",argv[0]); return 1; } srand(time(0)); nthreads = atoi(argv[1]); modename = argv[2]; if(!strcmp(modename,"deadlock")) { mode = MODE_DEADLOCK; } else if(!strcmp(modename,"single")) { mode = MODE_SINGLE; } else if(!strcmp(modename,"multi")) { mode = MODE_MULTI; } else if(!strcmp(modename,"fair")) { mode = MODE_FAIR; } else { fprintf(stderr,"bad mode name: %s\n",modename); return 1; } threadids = malloc(sizeof(int)*nthreads); threads = malloc(sizeof(pthread_t)*nthreads); for(i=0;i