int catmouse(int nargs, char ** args) { int index, error; int i; /* check and process command line arguments */ if (nargs != 5) { kprintf("Usage: <command> NUM_BOWLS NUM_CATS NUM_MICE NUM_LOOPS\n"); return 1; // return failure indication } /* check the problem parameters, and set the global variables */ NumBowls = atoi(args[1]); if (NumBowls <= 0) { kprintf("catmouse: invalid number of bowls: %d\n",NumBowls); return 1; } NumCats = atoi(args[2]); if (NumCats < 0) { kprintf("catmouse: invalid number of cats: %d\n",NumCats); return 1; } NumMice = atoi(args[3]); if (NumMice < 0) { kprintf("catmouse: invalid number of mice: %d\n",NumMice); return 1; } NumLoops = atoi(args[4]); if (NumLoops <= 0) { kprintf("catmouse: invalid number of loops: %d\n",NumLoops); return 1; } kprintf("Using %d bowls, %d cats, and %d mice. Looping %d times.\n", NumBowls,NumCats,NumMice,NumLoops); /* create the semaphore that is used to make the main thread wait for all of the cats and mice to finish */ CatMouseWait = sem_create("CatMouseWait",0); if (CatMouseWait == NULL) { panic("catmouse: could not create semaphore\n"); } /* * initialize the bowls */ if (initialize_bowls(NumBowls)) { panic("catmouse: error initializing bowls.\n"); } #if OPT_A1 // Create the kitchen k = kitchen_create(); #endif /* * Start NumCats cat_simulation() threads. */ for (index = 0; index < NumCats; index++) { error = thread_fork("cat_simulation thread",NULL,index,cat_simulation,NULL); if (error) { panic("cat_simulation: thread_fork failed: %s\n", strerror(error)); } } /* * Start NumMice mouse_simulation() threads. */ for (index = 0; index < NumMice; index++) { error = thread_fork("mouse_simulation thread",NULL,index,mouse_simulation,NULL); if (error) { panic("mouse_simulation: thread_fork failed: %s\n",strerror(error)); } } /* wait for all of the cats and mice to finish before terminating */ for(i=0;i<(NumCats+NumMice);i++) { P(CatMouseWait); } #if OPT_A1 // Cleanup the kitchen lol kitchen_destroy(k); #endif /* clean up the semaphore the we created */ sem_destroy(CatMouseWait); return 0; }
int catmouse(int nargs, char ** args) { int index, error; int i; /* check and process command line arguments */ if ((nargs != 9) && (nargs != 5)) { kprintf("Usage: <command> NUM_BOWLS NUM_CATS NUM_MICE NUM_LOOPS\n"); kprintf("or\n"); kprintf("Usage: <command> NUM_BOWLS NUM_CATS NUM_MICE NUM_LOOPS "); kprintf("CAT_EATING_TIME CAT_SLEEPING_TIME MOUSE_EATING_TIME MOUSE_SLEEPING_TIME\n"); return 1; // return failure indication } /* check the problem parameters, and set the global variables */ NumBowls = atoi(args[1]); bowlTaken = kmalloc(sizeof(bool)*NumBowls); for(int i = 0 ; i < NumBowls; i++){ bowlTaken[i] = false; } if (NumBowls <= 0) { kprintf("catmouse: invalid number of bowls: %d\n",NumBowls); return 1; } NumCats = atoi(args[2]); if (NumCats < 0) { kprintf("catmouse: invalid number of cats: %d\n",NumCats); return 1; } NumMice = atoi(args[3]); if (NumMice < 0) { kprintf("catmouse: invalid number of mice: %d\n",NumMice); return 1; } NumLoops = atoi(args[4]); if (NumLoops <= 0) { kprintf("catmouse: invalid number of loops: %d\n",NumLoops); return 1; } if (nargs == 9) { CatEatTime = atoi(args[5]); if (CatEatTime < 0) { kprintf("catmouse: invalid cat eating time: %d\n",CatEatTime); return 1; } CatSleepTime = atoi(args[6]); if (CatSleepTime < 0) { kprintf("catmouse: invalid cat sleeping time: %d\n",CatSleepTime); return 1; } MouseEatTime = atoi(args[7]); if (MouseEatTime < 0) { kprintf("catmouse: invalid mouse eating time: %d\n",MouseEatTime); return 1; } MouseSleepTime = atoi(args[8]); if (MouseSleepTime < 0) { kprintf("catmouse: invalid mouse sleeping time: %d\n",MouseSleepTime); return 1; } } kprintf("Using %d bowls, %d cats, and %d mice. Looping %d times.\n", NumBowls,NumCats,NumMice,NumLoops); kprintf("Using cat eating time %d, cat sleeping time %d\n", CatEatTime, CatSleepTime); kprintf("Using mouse eating time %d, mouse sleeping time %d\n", MouseEatTime, MouseSleepTime); /* create the semaphore that is used to make the main thread wait for all of the cats and mice to finish */ CatMouseWait = sem_create("CatMouseWait",0); if (CatMouseWait == NULL) { panic("catmouse: could not create semaphore\n"); } /* * initialize the bowls */ if (initialize_bowls(NumBowls)) { panic("catmouse: error initializing bowls.\n"); } /* * Start NumCats cat_simulation() threads. */ for (index = 0; index < NumCats; index++) { error = thread_fork("cat_simulation thread", NULL, cat_simulation, NULL, index); if (error) { panic("cat_simulation: thread_fork failed: %s\n", strerror(error)); } } /* * Start NumMice mouse_simulation() threads. */ for (index = 0; index < NumMice; index++) { error = thread_fork("mouse_simulation thread", NULL, mouse_simulation, NULL, index); if (error) { panic("mouse_simulation: thread_fork failed: %s\n",strerror(error)); } } /* wait for all of the cats and mice to finish before terminating */ for(i=0;i<(NumCats+NumMice);i++) { P(CatMouseWait); } /* clean up the semaphore that we created */ sem_destroy(CatMouseWait); /* clean up resources used for tracking bowl use */ cleanup_bowls(); return 0; }
int catmouse(int nargs, char ** args) { int catindex, mouseindex, error; int i; int mean_cat_wait_usecs, mean_mouse_wait_usecs; time_t before_sec, after_sec, wait_sec; uint32_t before_nsec, after_nsec, wait_nsec; int total_bowl_milliseconds, total_eating_milliseconds, utilization_percent; /* check and process command line arguments */ if ((nargs != 9) && (nargs != 5)) { kprintf("Usage: <command> NUM_BOWLS NUM_CATS NUM_MICE NUM_LOOPS\n"); kprintf("or\n"); kprintf("Usage: <command> NUM_BOWLS NUM_CATS NUM_MICE NUM_LOOPS "); kprintf("CAT_EATING_TIME CAT_SLEEPING_TIME MOUSE_EATING_TIME MOUSE_SLEEPING_TIME\n"); return 1; // return failure indication } /* check the problem parameters, and set the global variables */ NumBowls = atoi(args[1]); if (NumBowls <= 0) { kprintf("catmouse: invalid number of bowls: %d\n",NumBowls); return 1; } NumCats = atoi(args[2]); if (NumCats < 0) { kprintf("catmouse: invalid number of cats: %d\n",NumCats); return 1; } NumMice = atoi(args[3]); if (NumMice < 0) { kprintf("catmouse: invalid number of mice: %d\n",NumMice); return 1; } NumLoops = atoi(args[4]); if (NumLoops <= 0) { kprintf("catmouse: invalid number of loops: %d\n",NumLoops); return 1; } if (nargs == 9) { CatEatTime = atoi(args[5]); if (CatEatTime < 0) { kprintf("catmouse: invalid cat eating time: %d\n",CatEatTime); return 1; } CatSleepTime = atoi(args[6]); if (CatSleepTime < 0) { kprintf("catmouse: invalid cat sleeping time: %d\n",CatSleepTime); return 1; } MouseEatTime = atoi(args[7]); if (MouseEatTime < 0) { kprintf("catmouse: invalid mouse eating time: %d\n",MouseEatTime); return 1; } MouseSleepTime = atoi(args[8]); if (MouseSleepTime < 0) { kprintf("catmouse: invalid mouse sleeping time: %d\n",MouseSleepTime); return 1; } } if ((NumMice >= INVALID_ANIMAL_NUM) || (NumCats >= INVALID_ANIMAL_NUM)) { panic("Trying to use too many cats or mice: limit = %d\n", INVALID_ANIMAL_NUM); } kprintf("Using %d bowls, %d cats, and %d mice. Looping %d times.\n", NumBowls,NumCats,NumMice,NumLoops); kprintf("Using cat eating time %d, cat sleeping time %d\n", CatEatTime, CatSleepTime); kprintf("Using mouse eating time %d, mouse sleeping time %d\n", MouseEatTime, MouseSleepTime); /* create the semaphore that is used to make the main thread wait for all of the cats and mice to finish */ CatMouseWait = sem_create("CatMouseWait",0); if (CatMouseWait == NULL) { panic("catmouse: could not create semaphore\n"); } /* initialize our simulation state */ initialize_bowls(); /* initialize the synchronization functions */ catmouse_sync_init(NumBowls); /* get current time, for measuring total simulation time */ gettime(&before_sec,&before_nsec); /* * Start NumCats cat_simulation() threads and NumMice mouse_simulation() threads. * Alternate cat and mouse creation. */ for (catindex = 0; catindex < NumCats; catindex++) { error = thread_fork("cat_simulation thread", NULL, cat_simulation, NULL, catindex); if (error) { panic("cat_simulation: thread_fork failed: %s\n", strerror(error)); } if (catindex < NumMice) { error = thread_fork("mouse_simulation thread", NULL, mouse_simulation, NULL, catindex); if (error) { panic("mouse_simulation: thread_fork failed: %s\n",strerror(error)); } } } /* launch any remaining mice */ for(mouseindex = catindex; mouseindex < NumMice; mouseindex++) { error = thread_fork("mouse_simulation thread", NULL, mouse_simulation, NULL, mouseindex); if (error) { panic("mouse_simulation: thread_fork failed: %s\n",strerror(error)); } } /* wait for all of the cats and mice to finish before terminating */ for(i=0;i<(NumCats+NumMice);i++) { P(CatMouseWait); } /* get current time, for measuring total simulation time */ gettime(&after_sec,&after_nsec); /* compute total simulation time */ getinterval(before_sec,before_nsec,after_sec,after_nsec,&wait_sec,&wait_nsec); /* compute and report bowl utilization */ total_bowl_milliseconds = (wait_sec*1000 + wait_nsec/1000000)*NumBowls; total_eating_milliseconds = (NumCats*CatEatTime + NumMice*MouseEatTime)*NumLoops*1000; if (total_bowl_milliseconds > 0) { utilization_percent = total_eating_milliseconds*100/total_bowl_milliseconds; kprintf("STATS: Bowl utilization: %d%%\n",utilization_percent); } /* clean up the semaphore that we created */ sem_destroy(CatMouseWait); /* clean up the synchronization state */ catmouse_sync_cleanup(NumBowls); /* clean up resources used for tracking bowl use */ cleanup_bowls(); if (cat_wait_count > 0) { /* some rounding error here - not significant if cat_wait_count << 1000000 */ mean_cat_wait_usecs = (cat_total_wait_secs*1000000+cat_total_wait_nsecs/1000)/cat_wait_count; kprintf("STATS: Mean cat waiting time: %d.%d seconds\n", mean_cat_wait_usecs/1000000,mean_cat_wait_usecs%1000000); } if (mouse_wait_count > 0) { /* some rounding error here - not significant if mouse_wait_count << 1000000 */ mean_mouse_wait_usecs = (mouse_total_wait_secs*1000000+mouse_total_wait_nsecs/1000)/mouse_wait_count; kprintf("STATS: Mean mouse waiting time: %d.%d seconds\n", mean_mouse_wait_usecs/1000000,mean_mouse_wait_usecs%1000000); } return 0; }