| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | #include <pthread.h>
 | 
					
						
							|  |  |  | #include <semaphore.h>
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | #include <stdbool.h>
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | // #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*/
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | #define THINKING    0           /*philosopher is thinking*/
 | 
					
						
							|  |  |  | #define HUNGRY      1           /*philosopher is trying to get forks*/
 | 
					
						
							|  |  |  | #define EATING      2           /*philosopher is eating*/
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | pthread_mutex_t mutex;            /*mutual exclusion for critical region*/ | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | 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); | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | void Eat(int selectedPhilosopher); | 
					
						
							|  |  |  | int GetNumberPhilosophers(char* argv); | 
					
						
							|  |  |  | void Philosopher(int selectedPhilosopher); | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void PutForks(PhilosopherData PhilosopherList); | 
					
						
							|  |  |  | void TakeForks(PhilosopherData PhilosopherList); | 
					
						
							|  |  |  | void Test(PhilosopherData PhilosopherList[], int positionSelected, int numPhilosophers); | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | void Think(int selectedPhilosopher); | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void Up(pthread_mutex_t selectedSemaphore); | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *  Todo: | 
					
						
							|  |  |  |  *      Add prints to each state change | 
					
						
							| 
									
										
										
										
											2022-09-28 15:18:52 -05:00
										 |  |  |  *      Fix each function's requirements | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  |  *  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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | // 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | //
 | 
					
						
							|  |  |  | //  TODO:
 | 
					
						
							| 
									
										
										
										
											2022-09-28 15:18:52 -05:00
										 |  |  | //      Turn function into picking up forks (starting waits)
 | 
					
						
							|  |  |  | //      (Right fork is owned by selectedPhilosopher number for consistency)
 | 
					
						
							|  |  |  | //      Add sem_wait
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void Down(pthread_mutex_t selectedSemaphore) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2022-09-28 15:18:52 -05:00
										 |  |  | // TODO:
 | 
					
						
							|  |  |  | //      Add splitting function into multiple pthreads
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | void Philosopher(int numPhilosophers) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     // 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; | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  |     while (true) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-28 15:18:52 -05:00
										 |  |  |         Think(0);                /*philosopher is thinking*/ | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |         // TakeForks(0, numPhilosophers);          /*acquire two forks or block*/
 | 
					
						
							|  |  |  |         // Eat(0);                  /*yum-yum, spaghetti*/
 | 
					
						
							|  |  |  |         // PutForks(0, numPhilosophers);           /*put both forks back on table*/
 | 
					
						
							| 
									
										
										
										
											2022-09-28 15:18:52 -05:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void PutForks(PhilosopherData PhilosopherList) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     // 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*/
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Takes in a number for a selected philosopher, from 0 to N-1
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void TakeForks(PhilosopherData PhilosopherList) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     // 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*/
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void Test(PhilosopherData PhilosopherList[], int positionSelected, int numPhilosophers) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     if (PhilosopherList[positionSelected].state != HUNGRY) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     int leftPhilosopher = (positionSelected + (numPhilosophers-1)) % numPhilosophers; | 
					
						
							|  |  |  |     int rightPhilosopher = (positionSelected + 1) % numPhilosophers; | 
					
						
							|  |  |  |     if (PhilosopherList[leftPhilosopher].state == EATING) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     if (PhilosopherList[rightPhilosopher].state == EATING) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  |     PhilosopherList[positionSelected].state = EATING; | 
					
						
							|  |  |  |     // Up(&philosopherSemaphore[selectedPhilosopher]);
 | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Think(int selectedPhilosopher) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     printf("Function Think() was called.\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-28 15:18:52 -05:00
										 |  |  | // Todo:
 | 
					
						
							|  |  |  | //      Make function release hold on semaphore
 | 
					
						
							|  |  |  | //      Use 'sem_post'
 | 
					
						
							| 
									
										
										
										
											2022-09-27 22:58:47 -05:00
										 |  |  | void Up(pthread_mutex_t selectedSemaphore) | 
					
						
							| 
									
										
										
										
											2022-09-27 21:30:23 -05:00
										 |  |  | { | 
					
						
							|  |  |  |     printf("Function Up() was called.\n"); | 
					
						
							|  |  |  | } |