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;
}
Ejemplo n.º 2
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;
}