void smaug(int smaugWinChance)// { int k; int localpid; double elapsedTime; /* local counters used only for smaug routine */ int numJewels = INITIAL_TREASURE_IN_HOARD; int cowsEatenTotal = 0; int sheepsEatenTotal = 0; int thiefsWonTotal = 0; int huntersWonTotal = 0; int sleepThisIteration = 1; /* Initialize random number generator*/ /* Random numbers are used to determine the time between successive beasts */ smaugProcessID = getpid(); printf("SMAUGSMAUGSMAUGSMAUGSMAU PID is %d \n", smaugProcessID ); localpid = smaugProcessID; while (*terminateFlagp==0) { // Smaug goes to sleep if nothing happens and sleepThisIteration is 1 if(sleepThisIteration == 1) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has gone to sleep\n" ); // We must reset the semaphore to prevent smaug waking up when there's no need to seminfo.val = 0; semctlChecked(semID, SEM_DRAGONSLEEPING, SETVAL, seminfo); semopChecked(semID, &WaitDragonSleeping, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug sniffs his valey\n" ); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has woken up \n" ); } else { sleepThisIteration = 1; } semopChecked(semID, &WaitProtectMealWaitingFlag, 1); semopChecked(semID, &WaitProtectSheepMealWaitingFlag, 1); if(*mealWaitingFlagp >= 1 && *mealSheepWaitingFlagp >= 1) { while( *mealWaitingFlagp >= 1 && *mealSheepWaitingFlagp >= 1 ) { *mealWaitingFlagp = *mealWaitingFlagp - 1; *mealSheepWaitingFlagp = *mealSheepWaitingFlagp - 1; printf("SMAUGSMAUGSMAUGSMAUGSMAU signal cow meal flag %d\n", *mealWaitingFlagp); semopChecked(semID, &SignalProtectMealWaitingFlag, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug is eating a meal\n"); for( k = 0; k < COWS_IN_GROUP; k++ ) { semopChecked(semID, &SignalCowsWaiting, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU A cow is ready to eat\n"); } printf("SMAUGSMAUGSMAUGSMAUGSMAU signal sheep meal flag %d\n", *mealSheepWaitingFlagp); semopChecked(semID, &SignalProtectSheepMealWaitingFlag, 1); for( k = 0; k < SHEEPS_IN_GROUP; k++ ) { semopChecked(semID, &SignalSheepsWaiting, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU A sheep is ready to eat\n"); } /*Smaug waits to eat*/ semopChecked(semID, &WaitDragonEating, 1); for( k = 0; k < COWS_IN_GROUP; k++ ) { semopChecked(semID, &SignalCowsDead, 1); cowsEatenTotal++; printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug finished eating a cow\n"); } for( k = 0; k < SHEEPS_IN_GROUP; k++ ) { semopChecked(semID, &SignalSheepsDead, 1); sheepsEatenTotal++; printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug finished eating a sheep\n"); } printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has finished a meal\n"); if( (cowsEatenTotal >= MAX_COWS_EATEN) && (sheepsEatenTotal >= MAX_SHEEPS_EATEN) ) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has eaten the allowed number of cows and sheeps\n"); *terminateFlagp= 1; break; } printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug takes a nap for %d us\n", SMAUG_NAP_LENGTH); usleep(SMAUG_NAP_LENGTH); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug takes a deep breath\n"); /* Smaug check to see if another snack is waiting */ semopChecked(semID, &WaitProtectMealWaitingFlag, 1); semopChecked(semID, &WaitProtectSheepMealWaitingFlag, 1); if( *mealWaitingFlagp > 0 && *mealSheepWaitingFlagp > 0 ) { printf("SMAUGSMAUGSMAUGSMAUGSMAU %d Smaug eats again\n", localpid); continue; } } } semopChecked(semID, &SignalProtectMealWaitingFlag, 1); // release the protection semopChecked(semID, &SignalProtectSheepMealWaitingFlag, 1); // release the protection semopChecked(semID, &WaitProtectThiefCount, 1); if(*thiefCounterp > 0) { *thiefCounterp = *thiefCounterp - 1; semopChecked(semID, &SignalProtectThiefCount, 1); // Wake thief from wander state for interaction semopChecked(semID, &SignalThievesWaiting, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug is playing with a thief\n"); if( rand() % 100 <= smaugWinChance ) { numJewels += 20; thiefsWonTotal++; printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has defeated a thief\n"); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has gained a treasure (%d jewels). He now has %d jewels.\n", 20, numJewels); } else { numJewels -= 8; printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has been defeated by a thief\n"); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has lost a treasure (%d jewels). He now has %d jewels.\n", 8, numJewels); } printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has finished a game (1 thief process has been terminated)\n"); if(thiefsWonTotal >= MAX_THEIFES_WON ) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has won the allowed number of thieves\n"); *terminateFlagp= 1; break; } if( numJewels >= MAX_TREASURE_IN_HOARD) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has %d, so he is richer then everyone so he leaves.\n", numJewels); *terminateFlagp= 1; break; } if( numJewels <= MIN_TREASURE_IN_HOARD) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has %d, so is very poor and decide to leave\n", numJewels); *terminateFlagp= 1; break; } semopChecked(semID, &SignalThiefFinish, 1); } semopChecked(semID, &SignalProtectThiefCount, 1); //release semopChecked(semID, &WaitProtectHunterCount, 1); if(*hunterCounterp > 0) { // check thift *hunterCounterp = *hunterCounterp - 1; semopChecked(semID, &SignalProtectHunterCount, 1); semopChecked(semID, &SignalHuntersWaiting, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug is fighting with a hunter\n"); if( rand() % 100 <= smaugWinChance ) { huntersWonTotal++; numJewels += 5; printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has defeated a hunter\n"); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has gained a treasure (%d jewels). He now has %d jewels.\n", 10, numJewels); } else { numJewels -= 10; printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has been defeated by a hunter\n"); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has lost a treasure (%d jewels). He now has %d jewels.\n", 5, numJewels); } printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has finished a fight(1 hunter process has been terminated)\n"); if(huntersWonTotal >= MAX_HUNTERS_WON ) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has won the allowed number of hunters\n"); *terminateFlagp= 1; break; } if( numJewels >= MAX_TREASURE_IN_HOARD) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has %d, so he is richer then everyone so he leaves.\n", numJewels); *terminateFlagp= 1; break; } if( numJewels <= MIN_TREASURE_IN_HOARD) { printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug has %d, so is very poor and decide to leave\n", numJewels); *terminateFlagp= 1; break; } semopChecked(semID, &SignalHunterFinish, 1); } semopChecked(semID, &SignalProtectHunterCount, 1); //release printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug sleeps again\n"); semopChecked(semID, &WaitDragonSleeping, 1); printf("SMAUGSMAUGSMAUGSMAUGSMAU Smaug is awake again\n"); sleepThisIteration = 0; } }
void initialize() { /* Init semaphores */ semID=semget(IPC_PRIVATE, 25, 0666 | IPC_CREAT); /* Init to zero, no elements are produced yet */ seminfo.val=0; semctlChecked(semID, SEM_COWSINGROUP, SETVAL, seminfo); semctlChecked(semID, SEM_COWSWAITING, SETVAL, seminfo); semctlChecked(semID, SEM_COWSEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_COWSDEAD, SETVAL, seminfo); semctlChecked(semID, SEM_SHEEPSINGROUP, SETVAL, seminfo); semctlChecked(semID, SEM_SHEEPSWAITING, SETVAL, seminfo); semctlChecked(semID, SEM_SHEEPSEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_SHEEPSDEAD, SETVAL, seminfo); semctlChecked(semID, SEM_THIEVESWAITING, SETVAL, seminfo); semctlChecked(semID, SEM_THIEFFINISH, SETVAL, seminfo); semctlChecked(semID, SEM_HUNTERSWAITING, SETVAL, seminfo); semctlChecked(semID, SEM_HUNTERFINISH, SETVAL, seminfo); semctlChecked(semID, SEM_DRAGONFIGHTING, SETVAL, seminfo); semctlChecked(semID, SEM_DRAGONSLEEPING, SETVAL, seminfo); semctlChecked(semID, SEM_DRAGONEATING, SETVAL, seminfo); printf("!!INIT!!INIT!!INIT!! semaphores initiialized\n"); /* Init Mutex to one */ seminfo.val=1; semctlChecked(semID, SEM_PTERMINATE, SETVAL, seminfo); semctlChecked(semID, SEM_PCOWSINGROUP, SETVAL, seminfo); semctlChecked(semID, SEM_PMEALWAITINGFLAG, SETVAL, seminfo); semctlChecked(semID, SEM_PCOWSEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_PSHEEPSINGROUP, SETVAL, seminfo); semctlChecked(semID, SEM_PSHEEPSEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_PSHEEPMEALWAITINGFLAG, SETVAL, seminfo); semctlChecked(semID, SEM_PTHIEFCOUNT, SETVAL, seminfo); semctlChecked(semID, SEM_PHUNTERCOUNT, SETVAL, seminfo); printf("!!INIT!!INIT!!INIT!! mutexes initiialized\n"); /* Now we create and attach the segments of shared memory*/ if ((terminateFlag = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for terminateFlag\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for terminateFlag\n"); } if ((cowCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for cowCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for cowCounter\n"); } if ((mealWaitingFlag = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for mealWaitingFlag\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for mealWaitingFlag\n"); } if ((mealSheepWaitingFlag = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for mealWaitingFlag\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for mealWaitingFlag\n"); } if ((cowsEatenCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for cowsEatenCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for cowsEatenCounter\n"); } if ((sheepCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for sheepsCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for sheepCounter\n"); } if ((sheepsEatenCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for sheepsEatenCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for sheepsEatenCounter\n"); } if ((thiefCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for thiefCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for thiefCounter\n"); } if ((hunterCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for hunterCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for hunterCounter\n"); } /* Now we attach the segment to our data space. */ if ((terminateFlagp = shmat(terminateFlag, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for terminateFlag\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for terminateFlag\n"); } if ((cowCounterp = shmat(cowCounter, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for cowCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for cowCounter\n"); } if ((sheepCounterp = shmat(cowCounter, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for sheepCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for cowCounter\n"); } if ((mealWaitingFlagp = shmat(mealWaitingFlag, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for mealWaitingFlag\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for mealWaitingFlag\n"); } if ((mealSheepWaitingFlagp = shmat(mealSheepWaitingFlag, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for mealWaitingFlag\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for mealWaitingFlag\n"); } if ((cowsEatenCounterp = shmat(cowsEatenCounter, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for cowsEatenCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for cowsEatenCounter\n"); } if ((sheepsEatenCounterp = shmat(sheepsEatenCounter, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for sheepsEatenCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for sheepsEatenCounter\n"); } if ((thiefCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for thiefCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for thiefCounter\n"); } if ((thiefCounterp = shmat(thiefCounter, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for thiefCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for thiefCounter\n"); } printf("!!INIT!!INIT!!INIT!! initialize end\n"); if ((hunterCounter = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666)) < 0) { printf("!!INIT!!INIT!!INIT!! shm not created for hunterCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm created for hunterCounter\n"); } if ((hunterCounterp = shmat(hunterCounter, NULL, 0)) == (int *) -1) { printf("!!INIT!!INIT!!INIT!! shm not attached for hunterCounter\n"); exit(1); } else { printf("!!INIT!!INIT!!INIT!! shm attached for hunterCounter\n"); } printf("!!INIT!!INIT!!INIT!! initialize end\n"); }
//=========================================================== // Utilities //=========================================================== //function definitions void initialize() { semID = semget(IPC_PRIVATE, 39, 0666 | IPC_CREAT); //initialize values of semaphore //semaphores of Dragon seminfo.val = 0; semctlChecked(semID, SEM_S_DRAGONWAKEUP, SETVAL, seminfo); semctlChecked(semID, SEM_S_DRAGONEAT, SETVAL, seminfo); semctlChecked(semID, SEM_S_DRAGONFIGHT, SETVAL, seminfo); semctlChecked(semID, SEM_S_DRAGONPLAY, SETVAL, seminfo); seminfo.val = 1; // semctlChecked(semID, SEM_P_DRAGONWAKEUP, SETVAL, seminfo); semctlChecked(semID, SEM_P_DRAGONJEWEL, SETVAL, seminfo); //semaphores of meals seminfo.val = 0; semctlChecked(semID, SEM_N_MEAL, SETVAL, seminfo); semctlChecked(semID, SEM_S_MEALDONE, SETVAL, seminfo); seminfo.val = 1; semctlChecked(semID, SEM_P_NUMMEAL, SETVAL, seminfo); semctlChecked(semID, SEM_P_EATENMEAL, SETVAL, seminfo); //semaphores of sheep seminfo.val = 0; semctlChecked(semID, SEM_N_SHEEPINVALLEY, SETVAL, seminfo); semctlChecked(semID, SEM_S_SHEEPWAITING, SETVAL, seminfo); semctlChecked(semID, SEM_N_SHEEPTOEAT, SETVAL, seminfo); semctlChecked(semID, SEM_S_SHEEPEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_N_MEALSHEEP, SETVAL, seminfo); seminfo.val = 1; semctlChecked(semID, SEM_P_SHEEPINVALLEY, SETVAL, seminfo); semctlChecked(semID, SEM_P_SHEEPTOEAT, SETVAL, seminfo); semctlChecked(semID, SEM_P_SHEEPEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_P_MEALSHEEP, SETVAL, seminfo); //semaphores of cows seminfo.val = 0; semctlChecked(semID, SEM_N_COWINVALLEY, SETVAL, seminfo); semctlChecked(semID, SEM_S_COWWAITING, SETVAL, seminfo); semctlChecked(semID, SEM_N_COWTOEAT, SETVAL, seminfo); semctlChecked(semID, SEM_S_COWEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_N_MEALCOW, SETVAL, seminfo); seminfo.val = 1; semctlChecked(semID, SEM_P_COWINVALLEY, SETVAL, seminfo); semctlChecked(semID, SEM_P_COWTOEAT, SETVAL, seminfo); semctlChecked(semID, SEM_P_COWEATEN, SETVAL, seminfo); semctlChecked(semID, SEM_P_MEALCOW, SETVAL, seminfo); //semaphores of hunters seminfo.val = 0; semctlChecked(semID, SEM_N_HUNTERPATH, SETVAL, seminfo); semctlChecked(semID, SEM_S_HUNTERCAVE, SETVAL, seminfo); semctlChecked(semID, SEM_S_HUNTERFIGHT, SETVAL, seminfo); seminfo.val = 1; semctlChecked(semID, SEM_P_HUNTERPATH, SETVAL, seminfo); semctlChecked(semID, SEM_P_HUNTERLEAVE, SETVAL, seminfo); //semaphores of thieves seminfo.val = 0; semctlChecked(semID, SEM_N_THIEFPATH, SETVAL, seminfo); semctlChecked(semID, SEM_S_THIEFCAVE, SETVAL, seminfo); semctlChecked(semID, SEM_S_THIEFPLAY, SETVAL, seminfo); seminfo.val = 1; semctlChecked(semID, SEM_P_THIEFPATH, SETVAL, seminfo); semctlChecked(semID, SEM_P_THIEFLEAVE, SETVAL, seminfo); //semaphores of the system seminfo.val = 1; semctlChecked(semID, SEM_P_TERMINATION, SETVAL, seminfo); //allocate shared memory //shared memory for dragon // shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &DragonWakeUpFlag, &DragonWakeUp); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numDragonJewelFlag, &numDragonJewel); //shared memory for meal shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numMealFlag, &numMeal); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numEatenMealFlag, &numEatenMeal); //shared memory for sheep shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &SheepInValleyFlag, &SheepInValley); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numSheepToEatFlag, &numSheepToEat); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numSheepEatenFlag, &numSheepEaten); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numMealSheepFlag, &numMealSheep); //shared memory for cow shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &CowInValleyFlag, &CowInValley); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numCowToEatFlag, &numCowToEat); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numCowEatenFlag, &numCowEaten); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numMealCowFlag, &numMealCow); //shared memory for hunter shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numHunterPathFlag, &numHunterPath); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numHunterLeaveFlag, &numHunterLeave); //shared memory for thief shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numThiefPathFlag, &numThiefPath); shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &numThiefLeaveFlag, &numThiefLeave); //shared memory for the system shmAllocate(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666, NULL, 0, &flagTerminationFlag, &flagTermination); }