dining-philosophers/DiningPhilosophers.c
2022-09-27 21:30:23 -05:00

141 lines
4.6 KiB
C

#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#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*/
int philosopherState[N]; /*array to keep track of everyone's state*/
sem_t mutex = 1; /*mutual exclusion for critical region*/
sem_t philosopherSemaphore[N]; /*one semaphore per philospher*/
void Down(sem_t* selectedSemaphore);
void Eat(int selectedPhilosopher);
int GetNumberPhilosophers(char* argv);
void Philosopher(int selectedPhilosopher);
void PutForks(int selectedPhilosopher);
void TakeForks(int selectedPhilosopher);
void Test(int selectedPhilosopher);
void Think(int selectedPhilosopher);
void Up(sem_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;
}
//
// TODO:
// Turn function into putting down forks (releasing waits)
//
void Down(sem_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)
{
int stateEatingCount[numPhilosophers];
while (true)
{
Think(); /*philosopher is thinking*/
TakeForks(numPhilosophers); /*acquire two forks or block*/
Eat(); /*yum-yum, spaghetti*/
PutForks(numPhilosophers); /*put both forks back on table*/
}
}
void PutForks(int selectedPhilosopher) /*i: philosopher number, from 0 to N-1*/
{
Down(&mutex); /*enter critical region*/
printf("%d is now thinking.\n", selectedPhilosopher);
philosopherState[selectedPhilosopher] = THINKING; /*record fact that philosopher i is hungry*/
Test((i+N-1)%N); /*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(int selectedPhilosopher)
{
Down(&mutex); /*enter critical region*/
philosopherState[selectedPhilosopher] = 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(int selectedPhilosopher)
{
if (philosopherState[selectedPhilosopher] != HUNGRY)
return;
if (philosopherState[(selectedPhilosopher+N-1)%N LEFT] == EATING)
return;
if (philosopherState[RIGHT] == EATING)
return;
philosopherState[selectedPhilosopher] = 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)
void Up(sem_t* selectedSemaphore)
{
printf("Function Up() was called.\n");
}