Skip to content

Instantly share code, notes, and snippets.

@JonathanGrant
Last active October 16, 2015 02:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathanGrant/eca0245ad80efdd4b22f to your computer and use it in GitHub Desktop.
Save JonathanGrant/eca0245ad80efdd4b22f to your computer and use it in GitHub Desktop.
/* threadtest.c
// Simple test case for the threads assignment.
//
// Create two threads, and have them context switch
// back and forth between themselves by calling Thread::Yield,
// to illustratethe inner workings of the thread system.
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved. See copyright.h for copyright notice and limitation
// of liability and disclaimer of warranty provisions.*/
/*#include "copyright.h"
#include "system.h"
#include <string>
#include <sstream>
#include <queue>*/
#include "syscall.h"
#define NULL 0
#define true 1
#define false 0
/*#include "list.h"*/
/*OS ASSIGNMENT PART 2 CODE
//----------------------------------------------------------------------
// enum LineChoice
// The four choices of lines the Customer uses to signal which line he
// or she will be in next.
//----------------------------------------------------------------------*/
#define APPLICATION 1
#define PICTURE 2
#define PASSPORT 3
#define CASHIER 4
/*----------------------------------------------------------------------
// Here we are using Forward Declaration to declare all these classes
// So that there are no compiler errors
//----------------------------------------------------------------------*/
struct PassportOffice;
struct Customer;
struct Clerk;
struct Line;
/*MANAGER HEADER
// The following class defines a "Manager" whose job is to wake up clerks who
// have customers waiting, and to print out all the money values.
//
// Run -- runs the thread for the Manager class.
//
// printOutAllMoney() -- prints out all the money for all the types of clerks.
//
// wakeUpClerk(int) -- Wakes up a clerk with a certain clerk number.
//
// checkToSeeIfAnyClerksShouldWakeUp() -- This method does what it is called. Loops
// through all the clerks and wakes up those who should wake up.*/
struct Manager {
/*public:*/
/*Manager(char* _name, struct PassportOffice* _office);
~Manager();
void Run();
void printOutAllMoney();
void checkToSeeIfAnyClerksShouldWakeUp();
void wakeUpClerk(int clerkNumber);
void Stop() {shouldStop = true;}
void setSendOutside(int out) {sendOutside = out;}
private:*/
struct PassportOffice *theOffice;
char* name;
int number;
int shouldStop; /*bool
//bool sendOutside;*/
};
/*CLERK HEADERS
// The following class defines a "Clerk" whose job is to perform a certain
// function for each customer thread. This class is the foundation of the other Clerk
// classes.
//
// setState() -- Sets the state of the clerk from busy to available to on break.
//
// setCustomer() -- Gives the clerk a pointer of the customer who is at his or her register.
//
// takeBribeMoney(int) -- Takes the bribe money from a customer (struct Customer calls this).
//
// yesCustomerAtRegister(bool) -- The default customer is at a register method.
//
// takeBribe(bool) -- Take bribe from the customer (Clerk calls this).
//
// noCustomerAtRegister() -- The clerk method called when there is no one in a register.*/
struct Clerk {
/*public:
//-Clerk(std::string _name, int _number, PassportOffice* _theOffice); // Set initial value of the name
//-virtual ~Clerk(); // de-allocate
//-void Run();
//-std::string getName(){return name;}
//-int getNumber(){return number;}
//-int getState();
//-void setState(int newState);
//-void setCustomer(struct Customer*);
//-Lock* getBreakLock() {return breakLock;}
//-Lock* getDataLock();
//-int getBreakCV() {return breakCV;}
//-int getBribeCV();
//-int getWalkUpCV() {return walkUpCV;}
//-Line* getLine();
//-virtual void takeBribeMoney(int) = 0;
//protected:*/
struct PassportOffice *theOffice;
char* name;
int number;
int clerkState;
int tookBribe;
int/*Locks are now ints*/ breakLock;
int/*struct Lock*/ dataLock;
int/*Conditions are now ints*/ breakCV;
int/*int*/ myBribeCV;
int/*int*/ walkUpCV;
struct Customer *myCustomer;
struct Line *myLine;
/*-void noCustomerAtRegister();
//-void takeBribe(bool);
//-virtual void yesCustomerAtRegister(bool);*/
};
struct ApplicationClerk {
/*public:
//-ApplicationClerk(std::string _name, int _number, PassportOffice* _theOffice);
//-virtual ~ApplicationClerk();
//-virtual void takeBribeMoney(int money);
//-int getApplicationCV();
//-void takeApplication(bool);
//-void takeSocialSecurityNumber(bool);
//private:
//inheritance
union {
struct Clerk clerk;
} Base;
*/struct Clerk myClerk;
int/*int*/ myApplicationCV;
int customerHasApplication; /*bool*/
int customerHasSocialSecurityNumber; /*bool*/
/*methods
//-virtual void yesCustomerAtRegister(bool);*/
};
struct PictureClerk {
/*public:
-PictureClerk(std::string name, int _number, PassportOffice* _theOffice);
//-virtual ~PictureClerk();
//-void takeBribeMoney(int money);
//-int getPictureCV() {return myPictureCV;}
//-void likePicture(bool like) {isPictureLiked = like;}
//-void takeSocialSecurity(bool);
//-void setPictureDecisionMade(bool);
union {
struct Clerk clerk;
} Base;
*/struct Clerk myClerk;
int myPictureCV;
int customerHasSocialSecurityNumber; /*bool*/
/*-virtual void yesCustomerAtRegister(bool);*/
int isPictureLiked; /*bool*/
int pictureDecisionMade; /*bool*/
};
struct PassportClerk {
/*public:
//-PassportClerk(std::string name, int _number, PassportOffice* _theOffice);
//-virtual ~PassportClerk();
//-void takeBribeMoney(int money);
//-int getPassportCV() {return myPassportCV;}
//-void takeFiledApplication(bool app) {customerHasFiledApplication = app;}
//-void takePicture(bool check) {customerHasPicture = check;}
//-void takeSocial(bool);
//-void takeRecordedDocuments(bool doc) {customerHasRecordedDocuments = doc;}
union {
struct Clerk clerk;
} Base;
*/struct Clerk myClerk;
int myPassportCV;
/*virtual void yesCustomerAtRegister(bool isBribed);*/
int customerHasRecordedDocuments; /*bool*/
int customerHasSocialSecurityNumber; /*bool*/
int customerHasFiledApplication; /*bool*/
int customerHasPicture; /*bool*/
};
struct Cashier {
/*public:
-Cashier(std::string name, int _number, PassportOffice* _theOffice);
//-virtual ~Cashier();
//-void takeBribeMoney(int money);
//-int getCashierCV() {return myCashierCV;}
//-void takeFiledApplication(bool app) {customerHasFiledApplication = app;}
//-void takePicture(bool check) {customerHasPicture = check;}
//-void takeRecordedDocuments(bool doc) {customerHasRecordedDocuments = doc;}
//-void takeCustMoney(int money);
//-void recordPassportForCustomer(struct Customer* cust);
//-void takeSocial(bool);
union {
struct Clerk clerk;
} Base;
*/struct Clerk myClerk;
int myCashierCV;
int customerHasFiledApplication; /*bool*/
int customerHasRecordedDocuments; /*bool*/
int customerHasPicture; /*bool*/
int customerHasSocialSecurityNumber; /*bool*/
int tookBribe; /*bool*/
int tookMoney; /*bool*/
};
/*CUSTOMER HEADERS*/
struct Customer {
/*public:
-Customer(std::string _name, int socialSecurityNumber, int money, PassportOffice* _theOffice); // Set initial value of both the name and the socialSecurityNumber
~Customer(); // de-allocate semaphore
std::string getName() { return name;} // debugging assist
int getNumber(){return socialSecurityNumber;}
int getMoney() { return money;}
//Moving methods
//-void enterPassportOffice();
//-void chooseApplicationOrPictureClerk();
//-void enterLine();
//-void dealWithClerk(Clerk*);
//-void dealWithApplicationClerk(ApplicationClerk*);
//-void dealWithPictureClerk(PictureClerk*);
//-void dealWithPassportClerk(PassportClerk*);
//-void dealWithCashier(Cashier*);
//Data Recieving methods
//-void giveFiledApplication(bool app) {hasFiledApplication = app;}
//-void givePicture(bool pic) {hasPicture = pic;}
//-void giveRecordedDocuments(bool doc) {hasRecordedDocuments = doc;}
//-void sendBackToStart(){hasBeenSentBackToStart = true;}
//-void givePassport(bool pas) {hasPassport = pas;}
//-void giveFiledPicture(bool pic) {hasPicture = pic;}
//-void checkRequiredDocumentsForPassportClerk(bool checked){passportClerkHasCheckedRequiredDocuments = checked;}
//-void checkRequiredDocumentsForCashier(bool checked){cashierHasCheckedRequiredDocuments = checked;}
//-void acceptedMoney(bool mon) {hasAcceptedMoney = mon;}
private:*/
char* name;
int lineChoice;
int money;
int socialSecurityNumber;
int hasEnteredPassportOffice; /*bool*/
int hasSocial; /*bool*/
int hasApplication; /*bool*/
int hasPicture; /*bool*/
int hasFiledApplication; /*bool*/
int hasRecordedDocuments; /*bool*/
int hasPassport; /*bool*/
int hasBeenSentBackToStart; /*bool*/
int passportClerkHasCheckedRequiredDocuments; /*bool*/
int cashierHasCheckedRequiredDocuments; /*bool*/
int hasLeftPassportOffice; /*bool*/
struct PassportOffice *theOffice;
int isNowBribing; /*bool*/
int hasAcceptedMoney; /*bool*/
struct Clerk myClerk;
};
/*LINE HEADER*/
struct Line {
/*public:
Line(); // Construct
~Line(); // de-allocate semaphore
//-int getTotalLineSize();
//-int getBriberyLineSize();
//-int getNormalLineSize();
//-void addToBriberyLine(struct Customer*);
//-void addToNormalLine(struct Customer*);
//-Clerk* getClerk() {return clerk;}
//-void setClerk(Clerk* me){clerk = me;}
//-Lock* getLineLock() {return lineLock;}
//-void wakeUpNextInLine();
//-int getNormalLineCV() {return normalLineCV;}
//-int getBribeCV() {return bribeLineCV;}
private:*/
struct Clerk* clerk;
int briberyLineSize;
int normalLineSize;
int lineLock;
int normalLineCV;
int bribeLineCV;
};
/*PASSPORT OFFICE HEADERS*/
struct PassportOffice {
/*public:
PassportOffice(int setClerks); // Construct
~PassportOffice(); // de-allocate
//-int getNumAppClerks() {return numAppClerks;}
//-int getNumPicClerks(){return numPicClerks;}
//-int getNumPasClerks(){return numPasClerks;}
//-int getNumCashiers(){return numCashiers;}
//-int getNumTotalClerks() {return numAppClerks + numPicClerks + numPasClerks+numCashiers;}
//-Clerk** getAppClerks() {return appClerks;}
//-Clerk** getPicClerks() {return picClerks;}
//-Clerk** getPasClerks() {return pasClerks;}
//-Clerk** getCashiers () {return cashiers;}
//-void setAppClerks(Clerk**);
//-void setPicClerks(Clerk**);
//-void setPasClerks(Clerk**);
//-void setCashiers(Clerk**);
//-Clerk* enterShortestLine(struct Customer*, LineChoice, bool);
//-void addCustomer(struct Customer*);
//-void removeCustomer(struct Customer*);
int getShortestApplicationLineLock() {return findShortestApplicationLineLock;}
int getShortestPictureLineLock() {return findShortestPictureLineLock;}
int getShortestPassportLineLock() {return findShortestPassportLineLock;}
int getShortestCashierLineLock() {return findShortestCashierLineLock;}
int getFinishInitializationLock(){return finishInitializationLock;}
int getFinishInitializationCV(){return finishInitializationCV;}
int getAppMoneyLock() {return appMoneyLock;}
int getPicMoneyLock() {return picMoneyLock;}
int getPasMoneyLock() {return pasMoneyLock;}
int getCasMoneyLock() {return casMoneyLock;}
void AllClerksInitialized();
void addMoneyToApplicationClerks(int);
void addMoneyToPictureClerks(int);
void addMoneyToPassportClerks(int);
void addMoneyToCashiers(int);
int getMoneyForApplicationClerks(){return applicationClerkMoney;}
int getMoneyForPictureClerks(){return pictureClerkMoney;}
int getMoneyForPassportClerks(){return passportClerkMoney;}
int getMoneyForCashiers(){return cashierMoney;}
int getCustomerCounter(){return customerCounter;}
int getAppClerkCounter(){return appClerkCounter;}
int getPicClerkCounter(){return picClerkCounter;}
int getPasClerkCounter(){return pasClerkCounter;}
int getCashierCounter(){return cashierCounter;}
int getInitClerks() {return numInitClerks;}
void incrementCustomerCounter(){customerCounter++;}
void decrementCustomerCounter();
void incrementAppClerkCounter(){appClerkCounter++;}
void incrementPicClerkCounter(){picClerkCounter++;}
void incrementPasClerkCounter(){pasClerkCounter++;}
void incrementCashierCounter(){cashierCounter++;}
void incrementInitClerks() {numInitClerks++;}
//int getOutsideLock() {return outsideLock;}
//int getOutsideCV() {return outsideCV;}
void setManager(Manager* michael) {manager = michael;}
private:*/
int customerCounter;
int appClerkCounter;
int picClerkCounter;
int pasClerkCounter;
int cashierCounter;
int numPicClerks;
int numAppClerks;
int numPasClerks;
int numCashiers;
int numInitClerks;
struct PictureClerk picClerks[5];
struct ApplicationClerk appClerks[5];
struct PassportClerk pasClerks[5];
struct Cashier cashiers[5];
int findShortestApplicationLineLock;
int findShortestPictureLineLock;
int findShortestPassportLineLock;
int findShortestCashierLineLock;
int finishInitializationLock;
int appMoneyLock;
int picMoneyLock;
int pasMoneyLock;
int casMoneyLock;
int finishInitializationCV;
int applicationClerkMoney;
int pictureClerkMoney;
int passportClerkMoney;
int cashierMoney;
struct Manager* manager;
};
/*Global Variables*/
struct Manager theManager;
struct PassportOffice theOffice;
struct Customer theCustomers[50];
struct Line theAppLines[5];
struct Line thePicLines[5];
struct Line thePasLines[5];
struct Line theCasLines[5];
struct ApplicationClerk theAppClerks[5];
struct PictureClerk thePicClerks[5];
struct PassportClerk thePasClerks[5];
struct Cashier theCasClerks[5];
/*Fxn Forward Declarations*/
void ManagerRun();
void ManagerPrintOutAllMoney();
void ManagerCheckToSeeIfAnyClerksShouldWakeUp();
void ManagerWakeUpClerk(int clerkNumber);
void ClerkRun(struct Clerk theBro);
int ClerkGetState(struct Clerk theBro);
void ClerkSetState(struct Clerk theBro, int newState);
void ClerkSetCustomer(struct Clerk theBro, struct Customer* theDude) {theBro.myCustomer = theDude;};
int ClerkGetDataLock(struct Clerk theBro);
void ClerkTakeBribeMoney(struct Clerk theBro,int money);
void ApplicationClerkTakeBribeMoney(struct ApplicationClerk,int money);
int ApplicationClerkGetApplicationCV(struct ApplicationClerk theBro);
void ApplciationClerkTakeApplication(struct ApplicationClerk theBro,int);
void ApplicationClerkTakeSocialSecurityNumber(struct ApplicationClerk theBro,int);
void ApplicationClerkYesCustomerAtRegister(struct ApplicationClerk theBro, int isBribed);
int LineGetTotalLineSize(struct Line *lion);
struct Line CreateLine();
int LineGetBriberyLineSize(struct Line *lion);
int LineGetNormalLineSize(struct Line *lion);
void LineWakeUpNextInLine(struct Line *lion);
void ClerkYesCustomerAtRegister(struct Clerk theDude,int isBribed);
void PictureClerkTakeBribeMoney(struct PictureClerk theBro, int money);
void PictureClerkTakeSocialSecurity(struct PictureClerk theBro, int);
void PictureClerkSetPictureDecisionMade(struct PictureClerk theBro, int);
void PictureClerkYesCustomerAtRegister(struct PictureClerk theBro, int isBribed);
void PassportClerkTakeBribeMoney(struct PassportClerk theBro, int money);
void PassportClerkTakeSocial(struct PassportClerk theBro, int);
void PassportClerkYesCustomerAtRegister(struct PassportClerk theBro, int isBribed);
void CashierTakeBribeMoney(struct Cashier theBro, int money);
void CashierTakeCustMoney(struct Cashier theBro, int money);
void CashierRecordPassportForCustomer(struct Cashier theBro, struct Customer* cust);
void CashierTakeSocial(struct Cashier theBro, int);
void CashierYesCustomerAtRegister(struct Cashier theBro, int isBribed);
void CustomerEnterPassportOffice(struct Customer theBro);
void CustomerChooseApplicationOrPictureClerk(struct Customer theBro);
void CustomerEnterLine(struct Customer theBro);
void CustomerDealWithClerk(struct Customer theBro,struct Clerk);
void CustomerDealWithApplicationClerk(struct Customer theBro,struct ApplicationClerk);
void CustomerDealWithPictureClerk(struct Customer theBro,struct PictureClerk);
void CustomerDealWithPassportClerk(struct Customer theBro,struct PassportClerk);
void CustomerDealWithCashier(struct Customer theBro,struct Cashier);
void PassportOfficeSetAppClerks(struct Clerk**);
void PassportOfficeSetPicClerks(struct Clerk**);
void PassportOfficeSetPasClerks(struct Clerk**);
void PassportOfficeSetCashiers(struct Clerk**);
struct Clerk PassportOfficeEnterShortestLine(struct Customer, int, int);
void PassportOfficeAddCustomer(struct Customer*);
void PassportOfficeRemoveCustomer(struct Customer*);
void PassportOfficeAllClerksInitialized();
void PassportOfficeAddMoneyToApplicationClerks(int);
void PassportOfficeAddMoneyToPictureClerks(int);
void PassportOfficeAddMoneyToPassportClerks(int);
void PassportOfficeAddMoneyToCashiers(int);
void PassportOfficeDecrementCustomerCounter();
/*Functions from .h*/
void ManagerStop() {
theManager.shouldStop = 1;
}
char* ClerkGetName(struct Clerk theDude){
return theDude.name;
}
int ClerkGetNumber(struct Clerk theDude){
return theDude.number;
}
int ClerkGetBreakLock(struct Clerk theDude) {
return theDude.breakLock;
}
int ClerkGetBreakCV(struct Clerk theDude) {
return theDude.breakCV;
}
int ClerkGetWalkUpCV(struct Clerk theDude) {
return theDude.walkUpCV;
}
int PictureClerkGetPictureCV(struct PictureClerk theBro) {return theBro.myPictureCV;}
void PictureClerkLikePicture(struct PictureClerk theBro, int like) {theBro.isPictureLiked = like;}
int PassportClerkGetPassportCV(struct PassportClerk theBro) {return theBro.myPassportCV;}
void PassportClerkTakeFiledApplication(struct PassportClerk theBro, int app) {theBro.customerHasFiledApplication = app;}
void PassportClerkTakePicture(struct PassportClerk theBro, int check) {theBro.customerHasPicture = check;}
void PassportClerkTakeRecordedDocuments(struct PassportClerk theBro, int doc) {theBro.customerHasRecordedDocuments = doc;}
int CashierGetCashierCV(struct Cashier paul) {return paul.myCashierCV;}
void CashierTakeFiledApplication(struct Cashier paul, int app) {paul.customerHasFiledApplication = app;}
void CashierTakePicture(struct Cashier paul,int check) {paul.customerHasPicture = check;}
void CashierTakeRecordedDocuments(struct Cashier paul,int doc) {paul.customerHasRecordedDocuments = doc;}
char* CustomerGetName(struct Customer *theBro) { return theBro->name;}
int CustomerGetNumber(struct Customer *theBro){return theBro->socialSecurityNumber;}
int CustomerGetMoney(struct Customer *theBro) { return theBro->money;}
void CustomerGiveFiledApplication(struct Customer *theBro,int app) {theBro->hasFiledApplication = app;}
void CustomerGivePicture(struct Customer *theBro,int pic) {theBro->hasPicture = pic;}
void CustomerGiveRecordedDocuments(struct Customer *theBro,int doc) {theBro->hasRecordedDocuments = doc;}
void CustomerSendBackToStart(struct Customer *theBro){theBro->hasBeenSentBackToStart = true;}
void CustomerGivePassport(struct Customer *theBro,int pas) {theBro->hasPassport = pas;}
void CustomerGiveFiledPicture(struct Customer *theBro,int pic) {theBro->hasPicture = pic;}
void CustomerCheckRequiredDocumentsForPassportClerk(struct Customer *theBro,int checked){theBro->passportClerkHasCheckedRequiredDocuments = checked;}
void CustomerCheckRequiredDocumentsForCashier(struct Customer *theBro,int checked){theBro->cashierHasCheckedRequiredDocuments = checked;}
void CustomerAcceptedMoney(struct Customer *theBro,int mon) {theBro->hasAcceptedMoney = mon;}
int GetCustomerNumber(struct Customer *theBro) {return theBro->socialSecurityNumber;}
struct Clerk* LineGetClerk(struct Line *l) {return l->clerk;}
void LineSetClerk(struct Line *l,struct Clerk* me){l->clerk = me;}
int LineGetLineLock(struct Line *l) {return l->lineLock;}
int LineGetNormalLineCV(struct Line *l) {return l->normalLineCV;}
int LineGetBribeCV(struct Line *l) {return l->bribeLineCV;}
int PassportOfficeGetNumAppClerks() {return theOffice.numAppClerks;}
int PassportOfficeGetNumPicClerks(){return theOffice.numPicClerks;}
int PassportOfficeGetNumPasClerks(){return theOffice.numPasClerks;}
int PassportOfficeGetNumCashiers(){return theOffice.numCashiers;}
int PassportOfficeGetNumTotalClerks() {return theOffice.numAppClerks + theOffice.numPicClerks + theOffice.numPasClerks+theOffice.numCashiers;}
struct ApplicationClerk* PassportOfficeGetAppClerks() {return theAppClerks;}
struct PictureClerk* PassportOfficeGetPicClerks() {return thePicClerks;}
struct PassportClerk* PassportOfficeGetPasClerks() {return thePasClerks;}
struct Cashier* PassportOfficeGetCashiers () {return theCasClerks;}
int PassportOfficeGetShortestApplicationLineLock() {return theOffice.findShortestApplicationLineLock;}
int PassportOfficeGetShortestPictureLineLock() {return theOffice.findShortestPictureLineLock;}
int PassportOfficeGetShortestPassportLineLock() {return theOffice.findShortestPassportLineLock;}
int PassportOfficeGetShortestCashierLineLock() {return theOffice.findShortestCashierLineLock;}
int PassportOfficeGetFinishInitializationLock(){return theOffice.finishInitializationLock;}
int PassportOfficeGetFinishInitializationCV(){return theOffice.finishInitializationCV;}
int PassportOfficeGetAppMoneyLock() {return theOffice.appMoneyLock;}
int PassportOfficeGetPicMoneyLock() {return theOffice.picMoneyLock;}
int PassportOfficeGetPasMoneyLock() {return theOffice.pasMoneyLock;}
int PassportOfficeGetCasMoneyLock() {return theOffice.casMoneyLock;}
int PassportOfficeGetMoneyForApplicationClerks(){return theOffice.applicationClerkMoney;}
int PassportOfficeGetMoneyForPictureClerks(){return theOffice.pictureClerkMoney;}
int PassportOfficeGetMoneyForPassportClerks(){return theOffice.passportClerkMoney;}
int PassportOfficeGetMoneyForCashiers(){return theOffice.cashierMoney;}
int PassportOfficeGetCustomerCounter(){return theOffice.customerCounter;}
int PassportOfficeGetAppClerkCounter(){return theOffice.appClerkCounter;}
int PassportOfficeGetPicClerkCounter(){return theOffice.picClerkCounter;}
int PassportOfficeGetPasClerkCounter(){return theOffice.pasClerkCounter;}
int PassportOfficeGetCashierCounter(){return theOffice.cashierCounter;}
int PassportOfficeGetInitClerks() {return theOffice.numInitClerks;}
void PassportOfficeIncrementCustomerCounter(){theOffice.customerCounter++;}
void PassportOfficeIncrementAppClerkCounter(){theOffice.appClerkCounter++;}
void PassportOfficeIncrementPicClerkCounter(){theOffice.picClerkCounter++;}
void PassportOfficeIncrementPasClerkCounter(){theOffice.pasClerkCounter++;}
void PassportOfficeIncrementCashierCounter(){theOffice.cashierCounter++;}
void PassportOfficeIncrementInitClerks() {theOffice.numInitClerks++;}
void PassportOfficeSetManager(struct Manager *michael) {theOffice.manager = michael;}
/*MANAGER FUNCTIONS*/
void CreateManager(char* _name) { /*Do I need the word 'struct'?*/
theManager.name = _name;
theManager.shouldStop = 0;
theManager.theOffice = &theOffice;
PassportOfficeSetManager(&theManager);
}
void ManagerRun(){
int woa;
while(true == true){
ManagerPrintOutAllMoney();
ManagerCheckToSeeIfAnyClerksShouldWakeUp();
for (woa = 0; woa < 2000; woa++) {
Yield();
}
if (theManager.shouldStop == 1) {
ManagerPrintOutAllMoney();
break;
}
}
Exit(0);
}
void ManagerPrintOutAllMoney(){
int appMoneyLock = PassportOfficeGetAppMoneyLock();
int picMoneyLock = PassportOfficeGetPicMoneyLock();
int pasMoneyLock = PassportOfficeGetPasMoneyLock();
int casMoneyLock = PassportOfficeGetCasMoneyLock();
AcquireLock(appMoneyLock);
Write("\n\nManager has counted a total of $", 50, ConsoleOutput);
PrintInt(PassportOfficeGetMoneyForApplicationClerks());
Write(" for ApplicationClerks\n", 30, ConsoleOutput);
AcquireLock(picMoneyLock);
Write("\n\nManager has counted a total of $", 50, ConsoleOutput);
PrintInt(PassportOfficeGetMoneyForPictureClerks());
Write(" for PictureClerks\n", 30, ConsoleOutput);
AcquireLock(pasMoneyLock);
Write("\nManager has counter a total of $", 40, ConsoleOutput);
PrintInt(PassportOfficeGetMoneyForPassportClerks());
Write(" for PassportClerks\n", 30, ConsoleOutput);
AcquireLock(casMoneyLock);
Write("\nManager has counter a total of $", 40, ConsoleOutput);
PrintInt(PassportOfficeGetMoneyForCashiers());
Write(" for Cashiers\n", 30, ConsoleOutput);
Write("\nManager has counter a total of $", 40, ConsoleOutput);
PrintInt(PassportOfficeGetMoneyForApplicationClerks() +
PassportOfficeGetMoneyForPictureClerks() +
PassportOfficeGetMoneyForPassportClerks() +
PassportOfficeGetMoneyForCashiers());
Write(" for the PassportOffice\n\n", 30, ConsoleOutput);
/*release all the locks!*/
ReleaseLock(appMoneyLock);
ReleaseLock(picMoneyLock);
ReleaseLock(pasMoneyLock);
ReleaseLock(casMoneyLock);
}
void ManagerCheckToSeeIfAnyClerksShouldWakeUp() {
int c;
int breakCV;
int breakLock;
/*Get all the clerks*/
/*Loop through them
//bool appClerk = false;*/
for(c = 0; c < PassportOfficeGetNumAppClerks(); c++){
if (LineGetTotalLineSize(theAppClerks[c].myClerk.myLine) >= 3) {
if (theAppClerks[c].myClerk.clerkState == 2) {
/*If line size > 3 and the clerk is on break:
//Wake up the clerk*/
breakCV = ClerkGetBreakCV(theAppClerks[c].myClerk);
breakLock = ClerkGetBreakLock(theAppClerks[c].myClerk);
AcquireLock(breakLock);
SignalCV(breakCV,breakLock);
Write("Manager has woken up ApplicationClerk ", 40, ConsoleOutput);
PrintInt(theAppClerks[c].myClerk.number);
Write(".\n", 5, ConsoleOutput);
ReleaseLock(breakLock);
}
}
}
/*//If there is no Application Clerk available, wake one up
if(!appClerk){
}*/
for(c = 0; c < PassportOfficeGetNumPicClerks(); c++){
if (LineGetTotalLineSize(thePicClerks[c].myClerk.myLine) >= 3) {
if (thePicClerks[c].myClerk.clerkState == 2) {
/*If line size > 3 and the clerk is on break:
//Wake up the clerk*/
breakCV = ClerkGetBreakCV(thePicClerks[c].myClerk);
breakLock = ClerkGetBreakLock(thePicClerks[c].myClerk);
AcquireLock(breakLock);
SignalCV(breakCV,breakLock);
Write("Manager has woken up PictureClerk ", 40, ConsoleOutput);
PrintInt(thePicClerks[c].myClerk.number);
Write(".\n", 5, ConsoleOutput);
ReleaseLock(breakLock);
}
}
}
for(c = 0; c < PassportOfficeGetNumPasClerks(); c++){
if (LineGetTotalLineSize(thePasClerks[c].myClerk.myLine) >= 3) {
if (thePasClerks[c].myClerk.clerkState == 2) {
/*If line size > 3 and the clerk is on break:
//Wake up the clerk*/
breakCV = ClerkGetBreakCV(thePasClerks[c].myClerk);
breakLock = ClerkGetBreakLock(thePasClerks[c].myClerk);
AcquireLock(breakLock);
SignalCV(breakCV,breakLock);
Write("Manager has woken up PassportClerk ", 40, ConsoleOutput);
PrintInt(thePasClerks[c].myClerk.number);
Write(".\n", 5, ConsoleOutput);
ReleaseLock(breakLock);
}
}
}
for(c = 0; c < PassportOfficeGetNumCashiers(); c++){
if (LineGetTotalLineSize(theCasClerks[c].myClerk.myLine) >= 3) {
if (theCasClerks[c].myClerk.clerkState == 2) {
/*If line size > 3 and the clerk is on break:
//Wake up the clerk*/
breakCV = ClerkGetBreakCV(theCasClerks[c].myClerk);
breakLock = ClerkGetBreakLock(theCasClerks[c].myClerk);
AcquireLock(breakLock);
SignalCV(breakCV,breakLock);
Write("Manager has woken up Cashier ", 40, ConsoleOutput);
PrintInt(theCasClerks[c].myClerk.number);
Write(".\n", 5, ConsoleOutput);
ReleaseLock(breakLock);
}
}
}
}
/*
//New function: Make everyone go outside because there is a Senator in the house!!!
void Manager::sendEveryoneButTheSenatorOutside() {
//Wake up everyone in all the lines.
//First get the lock
Lock* outsideLock = theOffice->getOutsideLock();
outsideLock->AcquireLock();
//They know to go outside and wait until the senator is gone
//Get all the clerks
Clerk** appClerks = theOffice->getAppClerks();
Clerk** picClerks = theOffice->getPicClerks();
Clerk** pasClerks = theOffice->getPasClerks();
Clerk** cashiers = theOffice->getCashiers();
//Loop through them
for(int c = 0; c < theOffice->getNumAppClerks(); c++){
if (appClerks[c]->getLine()->getTotalLineSize() >= 1) {
//Send everyone in the line outside
for (int b = 0; b < appClerks[c]->getLine()->getBriberyLineSize(); b++) {
//wake up the customer
appClerks[c]->getLine()->wakeUpNextInLine();
}
}
}
for(int c = 0; c < theOffice->getNumPicClerks(); c++){
if (picClerks[c]->getLine()->getTotalLineSize() >= 1) {
//Send everyone in the line outside
for (int b = 0; b < picClerks[c]->getLine()->getBriberyLineSize(); b++) {
//wake up the customer
picClerks[c]->getLine()->wakeUpNextInLine();
}
}
}
for(int c = 0; c < theOffice->getNumPasClerks(); c++){
if (pasClerks[c]->getLine()->getTotalLineSize() >= 1) {
//Send everyone in the line outside
for (int b = 0; b < pasClerks[c]->getLine()->getBriberyLineSize(); b++) {
//wake up the customer
pasClerks[c]->getLine()->wakeUpNextInLine();
}
}
}
for(int c = 0; c < theOffice->getNumCashiers(); c++){
if (cashiers[c]->getLine()->getTotalLineSize() >= 1) {
//Send everyone in the line outside
for (int b = 0; b < cashiers[c]->getLine()->getBriberyLineSize(); b++) {
//wake up the customer
cashiers[c]->getLine()->wakeUpNextInLine();
}
}
}
sendOutside = false;
outsideLock->ReleaseLock();
}
*/
/*CLERK FUNCTIONS
//----------------------------------------------------------------------
// Clerk::Clerk
// Initialize a Clerk, so that it can be used for clerking.
//
// "name" is an arbitrary name, useful for debugging.
//----------------------------------------------------------------------*/
struct Clerk CreateClerk(char* _name, int _number, struct PassportOffice* _theOffice, struct Line* theLine)
{
struct Clerk theClerk;
theClerk.name = _name;
theClerk.number = _number;
theClerk.theOffice = _theOffice;
theClerk.myLine = theLine;
LineSetClerk(theClerk.myLine,&theClerk);
theClerk.dataLock = CreateLock("dataLock",8);
theClerk.myBribeCV = CreateCV("myBribeCV",9);
theClerk.breakCV = CreateCV("breakCV",7);
theClerk.breakLock = CreateLock("breakLock",9);
theClerk.walkUpCV = CreateCV("walkUpCV",8);
return theClerk;
}
/*----------------------------------------------------------------------
// Clerk::~Clerk()
//
// De-Initialize a Clerk, remove all the memory.
//----------------------------------------------------------------------*/
void DeleteClerk(struct Clerk theDude) {
/*free theDude.myLine;*/
DestroyLock(theDude.dataLock);
DestroyCV(theDude.myBribeCV);
DestroyCV(theDude.breakCV);
DestroyLock(theDude.breakLock);
DestroyCV(theDude.walkUpCV);
}
/*----------------------------------------------------------------------
// Clerk::getState
// Returns an integer value representing the state of a clerk.
//
// 0 ~ Available
// 1 ~ With Customer
// 2 ~ On Break
//----------------------------------------------------------------------*/
int ClerkGetState(struct Clerk theDude) {
return theDude.clerkState;
}
/*----------------------------------------------------------------------
// Clerk::getLine
// Returns a Line variable from the clerk. This is used by the Passport
// Office to send customers to the shortest lines.
//----------------------------------------------------------------------*/
struct Line* ClerkGetLine(struct Clerk theDude) {
return theDude.myLine;
}
/*----------------------------------------------------------------------
// Clerk::getDataLock
// Returns a Lock that is used for data sharing between the customer
// and the clerk.
//----------------------------------------------------------------------*/
int ClerkGetDataLock(struct Clerk theDude) {
return theDude.dataLock;
}
/*----------------------------------------------------------------------
// Clerk::setState
// Changes the state of a Clerk.
//
// 0 ~ Available
// 1 ~ With Customer
// 2 ~ On Break
//----------------------------------------------------------------------*/
void ClerkSetState(struct Clerk theDude, int newState) {
theDude.clerkState = newState;
}
/*----------------------------------------------------------------------
// Clerk::getBribeCV
// Returns the Bribery Condition Variable. The customer calls this when
// he or she is giving his or her bribe to the Clerk.
//----------------------------------------------------------------------*/
int ClerkGetBribeCV(struct Clerk theDude) {
return theDude.myBribeCV;
}
/*----------------------------------------------------------------------
// Clerk::noCustomerAtRegister
// This method checks the bribe line, and then the normal line, to see
// if any customers can be called up to the register. If there is one,
// call him or her up. The bribe line is checked first.
//
// myLineLock is the Lock the Clerk owns to ensure no one enters,
// bribes through, or exits the line while the Clerk checks it.
// myLine is the Line object that contains both the Bribery and Normal
// lines.
//----------------------------------------------------------------------*/
void ApplicationClerkNoCustomerAtRegister(struct ApplicationClerk theDude) {
/*Step One
//Check if there is a customer in line*/
int myLineLock = LineGetLineLock(theDude.myClerk.myLine);
AcquireLock(myLineLock);
if (LineGetBriberyLineSize(theDude.myClerk.myLine) == 0) {
if (LineGetNormalLineSize(theDude.myClerk.myLine) == 0) {
/*Go on break!*/
AcquireLock(theDude.myClerk.breakLock);
ReleaseLock(myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is going on break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 2;
WaitCV(theDude.myClerk.breakCV,theDude.myClerk.breakLock);
ReleaseLock(theDude.myClerk.breakLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is coming off break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 0;
return ApplicationClerkNoCustomerAtRegister(theDude);
} else {
AcquireLock(theDude.myClerk.dataLock);
/*Wake up the leading guy in this line*/
LineWakeUpNextInLine(theDude.myClerk.myLine);
/*and print out that I did it.*/
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(theDude.myClerk.number);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return ApplicationClerkYesCustomerAtRegister(theDude,0);
}
} else {
/*Wake up the leading guy in this line*/
AcquireLock(theDude.myClerk.dataLock);
LineWakeUpNextInLine(theDude.myClerk.myLine);
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return ApplicationClerkYesCustomerAtRegister(theDude,1);
}
}
void PictureClerkNoCustomerAtRegister(struct PictureClerk theDude) {
/*Step One
//Check if there is a customer in line*/
int myLineLock = LineGetLineLock(theDude.myClerk.myLine);
AcquireLock(myLineLock);
if (LineGetBriberyLineSize(theDude.myClerk.myLine) == 0) {
if (LineGetNormalLineSize(theDude.myClerk.myLine) == 0) {
/*Go on break!*/
AcquireLock(theDude.myClerk.breakLock);
ReleaseLock(myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is going on break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 2;
WaitCV(theDude.myClerk.breakCV,theDude.myClerk.breakLock);
ReleaseLock(theDude.myClerk.breakLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is coming off break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 0;
return PictureClerkNoCustomerAtRegister(theDude);
} else {
AcquireLock(theDude.myClerk.dataLock);
/*Wake up the leading guy in this line*/
LineWakeUpNextInLine(theDude.myClerk.myLine);
/*and print out that I did it.*/
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(theDude.myClerk.number);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return PictureClerkYesCustomerAtRegister(theDude,0);
}
} else {
/*Wake up the leading guy in this line*/
AcquireLock(theDude.myClerk.dataLock);
LineWakeUpNextInLine(theDude.myClerk.myLine);
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return PictureClerkYesCustomerAtRegister(theDude,1);
}
}
void PassportClerkNoCustomerAtRegister(struct PassportClerk theDude) {
/*Step One
//Check if there is a customer in line*/
int myLineLock = LineGetLineLock(theDude.myClerk.myLine);
AcquireLock(myLineLock);
if (LineGetBriberyLineSize(theDude.myClerk.myLine) == 0) {
if (LineGetNormalLineSize(theDude.myClerk.myLine) == 0) {
/*Go on break!*/
AcquireLock(theDude.myClerk.breakLock);
ReleaseLock(myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is going on break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 2;
WaitCV(theDude.myClerk.breakCV,theDude.myClerk.breakLock);
ReleaseLock(theDude.myClerk.breakLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is coming off break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 0;
return PassportClerkNoCustomerAtRegister(theDude);
} else {
AcquireLock(theDude.myClerk.dataLock);
/*Wake up the leading guy in this line*/
LineWakeUpNextInLine(theDude.myClerk.myLine);
/*and print out that I did it.*/
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(theDude.myClerk.number);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return PassportClerkYesCustomerAtRegister(theDude,0);
}
} else {
/*Wake up the leading guy in this line*/
AcquireLock(theDude.myClerk.dataLock);
LineWakeUpNextInLine(theDude.myClerk.myLine);
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return PassportClerkYesCustomerAtRegister(theDude,1);
}
}
void CashierNoCustomerAtRegister(struct Cashier theDude) {
/*Step One
//Check if there is a customer in line*/
int myLineLock = LineGetLineLock(theDude.myClerk.myLine);
AcquireLock(myLineLock);
if (LineGetBriberyLineSize(theDude.myClerk.myLine) == 0) {
if (LineGetNormalLineSize(theDude.myClerk.myLine) == 0) {
/*Go on break!*/
AcquireLock(theDude.myClerk.breakLock);
ReleaseLock(myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is going on break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 2;
WaitCV(theDude.myClerk.breakCV,theDude.myClerk.breakLock);
ReleaseLock(theDude.myClerk.breakLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" ", 2, ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" is coming off break \n", 25, ConsoleOutput);
theDude.myClerk.clerkState = 0;
return CashierNoCustomerAtRegister(theDude);
} else {
AcquireLock(theDude.myClerk.dataLock);
/*Wake up the leading guy in this line*/
LineWakeUpNextInLine(theDude.myClerk.myLine);
/*and print out that I did it.*/
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(theDude.myClerk.number);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return CashierYesCustomerAtRegister(theDude,0);
}
} else {
/*Wake up the leading guy in this line*/
AcquireLock(theDude.myClerk.dataLock);
LineWakeUpNextInLine(theDude.myClerk.myLine);
WaitCV(theDude.myClerk.walkUpCV,myLineLock);
Write(theDude.myClerk.name, sizeof(theDude.myClerk.name), ConsoleOutput);
PrintInt(theDude.myClerk.number);
Write(" has signalled Customer ", 30, ConsoleOutput);
PrintInt(CustomerGetNumber(theDude.myClerk.myCustomer));
Write(" to come to their counter. \n", 30, ConsoleOutput);
ReleaseLock(myLineLock);
return CashierYesCustomerAtRegister(theDude,1);
}
}
/*----------------------------------------------------------------------
// Clerk::yesCustomerAtRegister(bool isBribed)
// The default method for having a customer at a Clerk's register. The
// default method includes what is in common with all the Clerks:
// changing state, and taking bribe money.
//
// myBribeCV -- This is the Condition Variable used to take a bribe
// from a Customer in the bribe line.
//----------------------------------------------------------------------*/
/*void ClerkYesCustomerAtRegister(struct Clerk theDude,int isBribed) {
Step Zero
//Change state to with customer
theDude.clerkState = 1;
Step One
//Wait for the customer to bribe.
//If he or she has bribed, take his or her $500 and put it into the pot
//Clerk has dataLock here.
WaitCV(theDude.myBribeCV,theDude.dataLock);
if (isBribed == 1) {
ClerkTakeBribeMoney(theDude,500);
printf("%s %d has received $500 from Customer %d \n", name.c_str(), number, myCustomer->getNumber());
}
}*/
/*----------------------------------------------------------------------
// Clerk::Run
//
//----------------------------------------------------------------------*/
void ApplicationClerkRun(struct ApplicationClerk theDude) {
ApplicationClerkNoCustomerAtRegister(theDude);
}
void PictureClerkRun(struct PictureClerk theDude) {
PictureClerkNoCustomerAtRegister(theDude);
}
void PassportClerkRun(struct PassportClerk theDude) {
PassportClerkNoCustomerAtRegister(theDude);
}
void CashierRun(struct Cashier theDude) {
CashierNoCustomerAtRegister(theDude);
}
/*Application Clerk Public Methods
//----------------------------------------------------------------------
// ApplicationClerk::ApplicationClerk
// Initializes the ApplicationClerk object.
//
// name is used for debugging.
//----------------------------------------------------------------------*/
struct ApplicationClerk CreateApplicationClerk(char* _name, int _number, struct PassportOffice* _theOffice)
{
struct ApplicationClerk theBro;
theAppLines[_number] = CreateLine();
theBro.myClerk = CreateClerk(_name, _number, _theOffice, &theAppLines[_number]);
theBro.myApplicationCV = CreateCV("myApplicationCV",15);
PassportOfficeIncrementInitClerks();
if (PassportOfficeGetInitClerks() == PassportOfficeGetNumTotalClerks()) {
PassportOfficeAllClerksInitialized();
}
return theBro;
}
void DeleteApplicationClerk(struct ApplicationClerk theBro)
{
DestroyCV(theBro.myApplicationCV);
}
/*----------------------------------------------------------------------
// ApplicationClerk::takeBribeMoney
// This method tells the Passport Object to take and store a certain
// amount of money (usually $500) into the Application Clerk's pool.
//
// theOffice is the pointer of the Passport Office.
// tookBribe is a boolean value used to show the bribe has been taken.
//----------------------------------------------------------------------*/
void ClerkTakeBribeMoney(struct Clerk theBro, int money) {
theBro.tookBribe = true;
}
void ApplicationClerkTakeBribeMoney(struct ApplicationClerk theBro, int money) {
PassportOfficeAddMoneyToApplicationClerks(money);
theBro.myClerk.tookBribe = true;
}
/*----------------------------------------------------------------------
// ApplicationClerk::getApplicationCV
// This method returns the condition variable used for data sharing
// between the Customer and the Application Clerk.
//----------------------------------------------------------------------*/
int ApplicationClerkGetApplicationCV(struct ApplicationClerk theBro) {
return theBro.myApplicationCV;
}
/*----------------------------------------------------------------------
// ApplicationClerk::takeApplication
// This method tells the Application Clerk that the customer has given
// his or her application to the Clerk.
//
// customerHasApplication is the ApplicationClerk's own boolean
// variable to check later on if the customer indeed gave him or her
// the application.
//----------------------------------------------------------------------*/
void ApplicationClerkTakeApplication(struct ApplicationClerk theBro, int hasApplication){
theBro.customerHasApplication = hasApplication;
}
/*----------------------------------------------------------------------
// ApplicationClerk::takeSocialSecurityNumber
// This method tells the Application Clerk that the customer has given
// his or her Social Security Number to the Clerk.
//
// customerHasSocialSecurityNumber is the ApplicationClerk's own
// boolean variable to check later on if the customer indeed gave him
// or her the number.
//----------------------------------------------------------------------*/
void ApplicationClerkTakeSocialSecurityNumber(struct ApplicationClerk theBro, int hasSocialSecurityNumber) {
theBro.customerHasSocialSecurityNumber = hasSocialSecurityNumber;
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received SSN ", 20, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" from Customer ", 20, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 3, ConsoleOutput);
}
/*----------------------------------------------------------------------
// Clerk::goOnBreak
// This method tells the Clerk to go to sleep. When woken up by the
// manager, he or she will check the customer in line.
//
// I'd like to implement this on the Clerk class, but I don't think
// I can call noCustomerAtRegister because it is a Clerk specific
// method.
//----------------------------------------------------------------------*/
/*void Clerk::goOnBreak() {
currentThread->Sleep();
noCustomerAtRegister(); //How to call this?
//How to do this?
}*/
/*----------------------------------------------------------------------
// ApplicationClerk::yesCustomerAtRegister
// This method goes through the ApplicationClerk's routine with a
// customer. First, he or she waits for the customer to bribe (or
// not). Then, he or she waits for the customer to give his or her
// application and social security. Then the Clerk is woken up by the
// customer and checks to ensure both daya is there. If it is both
// there, the Clerk waits for 20 to 100 (currentThread->Yield()) and
// then gives the customer his or her recorded application.
//
// myBribeCV is the Condition Variable used to wait for the bribe.
// myApplicationCV is the Condition Variable used to wait for the
// customer to send data to the clerk.
// dataLock is the lock used by the Condition Variable to send data
// back and forth between customer and clerk.
// myCustomer is the pointer to the current customer.
// clerkState is the integer state of the Clerk.
//----------------------------------------------------------------------*/
void ApplicationClerkYesCustomerAtRegister(struct ApplicationClerk theBro, int isBribed) {
int yieldTime;
int y;
/*ClerkYesCustomerAtRegister(theBro.myClerk, isBribed);*/
/*Step Zero
//Change state to with customer*/
theBro.myClerk.clerkState = 1;
/*Step One
//Wait for the customer to bribe.
//If he or she has bribed, take his or her $500 and put it into the pot
//Clerk has dataLock here.*/
WaitCV(theBro.myClerk.myBribeCV,theBro.myClerk.dataLock);
if (isBribed == 1) {
ApplicationClerkTakeBribeMoney(theBro,500);
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received $500 from Customer ", 40, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 5, ConsoleOutput);
}
/*Step Two
//Customer gives me his or her completed application and his or her social security number.
Step Three
//If customer does NOT have both data:
//~an error has occurred with the customer.
//~print this out
//~give customer his or her missing data*/
AcquireLock(theBro.myClerk.dataLock);
if (!theBro.customerHasApplication || !theBro.customerHasSocialSecurityNumber) {
WaitCV(theBro.myApplicationCV,theBro.myClerk.dataLock);
}
ReleaseLock(theBro.myClerk.dataLock);
/*Step Four
//Thread->Yield() for 20 to 100 ( it is random), then:
//'Record' the customer into the data system.
//That really just means give customer a piece of data that means they finished this step.
//Tell customer he or she has been filed.*/
yieldTime = GetRand() % 80 + 20;
for ( y = 0; y < yieldTime; y++) {
Yield();
}
AcquireLock(theBro.myClerk.dataLock);
CustomerGiveFiledApplication(theBro.myClerk.myCustomer,1);
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has recorder a completed application for Customer ", 60, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 3, ConsoleOutput);
SignalCV(theBro.myApplicationCV,theBro.myClerk.dataLock);
ReleaseLock(theBro.myClerk.dataLock);
/*Step Five
//Customer Leaves
//Clear all customer data*/
theBro.customerHasApplication = 0;
theBro.customerHasSocialSecurityNumber = 0;
theBro.myClerk.tookBribe = 0;
theBro.myClerk.myCustomer = NULL;
/*Set state*/
theBro.myClerk.clerkState = 0;
/*Step Six
//call - When there is no customer at the register();*/
ApplicationClerkNoCustomerAtRegister(theBro);
}
/*Picture Clerk Methods*/
struct PictureClerk CreatePictureClerk(char* _name, int _number, struct PassportOffice _theOffice) {
struct PictureClerk theBro;
thePicLines[_number] = CreateLine();
theBro.myClerk = CreateClerk(_name, _number, &_theOffice, &thePicLines[_number]);
theBro.customerHasSocialSecurityNumber = 0;
theBro.isPictureLiked = 0;
theBro.myPictureCV = CreateCV("myPictureCV",11);
PassportOfficeIncrementInitClerks();
if (PassportOfficeGetInitClerks() == PassportOfficeGetNumTotalClerks()) {
PassportOfficeAllClerksInitialized();
}
return theBro;
}
void DestroyPictureClerk(struct PictureClerk theBro)
{
DestroyCV(theBro.myPictureCV);
}
void PictureClerkTakeSocialSecurity(struct PictureClerk theBro,int num) {
theBro.customerHasSocialSecurityNumber = num;
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received SSN ", 20, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" from Customer ", 20, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 3, ConsoleOutput);
}
/*----------------------------------------------------------------------
// PictureClerk::takeBribeMoney
// This method tells the Passport Object to take and store a certain
// amount of money (usually $500) into the Picture Clerk's pool.
//
// theOffice is the pointer of the Passport Office.
// tookBribe is a boolean value used to show the bribe has been taken.
//----------------------------------------------------------------------*/
void PictureClerkTakeBribeMoney(struct PictureClerk theBro,int money) {
PassportOfficeAddMoneyToPictureClerks(money);
theBro.myClerk.tookBribe = 1;
}
void PictureClerkSetPictureDecisionMade(struct PictureClerk theBro, int decision) {
theBro.pictureDecisionMade = decision;
}
/*----------------------------------------------------------------------
// PictureClerk::yesCustomerAtRegister
// This method goes through the PictureClerk's routine with a
// customer. First, he or she waits for the customer to bribe (or
// not). Then, he or she gives the customer his or her picture. If the
// customer likes it, the Clerk waits for 20 to 100
// (currentThread->Yield()) and then gives the customer his or her
// recorded picture.
//
// myBribeCV is the Condition Variable used to wait for the bribe.
// myPictureCV is the Condition Variable used to wait for the
// customer to send data to the clerk.
// dataLock is the lock used by the Condition Variable to send data
// back and forth between customer and clerk.
// myCustomer is the pointer to the current customer.
// clerkState is the integer state of the Clerk.
//----------------------------------------------------------------------*/
void PictureClerkYesCustomerAtRegister(struct PictureClerk theBro, int isBribed) {
int yieldTime;
int y;
/*ClerkYesCustomerAtRegister(theBro.myClerk, isBribed);*/
/*Step Zero
//Change state to with customer*/
theBro.myClerk.clerkState = 1;
/*Step One
//Wait for the customer to bribe.
//If he or she has bribed, take his or her $500 and put it into the pot
//Clerk has dataLock here.*/
WaitCV(theBro.myClerk.myBribeCV,theBro.myClerk.dataLock);
if (isBribed == 1) {
PictureClerkTakeBribeMoney(theBro,500);
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received $500 from Customer ", 40, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 5, ConsoleOutput);
}
/*Step Two
//I take the customer's picture
//This takes 20 to 100 yield()
//After waking up, of course*/
AcquireLock(theBro.myClerk.dataLock);
if(!theBro.customerHasSocialSecurityNumber){
WaitCV(theBro.myPictureCV,theBro.myClerk.dataLock);
}
ReleaseLock(theBro.myClerk.dataLock);
yieldTime = GetRand() % 80 + 20;
for (y = 0; y < yieldTime; y++) {
Yield();
}
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has taken a picture of Customer ", 40, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" \n", 5, ConsoleOutput);
/*Now give customer his or her picture*/
AcquireLock(theBro.myClerk.dataLock);
CustomerGivePicture(theBro.myClerk.myCustomer, 1);
SignalCV(theBro.myPictureCV,theBro.myClerk.dataLock);
ReleaseLock(theBro.myClerk.dataLock);
AcquireLock(theBro.myClerk.dataLock);
if(theBro.pictureDecisionMade == 0) {
WaitCV(theBro.myPictureCV,theBro.myClerk.dataLock);
}
if(theBro.isPictureLiked == 1) {
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has been told that Customer ", 30, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" does like their picture \n", 30, ConsoleOutput);
yieldTime = GetRand() % 80 + 20;
for (y = 0; y < yieldTime; y++) {
Yield();
}
/*Give customer filed picture*/
CustomerGiveFiledPicture(theBro.myClerk.myCustomer, 1);
SignalCV(theBro.myPictureCV,theBro.myClerk.dataLock);
}
else{
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has been told that Customer ", 30, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" does not like their picture \n", 40, ConsoleOutput);
}
ReleaseLock(theBro.myClerk.dataLock);
/*Customer Leaves
//Clear all customer data*/
theBro.isPictureLiked = 0;
theBro.myClerk.tookBribe = 0;
theBro.pictureDecisionMade = 0;
/*Set state*/
theBro.myClerk.clerkState = 0;
theBro.myClerk.myCustomer = NULL;
/*Step Six
//call - When there is no customer at the register();*/
return PictureClerkNoCustomerAtRegister(theBro);
}
/*PassportClerk Methods*/
struct PassportClerk CreatePassportClerk(char* _name, int _number, struct PassportOffice _theOffice) {
struct PassportClerk theBro;
thePasLines[_number] = CreateLine();
theBro.myClerk = CreateClerk(_name, _number, &_theOffice, &thePasLines[_number]);
theBro.customerHasRecordedDocuments = 0;
theBro.customerHasSocialSecurityNumber = 0;
theBro.customerHasFiledApplication = 0;
theBro.customerHasPicture = 0;
theBro.myPassportCV = CreateCV("myPassportCV",12);
PassportOfficeIncrementInitClerks();
if (PassportOfficeGetInitClerks() == PassportOfficeGetNumTotalClerks()) {
PassportOfficeAllClerksInitialized();
}
return theBro;
}
void DestroyPassportClerk(struct PassportClerk theBro)
{
DestroyCV(theBro.myPassportCV);
}
void PassportClerkTakeSocial(struct PassportClerk theBro,int hasSocial) {
theBro.customerHasSocialSecurityNumber = hasSocial;
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received SSN ", 20, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" from Customer ", 20, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" \n", 3, ConsoleOutput);
}
void PassportClerkTakeBribeMoney(struct PassportClerk theBro,int money) {
PassportOfficeAddMoneyToPassportClerks(money);
theBro.myClerk.tookBribe = 1;
}
void PassportClerkYesCustomerAtRegister(struct PassportClerk theBro,int isBribed) {
int yieldTime, y;
/*ClerkYesCustomerAtRegister(theBro.myClerk, isBribed);*/
/*Step Zero
//Change state to with customer*/
theBro.myClerk.clerkState = 1;
/*Step One
//Wait for the customer to bribe.
//If he or she has bribed, take his or her $500 and put it into the pot
//Clerk has dataLock here.*/
WaitCV(theBro.myClerk.myBribeCV,theBro.myClerk.dataLock);
if (isBribed == 1) {
PassportClerkTakeBribeMoney(theBro,500);
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received $500 from Customer ", 40, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 5, ConsoleOutput);
}
AcquireLock(theBro.myClerk.dataLock);
if(!theBro.customerHasSocialSecurityNumber) {
WaitCV(theBro.myPassportCV,theBro.myClerk.dataLock);
}
if(theBro.customerHasPicture == 0 || theBro.customerHasFiledApplication == 0) {
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has determined that Customer ", 35, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" does not have both their application and picture completed \n", 70, ConsoleOutput);
CustomerSendBackToStart(theBro.myClerk.myCustomer);
}
else{
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has determined that Customer ", 35, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" has both their application and picture completed \n", 60, ConsoleOutput);
/*if so, give customer his or her Recognition after waiting*/
yieldTime = GetRand() % 80 + 20;
for (y = 0; y < yieldTime; y++) {
Yield();
}
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has recorded Customer ", 25, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" 's passport documentation \n", 35, ConsoleOutput);
CustomerGiveRecordedDocuments(theBro.myClerk.myCustomer,1);
}
CustomerCheckRequiredDocumentsForPassportClerk(theBro.myClerk.myCustomer,1);
/*Now wake customer up*/
SignalCV(theBro.myPassportCV,theBro.myClerk.dataLock);
ReleaseLock(theBro.myClerk.dataLock);
/*Customer Leaves
//Clear all customer data*/
theBro.customerHasFiledApplication = 0;
theBro.customerHasPicture = 0;
theBro.myClerk.tookBribe = 0;
/*Set state*/
theBro.myClerk.clerkState = 0;
theBro.myClerk.myCustomer = NULL;
/*Step Six
//call - When there is no customer at the register();*/
return PassportClerkNoCustomerAtRegister(theBro);
}
/*Cashier Methods*/
struct Cashier CreateCashier(char* _name, int _number, struct PassportOffice _theOffice) {
struct Cashier theBro;
theCasLines[_number] = CreateLine();
theBro.myClerk = CreateClerk(_name, _number, &_theOffice, &theCasLines[_number]);
theBro.customerHasFiledApplication = 0;
theBro.customerHasRecordedDocuments = 0;
theBro.customerHasPicture = 0;
theBro.tookBribe = 0;
theBro.tookMoney = 0;
theBro.myCashierCV = CreateCV("myCashierCV",11);
PassportOfficeIncrementInitClerks();
if (PassportOfficeGetInitClerks() == PassportOfficeGetNumTotalClerks()) {
PassportOfficeAllClerksInitialized();
}
return theBro;
}
void DestroyCashier(struct Cashier theBro)
{
DestroyCV(theBro.myCashierCV);
}
void CashierTakeBribeMoney(struct Cashier theBro,int money){
PassportOfficeAddMoneyToCashiers(money);
theBro.tookBribe = 1;
}
void CashierTakeCustMoney(struct Cashier theBro,int money){
PassportOfficeAddMoneyToCashiers(money);
if (money >= 100) {
theBro.tookMoney = 1;
}
}
void CashierRecordPassportForCustomer(struct Cashier theBro,struct Customer* cust) {
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has recorded that Customer ", 30, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" has been given their completed passport \n", 45, ConsoleOutput);
}
void CashierTakeSocial(struct Cashier theBro,int hasSocial) {
theBro.customerHasSocialSecurityNumber = hasSocial;
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received SSN ", 20, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" from Customer ", 20, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" \n", 3, ConsoleOutput);
}
void CashierYesCustomerAtRegister(struct Cashier theBro,int isBribed) {
/*ClerkYesCustomerAtRegister(theBro.myClerk, isBribed);*/
/*Step Zero
//Change state to with customer*/
theBro.myClerk.clerkState = 1;
/*Step One
//Wait for the customer to bribe.
//If he or she has bribed, take his or her $500 and put it into the pot
//Clerk has dataLock here.*/
WaitCV(theBro.myClerk.myBribeCV,theBro.myClerk.dataLock);
if (isBribed == 1) {
CashierTakeBribeMoney(theBro,500);
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received $500 from Customer ", 40, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 5, ConsoleOutput);
}
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received SSN ", 20, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" from Customer ", 20, ConsoleOutput);
PrintInt(CustomerGetNumber(theBro.myClerk.myCustomer));
Write(" \n", 3, ConsoleOutput);
AcquireLock(theBro.myClerk.dataLock);
if(theBro.customerHasSocialSecurityNumber == 0) {
WaitCV(theBro.myCashierCV,theBro.myClerk.dataLock);
}
if(theBro.customerHasRecordedDocuments == 0) {
CustomerSendBackToStart(theBro.myClerk.myCustomer);
}
else{
CustomerCheckRequiredDocumentsForCashier(theBro.myClerk.myCustomer,1);
Write("Cashier ", 10, ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has verified that Customer ", 30, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" has been certified by a PassportClerk \n", 45, ConsoleOutput);
}
SignalCV(theBro.myCashierCV,theBro.myClerk.dataLock);
ReleaseLock(theBro.myClerk.dataLock);
if(theBro.customerHasRecordedDocuments) {
AcquireLock(theBro.myClerk.dataLock);
if(theBro.tookMoney == 0) {
WaitCV(theBro.myCashierCV,theBro.myClerk.dataLock);
}
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has received the $100 for Customer ", 40, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" after certification \n", 25, ConsoleOutput);
CustomerAcceptedMoney(theBro.myClerk.myCustomer, 1);
CustomerGivePassport(theBro.myClerk.myCustomer,1);
Write(theBro.myClerk.name, sizeof(theBro.myClerk.name), ConsoleOutput);
PrintInt(theBro.myClerk.number);
Write(" has provided Customer ", 25, ConsoleOutput);
PrintInt(GetCustomerNumber(theBro.myClerk.myCustomer));
Write(" their completed passport \n", 30, ConsoleOutput);
SignalCV(theBro.myCashierCV,theBro.myClerk.dataLock);
ReleaseLock(theBro.myClerk.dataLock);
}
/*Wait for customer to leave*/
WaitCV(theBro.myCashierCV,theBro.myClerk.dataLock);
/*Customer Leaves*/
/*Clear all customer data*/
theBro.customerHasFiledApplication = 0;
theBro.customerHasPicture = 0;
theBro.customerHasRecordedDocuments = 0;
theBro.tookBribe = 0;
/*Set state*/
theBro.myClerk.clerkState = 0;
theBro.myClerk.myCustomer = NULL;
/*Step Six
//call - When there is no customer at the register();*/
return CashierNoCustomerAtRegister(theBro);
}
/*CUSTOMER FUNCTIONS*/
struct Customer CreateCustomer(char* _name, int social, int cash, struct PassportOffice _theOffice) {
struct Customer theGnar;
theGnar.name = _name;
theGnar.socialSecurityNumber = social;
theGnar.money = cash;
theGnar.theOffice = &_theOffice;
theGnar.hasApplication = 1;
theGnar.hasSocial = 1;
return theGnar;
}
void DestroyCustomer(struct Customer theGnar) {
}
/*----------------------------------------------------------------------
// Customer::enterPassportOffice
// This is the first step in the routine of the Customer. He or she
// enters the passport office. Then he or she moves on...
//----------------------------------------------------------------------*/
void CustomerEnterPassportOffice(struct Customer theGnar) {
/*Step One
//Enter the passport office*/
theGnar.hasEnteredPassportOffice = 1;
PassportOfficeIncrementCustomerCounter();
/*Lock *senatorLock = theOffice->getSenatorLock();
senatorLock->AcquireLock();
if (isSenator){
//Wait for everyone to finish and move outside
Condition *senatorCV = theOffice->getSenatorCV();
theOffice->setSenatorInOffice(isSenator);
theOffice->changeNumSenatorsInOffice(1);
senatorCV->WaitCV(senatorLock);
senatorLock->ReleaseLock();
Lock* outsideLock = theOffice->getOutsideLock();
outsideLock->AcquireLock();
} else if (theOffice->isSenatorInOffice()) {
//Wait in the outside line
Lock *outsideLock = theOffice->getOutsideLock();
Condition *outsideCV = theOffice->getOutsideCV();
//Acquire the lock, then wait until the senator is gone
outsideLock->AcquireLock();
senatorLock->ReleaseLock();
theOffice->decrementCustomerCounter();
printf("Customer %d is going outside the Passport Office because there is a Senator present.\n", socialSecurityNumber);
outsideCV->WaitCV(outsideLock);
outsideLock->ReleaseLock();
} else {
senatorLock->ReleaseLock();
}
//Now choose a line to enter*/
CustomerChooseApplicationOrPictureClerk(theGnar);
}
/*----------------------------------------------------------------------
// Customer::chooseApplicationOrPictureClerk
// This is the second step in the customer's routine. He or she
// randomly chooses (50%) to get their application filed or their
// picture taken first. Then he or she will get in line.
//----------------------------------------------------------------------*/
void CustomerChooseApplicationOrPictureClerk(struct Customer theGnar) {
/*Step Two
//Randomly choose applicationClerk or pictureClerk*/
theGnar.lineChoice = (GetRand()%2 == 1) ? APPLICATION : PICTURE;
return CustomerEnterLine(theGnar);
}
/*----------------------------------------------------------------------
// Customer::enterLine()
// This method puts a Customer Thread in the correct line. The choice
// to bribe (50%) is made here, while lineChoice has been made
// beforehand.
//
//
//----------------------------------------------------------------------*/
void CustomerEnterLine(struct Customer theGnar){
/*Lock *senatorLock = theOffice->getSenatorLock();
senatorLock->AcquireLock();
if (theOffice->isSenatorInOffice() && !isSenator){
//Then go outside
//and print about it
Lock *outsideLock = theOffice->getOutsideLock();
Condition *outsideCV = theOffice->getOutsideCV();
//Acquire the lock, then wait until the senator is gone
outsideLock->AcquireLock();
senatorLock->ReleaseLock();
theOffice->decrementCustomerCounter();
printf("Customer %d is going outside the Passport Office because their is a Senator present.\n", socialSecurityNumber);
outsideCV->WaitCV(outsideLock);
outsideLock->ReleaseLock();
} else {
senatorLock->ReleaseLock();
}*/
/*struct Clerk* myClerk; Why was this here?*/
/*Bribe? Only if I am not a senator and have the money
if (!isSenator) {
*/theGnar.isNowBribing = (theGnar.money >= 600 && (GetRand() % 2 == 1));
theGnar.myClerk = PassportOfficeEnterShortestLine(theGnar, theGnar.lineChoice, theGnar.isNowBribing);
/*if (theOffice->isSenatorInOffice() && !isSenator){
//Then go outside
//and print about it
Lock *outsideLock = theOffice->getOutsideLock();
Condition *outsideCV = theOffice->getOutsideCV();
//Acquire the lock, then wait until the senator is gone
outsideLock->AcquireLock();
theOfice->decrementCustomerCounter();
printf("Customer %d is going outside the Passport Office because their is a Senator present.", socialSecurityNumber);
outsideCV->WaitCV(outsideLock);
outsideLock->ReleaseLock();
return enterLine;
}*/
CustomerDealWithClerk(theGnar,theGnar.myClerk);
}
void CustomerDealWithClerk(struct Customer theGnar,struct Clerk myClerk)
{
int dataLock;
int clerkBribeCV;
if (myClerk.clerkState == 0) {
/*set state to busy*/
ClerkSetState(myClerk,1);
}
/*Set Customer*/
ClerkSetCustomer(myClerk, &theGnar);
dataLock = ClerkGetDataLock(myClerk);
AcquireLock(dataLock);
/*if bribed: give clerk money*/
clerkBribeCV = ClerkGetBribeCV(myClerk);
if (theGnar.isNowBribing) {
/*Give Clerk my money*/
ClerkTakeBribeMoney(myClerk,500);
theGnar.money -= 500;
SignalCV(clerkBribeCV,dataLock); /*Clerk is waiting.
I have woken up, bribery is now over*/
theGnar.isNowBribing = false;
} else {
SignalCV(clerkBribeCV,dataLock);
/*Clerk is waiting for no bribe*/
}
if(theGnar.lineChoice == APPLICATION) {
return CustomerDealWithApplicationClerk(theGnar,theAppClerks[myClerk.number]);
}
if(theGnar.lineChoice == PICTURE) {
return CustomerDealWithPictureClerk(theGnar,thePicClerks[myClerk.number]);
}
if(theGnar.lineChoice == PASSPORT) {
return CustomerDealWithPassportClerk(theGnar,thePasClerks[myClerk.number]);
}
if(theGnar.lineChoice == CASHIER) {
return CustomerDealWithCashier(theGnar,theCasClerks[myClerk.number]);
}
}
/*----------------------------------------------------------------------
// Customer::walkUpToAndDealWithApplicationClerk
// Now the customer has reached the front of the line and is now
// approaching the register. If the customer has decided to bribe,
// he or she gives the clerk his or her bribe money.
//
// money is an integer variable describing the amount of money a
// customer has. At least 600 is needed to bribe.
// myClerk is the pointer of the clerk he or she is assigned to. This
// variable is given only when the clerk is at the front of the line.
// isNowBribing is a boolean variable reminding the customer to give
// the clerk the bribe money.
//----------------------------------------------------------------------*/
void CustomerDealWithApplicationClerk(struct Customer theGnar,struct ApplicationClerk myClerk) {
int clerkApplicationCV = ApplicationClerkGetApplicationCV(myClerk);
int dataLock = ClerkGetDataLock(myClerk.myClerk);
/*Give App Clerk my data*/
AcquireLock(dataLock);
ApplicationClerkTakeApplication(myClerk,theGnar.hasApplication);
ApplicationClerkTakeSocialSecurityNumber(myClerk,theGnar.hasSocial);
SignalCV(clerkApplicationCV,dataLock);
ReleaseLock(dataLock);
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has given SSN ", 20, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" to ApplicationClerk ", 25, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write(" \n", 3, ConsoleOutput);
AcquireLock(dataLock);
if (!theGnar.hasFiledApplication) {
WaitCV(clerkApplicationCV,dataLock);
}
ReleaseLock(dataLock);
/*Leave Clerk
//Get into pic line if I don't have my picture*/
if (theGnar.hasPicture == 0) {
theGnar.lineChoice = PICTURE;
} else {
/*Get into a PassportClerkLine*/
theGnar.lineChoice = PASSPORT;
}
return CustomerEnterLine(theGnar);
}
void CustomerDealWithPictureClerk(struct Customer theGnar,struct PictureClerk myClerk) {
int clerkPictureCV = PictureClerkGetPictureCV(myClerk);
int dataLock = ClerkGetDataLock(myClerk.myClerk);
int randNum;
AcquireLock(dataLock);
/*Give Clerk my Social Security Number*/
PictureClerkTakeSocialSecurity(myClerk,1);
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has given SSN ", 20, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" to ApplicationClerk ", 25, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write(" \n", 3, ConsoleOutput);
SignalCV(clerkPictureCV,dataLock);
ReleaseLock(dataLock);
/*Now choose if I like the picture or not*/
randNum = GetRand() % 100;
AcquireLock(dataLock);
if(randNum < 10) {
/*Didn't like it!*/
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" does not like their picture from PictureClerk ", 50, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write("\n",1,ConsoleOutput);
PictureClerkLikePicture(myClerk,0);
theGnar.hasPicture = 0;
}
else {
/*Liked it!*/
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" does like their picture from PictureClerk ", 45, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write("\n",1,ConsoleOutput);
PictureClerkLikePicture(myClerk,1);
theGnar.hasPicture = 1;
}
PictureClerkSetPictureDecisionMade(myClerk,1);
SignalCV(clerkPictureCV,dataLock);
ReleaseLock(dataLock);
AcquireLock(dataLock);
if(randNum > 10 && !theGnar.hasPicture) {
WaitCV(clerkPictureCV,dataLock);
}
ReleaseLock(dataLock);
if (!theGnar.hasFiledApplication) {
theGnar.lineChoice = APPLICATION;
} else {
theGnar.lineChoice = PASSPORT;
/*Get into a PassportClerkLine*/
}
return CustomerEnterLine(theGnar);
}
void CustomerDealWithPassportClerk(struct Customer theGnar,struct PassportClerk myClerk) {
int clerkPassportCV = PassportClerkGetPassportCV(myClerk);
int dataLock = ClerkGetDataLock(myClerk.myClerk);
int yieldTime;
int y;
AcquireLock(dataLock);
/*Give filed application and picture from customer*/
PassportClerkTakeFiledApplication(myClerk,theGnar.hasFiledApplication);
PassportClerkTakePicture(myClerk,theGnar.hasPicture);
PassportClerkTakeSocial(myClerk,1);
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has given SSN ", 20, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" to PassportClerk ", 20, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write(" \n", 3, ConsoleOutput);
SignalCV(clerkPassportCV,dataLock);
ReleaseLock(dataLock);
AcquireLock(dataLock);
if(!theGnar.passportClerkHasCheckedRequiredDocuments){
WaitCV(clerkPassportCV,dataLock);
}
ReleaseLock(dataLock);
if(theGnar.hasBeenSentBackToStart) {
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has gone to PassportClerk ", 30, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write(" too soon. They are going to the back of the line. \n", 55, ConsoleOutput);
/*I am punished.
//Yield for 100 to 1000*/
yieldTime = GetRand() % 900 + 100;
for (y = 0; y < yieldTime; y++) {
Yield();
}
theGnar.lineChoice = PASSPORT;
theGnar.hasBeenSentBackToStart = false;
}
else{
theGnar.lineChoice = CASHIER;
}
return CustomerEnterLine(theGnar);
}
void CustomerDealWithCashier(struct Customer theGnar,struct Cashier myClerk) {
int myCashierCV = CashierGetCashierCV(myClerk);
int dataLock = ClerkGetDataLock(myClerk.myClerk);
int yieldTime, y;
/*Give social security and other documents*/
AcquireLock(dataLock);
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has given SSN ", 20, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" to Cashier ", 15, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write(" \n", 3, ConsoleOutput);
CashierTakeSocial(myClerk,1);
CashierTakeRecordedDocuments(myClerk,theGnar.hasRecordedDocuments);
CashierTakeFiledApplication(myClerk,theGnar.hasFiledApplication);
CashierTakePicture(myClerk,theGnar.hasPicture);
SignalCV(myCashierCV,dataLock);
ReleaseLock(dataLock);
/*Wait for cashier to give it a look*/
AcquireLock(dataLock);
if(!theGnar.cashierHasCheckedRequiredDocuments) {
WaitCV(myCashierCV,dataLock);
}
if(theGnar.hasBeenSentBackToStart) {
ReleaseLock(dataLock);
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has gone to Cashier ", 30, ConsoleOutput);
PrintInt(myClerk.myClerk.number);
Write(" too soon. They are going to the back of the line. \n", 55, ConsoleOutput);
/*I am punished.
//Yield for 100 to 1000*/
yieldTime = GetRand() % 900 + 100;
for (y = 0; y < yieldTime; y++) {
Yield();
}
theGnar.lineChoice = CASHIER;
theGnar.hasBeenSentBackToStart = 0;
return CustomerEnterLine(theGnar);
}
else{
SignalCV(myCashierCV,dataLock);
ReleaseLock(dataLock);
}
/*Give $100 to the cashier*/
AcquireLock(dataLock);
if (theGnar.money >= 100) {
theGnar.money -= 100;
CashierTakeCustMoney(myClerk,100);
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" has given Cashier ", 20, ConsoleOutput);
PrintInt(ClerkGetNumber(myClerk.myClerk));
Write("$100. \n", 10, ConsoleOutput);
}
SignalCV(myCashierCV,dataLock);
ReleaseLock(dataLock);
/*Wait for my passport!!!*/
AcquireLock(dataLock);
if(0==theGnar.hasPassport) {
WaitCV(myCashierCV,dataLock);
}
SignalCV(myCashierCV,dataLock);
ReleaseLock(dataLock);
/*Lock* senatorLock = theOffice->getSenatorLock();
senatorLock->AcquireLock();
if(isSenator) {
printf("Senator %d is leaving the Passport Office. \n", socialSecurityNumber);
theOffice->changeNumSenatorsInOffice(-1);
senatorLock->ReleaseLock();
}*/
Write("Customer ", 10, ConsoleOutput);
PrintInt(theGnar.socialSecurityNumber);
Write(" is leaving the Passport Office. \n", 35, ConsoleOutput);
PassportOfficeDecrementCustomerCounter();
}
/*LINE FUNCTIONS*/
struct Line CreateLine()
{
struct Line lion;
lion.lineLock = CreateLock("lineLock",8);
lion.normalLineCV = CreateCV("normalLineCV",12);
lion.bribeLineCV = CreateCV("bribeLineCV",11);
lion.normalLineSize = 0;
lion.briberyLineSize = 0;
return lion;
}
void DestoryLine(struct Line *lion)
{
DestroyLock(lion->lineLock);
DestroyCV(lion->normalLineCV);
DestroyCV(lion->bribeLineCV);
}
int LineGetTotalLineSize(struct Line *lion) {
return lion->briberyLineSize + lion->normalLineSize;
}
int LineGetBriberyLineSize(struct Line *lion) {
return lion->briberyLineSize;
}
int LineGetNormalLineSize(struct Line *lion) {
return lion->normalLineSize;
}
/*
int Line::getSenatorLineSize() {
return senatorLine.size();
}*/
void LineAddToBriberyLine(struct Line *lion,struct Customer* customer) {
lion->briberyLineSize++;
}
void LineAddToNormalLine(struct Line *lion,struct Customer* customer) {
lion->normalLineSize++;
}
/*void Line::addToSenatorLine(struct Customer* customer) {
senatorLine.push(customer);
}*/
void LineWakeUpNextInLine(struct Line *lion) {
/*if(!senatorLineSize == 0){
senatorLine.pop();
senatorLineCV->SignalCV(lineLock);
} else */if(!lion->briberyLineSize == 0){
lion->briberyLineSize--;
SignalCV(lion->bribeLineCV,lion->lineLock);
} else {
lion->normalLineSize--;
SignalCV(lion->normalLineCV,lion->lineLock);
}
}
/*PASSPORT OFFICE FUNCTIONS*/
struct PassportOffice CreatePassportOffice(int setClerks)
{
struct PassportOffice ppo;
ppo.findShortestApplicationLineLock = CreateLock("findShortestApplicationLineLock",31);
ppo.findShortestPictureLineLock = CreateLock("findShortestPictureLineLock",27);
ppo.findShortestPassportLineLock = CreateLock("findShortestPassportLineLock",28);
ppo.findShortestCashierLineLock = CreateLock("findShortestCashierLineLock",27);
ppo.finishInitializationLock = CreateLock("finishInitializationLock",24);
ppo.finishInitializationCV = CreateCV("finishInitializationCV",22);
AcquireLock(ppo.finishInitializationLock);
ppo.finishInitializationCV = CreateCV("finishInitializationCV",22);
ppo.numPicClerks = setClerks;
ppo.numAppClerks = setClerks;
ppo.numPasClerks = setClerks;
ppo.numCashiers = setClerks;
/*Should we really have these arrays if we are going to make these threads?
ppo.picClerks = thePicClerks;
ppo.appClerks = theAppClerks;
ppo.pasClerks = thePasClerks;
ppo.cashiers = theCasClerks;*/
ppo.applicationClerkMoney = 0;
ppo.pictureClerkMoney = 0;
ppo.passportClerkMoney = 0;
ppo.cashierMoney = 0;
ppo.customerCounter = 0;
ppo.appClerkCounter = 0;
ppo.picClerkCounter = 0;
ppo.pasClerkCounter = 0;
ppo.cashierCounter = 0;
ppo.appMoneyLock = CreateLock("appMoneyLock",12);
ppo.picMoneyLock = CreateLock("picMoneyLock",12);
ppo.pasMoneyLock = CreateLock("pasMoneyLock",12);
ppo.casMoneyLock = CreateLock("casMoneyLock",12);
/*outsideLock = CreateLock("Outside Lock");
//outsideCV = CreateCV("Outside CV");
//senatorLock = CreateLock("Senator Lock");
//senatorCV = CreateCV("Senator Condition");*/
ppo.manager = NULL;
return ppo;
}
void DestroyPassportOffice(struct PassportOffice ppo){
/*for(int i = 0; i < ppo.numPicClerks; i++){
delete &ppo.picClerks[i];
}
for(int i = 0; i < ppo.numAppClerks; i++){
delete &ppo.appClerks[i];
}
for(int i = 0; i < ppo.numPasClerks; i++){
delete &ppo.pasClerks[i];
}
for(int i = 0; i < ppo.numCashiers; i++){
delete &ppo.cashiers[i];
}
delete [] ppo.picClerks;
delete [] ppo.appClerks;
delete [] ppo.pasClerks;
delete [] ppo.cashiers;*/
}
/*void PassportOfficeSetAppClerks(Clerk[] _appClerks){
theOffice.appClerks = _appClerks;
}
void PassportOfficeSetPicClerks(Clerk[] _picClerks){
theOffice.picClerks = _picClerks;
}
void PassportOfficeSetPasClerks(Clerk[] _pasClerks){
theOffice.pasClerks = _pasClerks;
}
void PassportOfficeSetCashiers(Clerk[] _cashiers){
theOffice.cashiers = _cashiers;
}*/
void PassportOfficeAllClerksInitialized(){
SignalCV(theOffice.finishInitializationCV,theOffice.finishInitializationLock);
/*finishInitializationLock->ReleaseLock();*/
}
/*void PassportOffice::changeNumSenatorsInOffice(int num) {
if (numSenatorsInOffice <= 0 && num >= 1) {
//Tell the manager to kick everyone out
manager->setSendOutside(true);
}
numSenatorsInOffice += num;
if (numSenatorsInOffice <= 0) {
numSenatorsInOffice = 0;
//Wake up the customers outside, its time to let them back in
outsideLock->AcquireLock();
outsideCV->Broadcast(outsideLock);
outsideLock->ReleaseLock();
} else if (num < 0) {
//Then its time to signal the next Senator to come through
senatorLock->AcquireLock();
senatorCV->SignalCV(senatorLock);
senatorLock->ReleaseLock();
}
}*/
void PassportOfficeDecrementCustomerCounter() {
theOffice.customerCounter--;
if (theOffice.customerCounter == 0) {
Write("\nThe last customer has exited the passport office.\n", 55, ConsoleOutput);
Write("The simulation is over.\nI hope you enjoyed it!\n", 50, ConsoleOutput);
/*Now put Manager to sleep*/
ManagerStop();
}
/*
if (customerCounter == 1) {
printf("\n\nCustomer counter at 1\n\n");
customerCounter = 0;
senatorLock->AcquireLock();
senatorCV->SignalCV(senatorLock);
senatorLock->ReleaseLock();
}*/
}
void PassportOfficeAddMoneyToApplicationClerks(int money) {
AcquireLock(theOffice.appMoneyLock);
theOffice.applicationClerkMoney += money;
ReleaseLock(theOffice.appMoneyLock);
}
void PassportOfficeAddMoneyToPictureClerks(int money) {
AcquireLock(theOffice.picMoneyLock);
theOffice.pictureClerkMoney += money;
ReleaseLock(theOffice.picMoneyLock);
}
void PassportOfficeAddMoneyToPassportClerks(int money) {
AcquireLock(theOffice.pasMoneyLock);
theOffice.passportClerkMoney += money;
ReleaseLock(theOffice.pasMoneyLock);
}
void PassportOfficeAddMoneyToCashiers(int money) {
AcquireLock(theOffice.casMoneyLock);
theOffice.cashierMoney += money;
ReleaseLock(theOffice.casMoneyLock);
}
struct Clerk PassportOfficeEnterShortestLine(struct Customer customer, int choice, int isBribing) {
int shortestLineSize = 999999999;
int shortestPointer = -1;
int numClerks;
int newSize;
int c;
int lineCV;
int lineLock;
int walkUpCV;
/*Clerk clerks[5];*/
if(choice == APPLICATION) {
AcquireLock(theOffice.findShortestApplicationLineLock);
numClerks = theOffice.numAppClerks;
for (c = 0; c < numClerks; c++) {
if (isBribing == 1) {
newSize = LineGetBriberyLineSize(theAppClerks[c].myClerk.myLine);
} else {
newSize = LineGetTotalLineSize(theAppClerks[c].myClerk.myLine);
}
if (newSize < shortestLineSize) {
shortestPointer = c;
shortestLineSize = newSize;
}
}
/*Now put customer to sleep
//With a CV*/
lineLock = LineGetLineLock(theAppClerks[shortestPointer].myClerk.myLine);
if (isBribing == 1) {
lineCV = LineGetBribeCV(theAppClerks[shortestPointer].myClerk.myLine);
} else {
lineCV = LineGetNormalLineCV(theAppClerks[shortestPointer].myClerk.myLine);
}
/*HERE IS WHERE YOU STATE YOU GOT INTO LINE! */
AcquireLock(lineLock);
if (isBribing == 1) {
LineAddToBriberyLine(theAppClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in bribe line for ApplicationClerk ", 50, ConsoleOutput);
PrintInt(theAppClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
} else {
LineAddToNormalLine(theAppClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in regular line for ApplicationClerk ", 50, ConsoleOutput);
PrintInt(theAppClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
}
/*Now release the shortest line lock*/
ReleaseLock(theOffice.findShortestApplicationLineLock);
WaitCV(lineCV,lineLock);
/*Give the clerk a pointer of the customer*/
ClerkSetCustomer(theAppClerks[shortestPointer].myClerk,&customer);
/*and wake up the customer*/
walkUpCV = ClerkGetWalkUpCV(theAppClerks[shortestPointer].myClerk);
SignalCV(walkUpCV,lineLock);
ReleaseLock(lineLock);
/*Give him or her a pointer to his or her clerk*/
if (shortestPointer >= 0) {
return theAppClerks[shortestPointer].myClerk;
} else {
return theAppClerks[0].myClerk;
}
}
if(choice == PICTURE) {
AcquireLock(theOffice.findShortestPictureLineLock);
numClerks = theOffice.numPicClerks;
for (c = 0; c < numClerks; c++) {
if (isBribing == 1) {
newSize = LineGetBriberyLineSize(thePicClerks[c].myClerk.myLine);
} else {
newSize = LineGetTotalLineSize(thePicClerks[c].myClerk.myLine);
}
if (newSize < shortestLineSize) {
shortestPointer = c;
shortestLineSize = newSize;
}
}
/*Now put customer to sleep
//With a CV*/
lineLock = LineGetLineLock(thePicClerks[shortestPointer].myClerk.myLine);
if (isBribing == 1) {
lineCV = LineGetBribeCV(thePicClerks[shortestPointer].myClerk.myLine);
} else {
lineCV = LineGetNormalLineCV(thePicClerks[shortestPointer].myClerk.myLine);
}
/*HERE IS WHERE YOU STATE YOU GOT INTO LINE! */
AcquireLock(lineLock);
if (isBribing == 1) {
LineAddToBriberyLine(thePicClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in bribe line for PictureClerk ", 45, ConsoleOutput);
PrintInt(thePicClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
} else {
LineAddToNormalLine(thePicClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in regular line for PictureClerk ", 50, ConsoleOutput);
PrintInt(thePicClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
}
/*Now release the shortest line lock*/
ReleaseLock(theOffice.findShortestPictureLineLock);
WaitCV(lineCV,lineLock);
/*Give the clerk a pointer of the customer*/
ClerkSetCustomer(thePicClerks[shortestPointer].myClerk,&customer);
/*and wake up the customer*/
walkUpCV = ClerkGetWalkUpCV(thePicClerks[shortestPointer].myClerk);
SignalCV(walkUpCV,lineLock);
ReleaseLock(lineLock);
/*Give him or her a pointer to his or her clerk*/
if (shortestPointer >= 0) {
return thePicClerks[shortestPointer].myClerk;
} else {
return thePicClerks[0].myClerk;
}
}
if(choice == CASHIER) {
AcquireLock(theOffice.findShortestCashierLineLock);
numClerks = theOffice.numCashiers;
for (c = 0; c < numClerks; c++) {
newSize;
if (isBribing == 1) {
newSize = LineGetBriberyLineSize(theCasClerks[c].myClerk.myLine);
} else {
newSize = LineGetTotalLineSize(theCasClerks[c].myClerk.myLine);
}
if (newSize < shortestLineSize) {
shortestPointer = c;
shortestLineSize = newSize;
}
}
/*Now put customer to sleep
//With a CV*/
lineLock = LineGetLineLock(theCasClerks[shortestPointer].myClerk.myLine);
if (isBribing == 1) {
lineCV = LineGetBribeCV(theCasClerks[shortestPointer].myClerk.myLine);
} else {
lineCV = LineGetNormalLineCV(theCasClerks[shortestPointer].myClerk.myLine);
}
/*HERE IS WHERE YOU STATE YOU GOT INTO LINE! */
AcquireLock(lineLock);
if (isBribing == 1) {
LineAddToBriberyLine(theCasClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in bribe line for Cashier ", 40, ConsoleOutput);
PrintInt(theCasClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
} else {
LineAddToNormalLine(theCasClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in regular line for Cashier ", 45, ConsoleOutput);
PrintInt(theCasClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
}
/*Now release the shortest line lock*/
ReleaseLock(theOffice.findShortestCashierLineLock);
WaitCV(lineCV,lineLock);
/*Give the clerk a pointer of the customer*/
ClerkSetCustomer(theCasClerks[shortestPointer].myClerk,&customer);
/*and wake up the customer*/
walkUpCV = ClerkGetWalkUpCV(theCasClerks[shortestPointer].myClerk);
SignalCV(walkUpCV,lineLock);
ReleaseLock(lineLock);
/*Give him or her a pointer to his or her clerk*/
if (shortestPointer >= 0) {
return theCasClerks[shortestPointer].myClerk;
} else {
return theCasClerks[0].myClerk;
}
}
if(choice == PASSPORT) {
AcquireLock(theOffice.findShortestPassportLineLock);
numClerks = theOffice.numPasClerks;
for (c = 0; c < numClerks; c++) {
if (isBribing == 1) {
newSize = LineGetBriberyLineSize(thePasClerks[c].myClerk.myLine);
} else {
newSize = LineGetTotalLineSize(thePasClerks[c].myClerk.myLine);
}
if (newSize < shortestLineSize) {
shortestPointer = c;
shortestLineSize = newSize;
}
}
/*Now put customer to sleep
//With a CV*/
lineLock = LineGetLineLock(thePasClerks[shortestPointer].myClerk.myLine);
if (isBribing == 1) {
lineCV = LineGetBribeCV(thePasClerks[shortestPointer].myClerk.myLine);
} else {
lineCV = LineGetNormalLineCV(thePasClerks[shortestPointer].myClerk.myLine);
}
/*HERE IS WHERE YOU STATE YOU GOT INTO LINE! */
AcquireLock(lineLock);
if (isBribing == 1) {
LineAddToBriberyLine(thePasClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in bribe line for PassportClerk ", 45, ConsoleOutput);
PrintInt(thePasClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
} else {
LineAddToNormalLine(thePasClerks[shortestPointer].myClerk.myLine,&customer);
Write("Customer ", 10, ConsoleOutput);
PrintInt(customer.socialSecurityNumber);
Write(" has gotten in regular line for PassportClerk ", 50, ConsoleOutput);
PrintInt(thePasClerks[shortestPointer].myClerk.number);
Write(" \n", 3, ConsoleOutput);
}
/*Now release the shortest line lock*/
ReleaseLock(theOffice.findShortestPassportLineLock);
WaitCV(lineCV,lineLock);
/*Give the clerk a pointer of the customer*/
ClerkSetCustomer(thePasClerks[shortestPointer].myClerk,&customer);
/*and wake up the customer*/
walkUpCV = ClerkGetWalkUpCV(thePasClerks[shortestPointer].myClerk);
SignalCV(walkUpCV,lineLock);
ReleaseLock(lineLock);
/*Give him or her a pointer to his or her clerk*/
if (shortestPointer >= 0) {
return thePasClerks[shortestPointer].myClerk;
} else {
return thePasClerks[0].myClerk;
}
}
}
void startCustomer() {
int rnum = GetRand() % 4;
int money = 100, i;
char* sName = "Customer";
struct Customer custie;
if (rnum == 1) {
money += 500;
} else if (rnum == 2) {
money += 1000;
} else if (rnum == 3) {
money += 1500;
}
i = PassportOfficeGetCustomerCounter();
custie = CreateCustomer(sName, i, money, theOffice);
/*//Don't allow customer to enter if there is already a Senator in the building.
//Unless he or she is a senator.
Lock* senatorLock = theOffice->getSenatorLock();
senatorLock->AcquireLock();
if(theOffice->isSenatorInOffice() && !custie->getIsSenator()) {
//I am not a senator.
//There is a senator in the office.
//Wait for him or her to leave.
Lock* outsideLock = theOffice->getOutsideLock();
int outsideCV = theOffice->getOutsideCV();
outsideLock->AcquireLock();
senatorLock->ReleaseLock();
outsideCV->WaitCV(outsideLock);
outsideLock->ReleaseLock();
} else {
senatorLock->ReleaseLock();
}*/
CustomerEnterPassportOffice(custie);
}
void startClerk()
{
int appClerkCounter = PassportOfficeGetAppClerkCounter();
int picClerkCounter = PassportOfficeGetPicClerkCounter();
int pasClerkCounter = PassportOfficeGetPasClerkCounter();
int cashierCounter = PassportOfficeGetCashierCounter();
if(appClerkCounter < PassportOfficeGetNumAppClerks()){
theAppClerks[appClerkCounter] = CreateApplicationClerk("ApplicationClerk", appClerkCounter, &theOffice);
/*PassportOfficeSetAppClerks(theAppClerks);*/
PassportOfficeIncrementAppClerkCounter();
ApplicationClerkRun(theAppClerks[appClerkCounter]);
return;
}
if(picClerkCounter < PassportOfficeGetNumPicClerks()){
thePicClerks[picClerkCounter] = CreatePictureClerk("PictureClerk", picClerkCounter, theOffice);
/*PassportOfficeSetPicClerks(thePicClerks);*/
PassportOfficeIncrementPicClerkCounter();
PictureClerkRun(thePicClerks[picClerkCounter]);
return;
}
if(pasClerkCounter < PassportOfficeGetNumPasClerks()){
thePasClerks[pasClerkCounter] = CreatePassportClerk("PassportClerk", pasClerkCounter, theOffice);
/*PassportOfficeSetPasClerks(thePasClerks);*/
PassportOfficeIncrementPasClerkCounter();
PassportClerkRun(thePasClerks[pasClerkCounter]);
return;
}
if(cashierCounter < PassportOfficeGetNumCashiers()){
theCasClerks[cashierCounter] = CreateCashier("Cashier", cashierCounter, theOffice);
/*PassportOfficeSetCashiers(theCasClerks);*/
PassportOfficeIncrementCashierCounter();
CashierRun(theCasClerks[cashierCounter]);
return;
}
}
void startManager() {
CreateManager("Michael");
/*theOffice->getFinishInitializationLock()->AcquireLock();*/
ManagerRun();
}
void SystemTest(int, int);
/*
void TestOne() {
printf("\n\n~~~~~~~~~Test One~~~~~~~~~\n\n");
printf("To prove Test One, we will have ten Customers entering a passport office with only 2 Clerks.\n");
printf("Print statements about Locks and Condition Variables will be turned on.\n");
//Change test case to 1
testcase = 0;
SystemTest(10, 2);
}
void TestTwo() {
printf("\n\n~~~~~~~~~Test Two~~~~~~~~~\n\n");
printf("To prove Test Two, we will have ten Customers entering a passport office with only 1 Clerk.\n");
printf("Print statements about Locks will be turned on.\n");
//Create a Passport Office
//Create One Clerk Thread (per type)
//Create a Manager Thread
//Have manager thread only print out money once
//Print out locks and stuff during this time
testcase = 0;
SystemTest(10, 1);
}
void TestThree() {
printf("\n\n~~~~~~~~~Test Three~~~~~~~~~\n\n");
printf("To prove Test Three, we will have ten Customers entering a passport office with only 1 Clerk.\n");
//printf("Print statements about each Cashier-Customer Interaction will be turned on.\n");
//Create a Passport Office
//Create One Clerk Thread (per type)
//Don't let them go on break
//Create two customer threads
//send them on their way to the cashier with everything they need for the cashier
//print out customer leaving and the cashier waiting for the customer to leave
//Print out next customer entering cashier
testcase = 0;
SystemTest(10, 1);
}
void TestFour() {
printf("\n\n~~~~~~~~~Test Four~~~~~~~~~\n\n");
printf("To prove Test Four, we will have fifty Customers entering a passport office with 5 Clerks.\n");
printf("Print statements about the number of customers in each line will be turned on.\n");
//Create a Passport Office
//Create One Clerk Thread (per type)
//Create Manager Thread
//Create three customer threads
//print out line information every time someone enters/leaves a line
//print out line info when clerks go on break or check to see if they can
testcase = 0;
SystemTest(50, 5);
}
void TestFive() {
printf("\n\n~~~~~~~~~Test Five~~~~~~~~~\n\n");
printf("To prove Test Five, we will have fifteen Customers entering a passport office with only 2 Clerks.\n");
Same as test four, but with a manager printing info
testcase = 0;
SystemTest(15, 2);
}
void TestSix() {
printf("\n\n~~~~~~~~~Test Six~~~~~~~~~\n\n");
printf("To prove Test Six, we will have fifty Customers entering a passport office with 2 Clerks.\n");
How do we prove that total sales do not suffer from race conditions?
testcase = 0;
SystemTest(50, 2);
}
void TestSeven() {
Create a Passport Office
//Create one clerk per type threads
//Don't allow breaks
//Create 20 Customers (non senator) Threads
//Send them into the PassportOffice
//Wait for five of them to complete their passports
//Create a Senator Thread
//Send him or her inside the passport office
}*/
void SystemTest(int numCust, int numClerks) {
int totalClerks;
int x, i;
int initCV;
while (numCust < 1 || numCust > 50) {
Write("\nHow many customers? 50\n", 41, ConsoleOutput);
numCust = 50;
}
while (numClerks < 1 || numClerks > 5) {
Write("How many of each type of clerk? 5\n", 50, ConsoleOutput);
numClerks = 5;
}
Write("Ok, here is what the simulation will run with:\n", 50, ConsoleOutput);
Write("Number of Customers = ", 25, ConsoleOutput);
PrintInt(numCust);
Write("\n", 2, ConsoleOutput);
Write("Number of ApplicationClerks = ", 35, ConsoleOutput);
PrintInt(numClerks);
Write("\n", 2, ConsoleOutput);
Write("Number of PictureClerks = ", 30, ConsoleOutput);
PrintInt(numClerks);
Write("\n", 2, ConsoleOutput);
Write("Number of PassportClerks = ", 30, ConsoleOutput);
PrintInt(numClerks);
Write("\n", 2, ConsoleOutput);
Write("Number of Cashiers = ", 25, ConsoleOutput);
PrintInt(numClerks);
Write("\n", 2, ConsoleOutput);
Write("Number of Senators = ", 25, ConsoleOutput);
PrintInt(0);
Write("\n", 2, ConsoleOutput);
theOffice = CreatePassportOffice(numClerks);
totalClerks = numClerks * 4;
/*char** clerkNames = new char*[totalClerks];
std::stringstream clerkSS;*/
for (x = 0; x < totalClerks; x++) {
/*Thread *newClerk;
clerkSS.clear();
clerkSS.str("");*/
char* clerkSS;
if (x / numClerks == 0) {
clerkSS = "ApplicationClerk ";
} else if (x / numClerks == 1) {
clerkSS = "PictureClerk ";
} else if (x / numClerks == 2) {
clerkSS = "PassportClerk ";
} else {
clerkSS = "Cashier ";
}
/*std::string s = clerkSS.str();
clerkNames[x] = new char[s.length() + 1];
std::strcpy(clerkNames[x], s.c_str());
newClerk = new Thread(clerkNames[x]);
newClerk->Fork((VoidFunctionPtr)startClerk,(int)ppo);*/
Fork(&startClerk,clerkSS, sizeof clerkSS, x%numClerks);
}
/*Wait for all clerks to be initialized before initializing the manager*/
initCV = PassportOfficeGetFinishInitializationCV();
WaitCV(initCV,PassportOfficeGetFinishInitializationLock());
/*Now create the Manager Thread
Thread *newManager = new Thread("Manager");
newManager->Fork((VoidFunctionPtr)startManager,(int)ppo);*/
Fork(&startManager, "Manager", 7, 0);
/*typedef Customer* cusPtr;
//cusPtr * custs = new cusPtr[numCust];*/
/*std::stringstream custSS;
char** customerNames = new char*[numCust];*/
for (i=0; i<numCust; i++) {
/*Now initialize the threads of customers
custSS.clear();
custSS.str("");*/
char* custSS = "Customer ";
/*std::string s = custSS.str();
customerNames[i] = new char[s.length() + 1];
std::strcpy(customerNames[i], s.c_str());
Thread *newCust = new Thread(customerNames[i]);
newCust->Fork((VoidFunctionPtr)startCustomer,(int)ppo);*/
Fork(&startCustomer, custSS, sizeof custSS, i);
}
/*DELETE CUSTOMER NAMES
//DELETE CLERKS NAMES*/
}
/* --------------------------------------------------
// Problem2()
// The tests meant to run with part 2 of the assignment.
// --------------------------------------------------*/
int main() {
int choice1 = -1;
while (choice1 != 1 && choice1 != 2) {
Write("What action would you like to take?\n", 40, ConsoleOutput);
Write("1) System Test Simulation\n", 30, ConsoleOutput);
Write("2) Other Tests\n", 20, ConsoleOutput);
PrintInt(1);
choice1 = 1;
}
if (choice1 == 1) {
/*testcase = 0;*/
SystemTest(-1,-1);
}/*
else if (choice1 = 2) {
int choice2 = -1;
printf("Which test would you like to run?\n");
printf("1) Customers choose the shortest line, but no two customers choose the same shortest line at the same time.\n");
printf("2) Managers only read from one Clerk's total money at a time.\n");
printf("3) Customers do not leave until they are given their passport by the Cashier. The Cashier does not start on another customer until they know that the last Customer has left their area.\n");
printf("4) Clerks go on break when no one is waiting in their line.\n");
printf("5) Managers wake up clerks when lines are too long.\n");
printf("6) Total sales do not suffer from race conditions.\n");
printf("7) Customers demonstrate proper behavior around Senators.\n");
scanf("%d", &choice2);
switch (choice2) {
case 1:
TestOne();
break;
case 2:
TestTwo();
break;
case 3:
TestThree();
break;
case 4:
TestFour();
break;
case 5:
TestFive();
break;
case 6:
TestSix();
break;
case 7:
TestSeven();
break;
}
}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment