// program description: // This program written in BACI simulates the studying and // drinking coffee of students. int amtOfStudents; // how many students there are int mugsPerPot; // how many mugs each pot fills int timesToFill; // how many times to fill pot in simulation int potToFillNext; // which pot to fill next int fillCount =0; // how many times has pot been filled const int amtOfPots = 5; // how many pots are there int mugsLeft[ amtOfPots ]; int gettingFilled[ amtOfPots ]; semaphore outputMutex; // one person can write to screen semaphore potNeedsFilling; // signal when student should fill semaphore potMutex; // only one should get the pot 5 semaphore checkMutex; // for checking if coffee is left semaphore filledPot; // for checking if pot has coffee semaphore confirm; // for changing which pot to fill // student who fills the coffee pot void studentFiller() { int potToFill; // continue to fill as long as the user wanted while ( 1 && fillCount < timesToFill ) { // sleep until the pot needs filling and then wait on pot access wait( potNeedsFilling ); potToFill = potToFillNext; signal( confirm ); wait( potMutex ); mugsLeft[ potToFill ] = mugsPerPot; // fill up the pot fillCount = fillCount + 1; // increment fill count wait( outputMutex ); cout << "Pot " << potToFill << " filled" << endl; signal( outputMutex ); gettingFilled[ potToFillNext ] = 0; // pot getting filled signal( potMutex ); // release access to the pot signal( filledPot ); // signify that the pot was filled } } // normal studying student void student( int id ) { int i; // used in for loop int temp; // continue to drink coffee as long as the user wanted while ( 1 && fillCount < timesToFill ) { temp = -1; // wait for access to the pot 6 wait( potMutex ); // if the pot is empty and it is not currently getting filled for ( i = 0; i < amtOfPots; i = i + 1 ) { if ( mugsLeft[ i ] == 0 && gettingFilled[ i ] == 0 ) { wait( outputMutex ); cout << "Student " << id << " had the pot filled" << endl; signal( outputMutex ); gettingFilled[ i ] = 1; // show pot about to fill potToFillNext = i; signal( potNeedsFilling ); // wake up the pot filler wait( confirm ); // ensure stnt has pot number } } // release access to the pot signal( potMutex ); // if the last filling ended up being the last one then break if ( fillCount >= timesToFill ) { signal( filledPot ); break; } // wait for access to the pot wait( potMutex ); // as long as the pot is empty keep looping do { for ( i = 0; i < amtOfPots && temp == -1; i = i + 1 ) { if ( mugsLeft[ i ] > 0 ) { temp = i; } } signal( potMutex ); // release access to the pot if ( fillCount < timesToFill ) { wait( filledPot ); // wait until pot has stuff in it } else { signal( filledPot ); 7 break; } wait( potMutex ); // wait on the pot again } while ( mugsLeft[ temp ] == 0 ); // drink a mug of coffee mugsLeft[ temp ] = mugsLeft[ temp ] - 1; if ( mugsLeft[ temp ] != 0 ) { signal( filledPot ); // check if pot empty for next guy } wait( outputMutex ); if ( fillCount < timesToFill ) { cout << "Student " << id << " drank a cup of coffee" << endl; } signal( outputMutex ); // release access to the pot signal( potMutex ); } } // main function void main() { int i; // used in for loop initialsem( outputMutex, 1 ); // initialize output sempahore initialsem( potNeedsFilling, 0 ); // does the pot need filling initialsem( potMutex, 1 ); // access to the coffee pot initialsem( checkMutex, 1 ); // for checking mugsLeft initialsem( filledPot, 1 ); // is coffee left initialsem( confirm, 1 ); // is coffee left cout << "How many students should there be ( no more than 17 ): "; cin >> amtOfStudents; cout << "How many mugs should each pot of coffee fill: "; cin >> mugsPerPot; 8 cout << "How many times should the coffee pot be filled: "; cin >> timesToFill; // fill up all the pots before starting for ( i = 0; i < amtOfPots; i = i + 1 ) { mugsLeft[ i ] = mugsPerPot; gettingFilled[ i ] = 0; } // begin the appropriate number of students cobegin { studentFiller(); for ( i = 0; i < amtOfStudents; i = i + 1 ) { student( i ); } } cout << "Simulation Finished!" << endl; }