Beispiel #1
0
/*
 * Common code for cmd_prog and cmd_shell.
 *
 * This function uses the one_thread_only() function to make
 * the kernel menu thread wait until the newly-launched program
 * has finished.  The one_thread_only() function is a bit ugly
 * (it works in this specific situation but not more generally)
 * Once you have A2 working, you should be able to use your
 * call your waitpid implementation (instead of one_thread_only())
 * to provide the necessary synchronization.
 *
 * Also note that because the subprogram's thread uses the "args"
 * array and strings, there will be a race condition between the
 * subprogram and the menu input code if the menu thread is not
 * made to wait (using one_thread_only or some other mechanism)
 */
static
int
common_prog(int nargs, char **args)
{
	int result;

#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	result = thread_fork(args[0] /* thread name */,
			args /* thread arg */, nargs /* thread arg */,
			cmd_progthread, NULL);
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		return result;
	}
	
	/* this function is a bit of a hack that is used to make
	 * the kernel menu thread wait until the newly-forked
         * thread completes before the menu thread returns */
	while (!one_thread_only()) {
	  clocksleep(1);
	}

	return 0;
}
Beispiel #2
0
/*
 * Common code for cmd_prog and cmd_shell.
 *
 * Note that this does not wait for the subprogram to finish, but
 * returns immediately to the menu. This is usually not what you want,
 * so you should have it call your system-calls-assignment waitpid
 * code after forking.
 *
 * Also note that because the subprogram's thread uses the "args"
 * array and strings, until you do this a race condition exists
 * between that code and the menu input code.
 */
static
int
common_prog(int nargs, char **args)
{
	int result;

#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif
#if OPT_BADSYNCH
    kprintf("Starting %s, menu will sleep for %d second(s)...\n", args[0],
        menusleep_secs);
#endif
	result = thread_fork(args[0] /* thread name */,
			args /* thread arg */, nargs /* thread arg */,
			cmd_progthread, NULL);
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		return result;
	}
#if OPT_BADSYNCH
    clocksleep(menusleep_secs);
#endif
	return 0;
}
Beispiel #3
0
/*
 * mouse_sleep()
 *
 * Purpose:
 *   simulates a mouse sleeping
 *
 * Arguments: none
 *
 * Returns: nothing
 *
 */
void
mouse_sleep(int sleep_time)
{
  /* simulate sleeping by introducing a delay */
  clocksleep(sleep_time);
  return;
}
Beispiel #4
0
void
cat_eat(unsigned int bowlnumber, int eat_time)
{

  /* check the argument */
  if ((bowlnumber == 0) || ((int)bowlnumber > num_bowls)) {
    panic("cat_eat: invalid bowl number %d\n",bowlnumber);
  }

  /* check and update the simulation state to indicate that
   * the cat is now eating at the specified bowl */
  P(mutex);   // start critical section

  /* first check whether allowing this cat to eat will
   * violate any simulation requirements */
  if (bowls[bowlnumber-1] == 'c') {
    /* there is already a cat eating at the specified bowl */
    panic("cat_eat: attempt to make two cats eat from bowl %d!\n",bowlnumber);
  }
  if (eating_mice_count > 0) {
    /* there is already a mouse eating at some bowl */
    panic("cat_eat: attempt to make a cat eat while mice are eating!\n");
  }
  KASSERT(bowls[bowlnumber-1]=='-');
  KASSERT(eating_mice_count == 0);

  /* now update the state to indicate that the cat is eating */
  eating_cats_count += 1;
  bowls[bowlnumber-1] = 'c';

  /* print a summary of the current state */
  kprintf("cat_eat   (bowl %3d) start:  ",bowlnumber);
  print_state();
  kprintf("\n");

  V(mutex);  // end critical section

  /* simulate eating by introducing a delay
   * note that eating is not part of the critical section */
  clocksleep(eat_time);

  /* update the simulation state to indicate that
   * the cat is finished eating */
  P(mutex);  // start critical section

  KASSERT(eating_cats_count > 0);
  KASSERT(bowls[bowlnumber-1]=='c');
  eating_cats_count -= 1;
  bowls[bowlnumber-1]='-';

  /* print a summary of the current state */
  kprintf("cat_eat   (bowl %3d) finish: ",bowlnumber);
  print_state();
  kprintf("\n");
  
  V(mutex);  // end critical section

  return;
}
static
void
shower()
{
	clocksleep(1);
	// The thread enjoys a refreshing shower!
    //clocksleep(1);
}
Beispiel #6
0
/* who should be "cat" or "mouse" */
static void
lock_eat(const char *who, int num, int bowl, int iteration)
{
    kprintf("%s: %d starts eating: bowl %d, iteration %d\n", who, num,
            bowl, iteration);
    clocksleep(1);
    kprintf("%s: %d ends eating: bowl %d, iteration %d\n", who, num,
            bowl, iteration);
}
Beispiel #7
0
void
mouse_eat(unsigned int bowlnumber, int eat_time, unsigned int mouse_num)
{
  /* check the bowl number */
  KASSERT(bowlnumber > 0);
  KASSERT((int)bowlnumber <= NumBowls);

  /* check and updated the simulation state to indicate that
   * the mouse is now eating at the specified bowl. */
  P(mutex);  // start critical section

  /* first check whether allowing this mouse to eat will
   * violate any simulation requirements */
  if (bowls[bowlnumber-1].animal == 'm') {
    /* there is already a mouse eating at the specified bowl */
    panic("mouse_eat: attempt to make mouse %d eat from bowl %d while mouse %d is there!\n",
           mouse_num, bowlnumber, bowls[bowlnumber-1].which);
  }
  if (eating_cats_count > 0) {
    /* there is already a cat eating at some bowl */
    panic("mouse_eat: attempt to make mouse %d eat while cats are eating!\n", mouse_num);
  }
  KASSERT(bowls[bowlnumber-1].animal=='-');
  KASSERT(bowls[bowlnumber-1].which==INVALID_ANIMAL_NUM);
  KASSERT(eating_cats_count == 0);

  /* now update the state to indicate that the mouse is eating */
  eating_mice_count += 1;
  bowls[bowlnumber-1].animal = 'm';
  bowls[bowlnumber-1].which = mouse_num;
  print_state();

  DEBUG(DB_SYNCPROB,"mouse %d starts to eat at bowl %d [%d:%d]\n",
	mouse_num,bowlnumber,eating_cats_count,eating_mice_count);
  V(mutex);  // end critical section

  /* simulate eating by introducing a delay
   * note that eating is not part of the critical section */
  clocksleep(eat_time);

  /* update the simulation state to indicate that
   * the mouse is finished eating */
  P(mutex); // start critical section

  KASSERT(eating_mice_count > 0);
  eating_mice_count -= 1;
  KASSERT(bowls[bowlnumber-1].animal=='m');
  KASSERT(bowls[bowlnumber-1].which==mouse_num);
  bowls[bowlnumber-1].animal='-';
  bowls[bowlnumber-1].which=INVALID_ANIMAL_NUM;
  print_state();

  DEBUG(DB_SYNCPROB,"mouse %d finishes eating at bowl %d [%d:%d]\n",
	mouse_num,bowlnumber,eating_cats_count,eating_mice_count);
  V(mutex);  // end critical section
  return;
}
static
void
cat(void * unusedpointer, 
    unsigned long catnumber)
{
        int whichBowl = 0; // 0 = neither bowl, 1 = bowlOne, 2 = bowlTwo

	(void) unusedpointer;
        //(void) catnumber;	

	lock_acquire(l);
	//wait until there are no mioce eating and there is at most 1 cat eating
       	while((catsEating > 1) || (miceEating > 0))
	{
		cv_wait(c, l);
	}
	
	//choose a bowl
	if(!bowlOneUsed){
		bowlOneUsed = 1;
		whichBowl = 1;
	}
	else if(!bowlTwoUsed){
		bowlTwoUsed = 1;
		whichBowl = 2;
	}
	else
		panic("No bowl open for cat, even though we waited for an open bowl");

	catsEating++;

	//cat eats
	lock_release(l);
	kprintf("cat %lu starts eating at bowl %d \n", catnumber, whichBowl);
	clocksleep(1);
	kprintf("cat %lu done eating at bowl %d \n", catnumber, whichBowl);
	lock_acquire(l);

	
	if(whichBowl == 1)
		bowlOneUsed = 0;
	else if (whichBowl == 2)
		bowlTwoUsed = 0;
	else
		panic("Neither bowl was used (cat)!");
	catsEating--;
	
	cv_broadcast(c, l);
	lock_release(l);
}
Beispiel #9
0
void baby_bird(void)
{
		
	int sleep_time;

	do {
		// Don't try to eat until mama has filled the bowl
		/* This handles an issue where the bowl lock is released so that 
			mama can refill bowl, but other babies enter scheduler first
			and claim the lock. */
		while (food_in_bowl <= 0);
		kprintf("\nBaby bird acquiring bowl lock...\n");
		lock_acquire(bowl_lock); // Lock out other babies		 
		
		kprintf("Baby bird has acquired the lock.\n");
		kprintf("Baby bird is now eating...\n");
		food_in_bowl--; // eat a portion
		kprintf("%d worms remain.\n", food_in_bowl);

		if (food_in_bowl <=0)
		{
			kprintf("\nOut of food.\n");
						
			kprintf("Signalling mama...\n");
			cv_signal(mama, bowl_lock); // alert mama to refill
			kprintf("I told mama to refill the bowl...\n");
			kprintf("Releasing bowl lock...\n");
			lock_release(bowl_lock); // release the lock
		
		}
		else	
		{	
			kprintf("Baby bird is releasing the lock...\n");
			lock_release(bowl_lock); // Unlock the bowl
		}
		kprintf("Baby bird is sleeping...\n\n");
		sleep_time = random() % MAXSLEEP;
		clocksleep(sleep_time); // Sleep a random number of seconds
	} while (1);
	
}
Beispiel #10
0
/*
 * mouse_sleep()
 *
 * Purpose:
 *   simulates a mouse sleeping
 *
 * Arguments: none
 *
 * Returns: nothing
 *
 */
void
mouse_sleep() {
  /* simulate sleeping by introducing a delay */
  clocksleep(MOUSESLEEPINGTIME);
  return;
}
Beispiel #11
0
/*
 * cat_sleep()
 *
 * Purpose:
 *   simulates a cat sleeping
 *
 * Arguments: none
 *
 * Returns: nothing
 *
 */
void
cat_sleep() {
  /* simulate sleeping by introducing a delay */
  clocksleep(CATSLEEPINGTIME);
  return;
}
int
catmouse(int nargs,
         char ** args)
{
        int index, error, index2;
        /*
         * Avoid unused variable warnings.
         */

        (void) nargs;
        (void) args;


	l = lock_create(lname);
	c = cv_create(cname);
	catsEating = 0;
  	miceEating = 0;
  	bowlOneUsed = 0;
  	bowlTwoUsed = 0;

	/*
         * Start NMICE mouse() threads.
         */
	
	for (index2 = 0; index2 < NMICE; index2++) 
			{
                		error = thread_fork("mouse thread", 
                                    NULL, 
                                    index2, 
                                    mouse, 
                                    NULL
                                    );
                /*
                 * panic() on error.
                 */
                		if (error) {
         
                       	 panic("mouse: thread_fork failed: %s\n", 
                         	     strerror(error)
                         	     );
                		}	
       		 	}
        /*
         * Start NCATS cat() threads.
         */
        for (index = 0; index < NCATS; index++) {
           
                error = thread_fork("cat thread", 
                                    NULL, 
                                    index, 
                                    cat, 
                                    NULL
                                    );
                
                /*
                 * panic() on error.
                 */

                if (error) {
                 
                        panic("cat: thread_fork failed: %s\n", 
                              strerror(error)
                              );
                }
        }

	//join threads with a CV if you have time, deallocate threads after join
	//cv_destroy(c);
	//lock_destroy(l);


	//we dont want the main thread to finish before the others
	clocksleep(10);
        return 0;
}