#include #include #include #include #include #include // #define N 5 /*number of philosophers*/ // #define LEFT (i+N-1)%N /*number of i's left neighbor*/ // #define RIGHT (i+1)%N /*number of i's right neighbor*/ #define THINKING 0 /*philosopher is thinking*/ #define HUNGRY 1 /*philosopher is trying to get forks*/ #define EATING 2 /*philosopher is eating*/ pthread_mutex_t mutex; /*mutual exclusion for critical region*/ typedef struct PhilosopherData { int eatingCount; int position; sem_t semaphore; int state; } PhilosopherData; bool AllPhilosophersFull(PhilosopherData PhilosopherList[], int numPhilosophers); void Down(pthread_mutex_t selectedSemaphore); void Eat(int selectedPhilosopher); int GetNumberPhilosophers(char* argv); void Philosopher(int selectedPhilosopher); void PutForks(PhilosopherData PhilosopherList); void TakeForks(PhilosopherData PhilosopherList); void Test(PhilosopherData PhilosopherList[], int positionSelected, int numPhilosophers); void Think(int selectedPhilosopher); void Up(pthread_mutex_t selectedSemaphore); /* * Todo: * Create function up() * Create function down() * Create function eat() * Create function think() * Add prints to each state change * Theories: * Threads should be put to sleep if can't eat * Sleep has to be awoken by something else, process can't wake own thread * Place semaphores so states can be checked by all * Total fork count = N / 2 * */ int main(int argc, char* argv[]) { if (argc == 2) { int philosopherCount; philosopherCount = GetNumberPhilosophers(argv[1]); Philosopher(philosopherCount); } return 0; } // Takes in array of times each philosopher has eaten // If all philosophers have ate twice, then returns true // Otherwise, if a philosopher has not eaten twice, returns false bool AllPhilosophersFull(PhilosopherData PhilosopherList[], int numPhilosophers) { for (int i = 0; i < numPhilosophers; i++) if (PhilosopherList[i].eatingCount != 2) return false; return true; } // // TODO: // Turn function into putting down forks (releasing waits) // sem_wait void Down(pthread_mutex_t selectedSemaphore) { printf("Function Down() was called.\n"); } // // TODO: // Add changing state to function // Add increasing eating count functionality // void Eat(int selectedPhilosopher) { printf("Function Eat() was called.\n"); } // Takes in char* and converts into a number // Returns a number int GetNumberPhilosophers(char* argv) { int numPhilosophers; sscanf(argv, "%d", &numPhilosophers); return numPhilosophers; } // Takes in the number of philosophers, from 0 to N-1 // Finishes when all philosophers have eaten twice void Philosopher(int numPhilosophers) { // Below replaced by PhilosopherData // int philosopherEatingCount[numPhilosophers]; // sem_t philosopherSemaphore[numPhilosophers]; /*one semaphore per philospher*/ // // array to keep track of everyone's state // int philosopherState[numPhilosophers]; PhilosopherData PhilosopherList[numPhilosophers]; int forkCount = numPhilosophers / 2; while (true) { break; // Think(0); /*philosopher is thinking*/ // TakeForks(0, numPhilosophers); /*acquire two forks or block*/ // Eat(0); /*yum-yum, spaghetti*/ // PutForks(0, numPhilosophers); /*put both forks back on table*/ } } void PutForks(PhilosopherData PhilosopherList) { // Down(&mutex); /*enter critical region*/ printf("%d is now thinking.\n", PhilosopherList.position); PhilosopherList.state = THINKING; /*philosopher has finished eating*/ // philosopherState[selectedPhilosopher] = THINKING; /*record fact that philosopher i is hungry*/ // Test(selectedPhilosopher, numPhilosophers); // Test(LEFT); /*try to acquire 2 forks*/ // Test(RIGHT); /*exit critical region*/ // Up(&mutex); /*block if forks were not acquired*/ } // Takes in a number for a selected philosopher, from 0 to N-1 void TakeForks(PhilosopherData PhilosopherList) { // Down(&mutex); /*enter critical region*/ PhilosopherList.state = HUNGRY; /*philosopher has finished eating*/ // Test(selectedPhilosopher, ); /*see if left neighbor can now eat*/ // Up(&mutex); /*see if right neighbor can now eat*/ // Down(&philosopherSemaphore[selectedPhilosopher]); /*exit critical region*/ } // Takes in the number of philosophers, from 0 to N-1 // Checks if left and right philosopher is not eating, // and philosopher is hungry, then philosopher will eat void Test(PhilosopherData PhilosopherList[], int positionSelected, int numPhilosophers) { if (PhilosopherList[positionSelected].state != HUNGRY) return; int leftPhilosopher = (positionSelected + (numPhilosophers-1)) % numPhilosophers; int rightPhilosopher = (positionSelected + 1) % numPhilosophers; if (PhilosopherList[leftPhilosopher].state == EATING) return; if (PhilosopherList[rightPhilosopher].state == EATING) return; PhilosopherList[positionSelected].state = EATING; // Up(&philosopherSemaphore[selectedPhilosopher]); } void Think(int selectedPhilosopher) { printf("Function Think() was called.\n"); } // Pick up for on left and right // (Right fork is owned by selectedPhilosopher number for consistency) // sem_post void Up(pthread_mutex_t selectedSemaphore) { printf("Function Up() was called.\n"); }