Initial commit
This commit is contained in:
commit
ba0363c2c0
140
DiningPhilosophers.c
Normal file
140
DiningPhilosophers.c
Normal file
@ -0,0 +1,140 @@
|
||||
#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");
|
||||
}
|
BIN
Dining_Philosophers_img.PNG
Executable file
BIN
Dining_Philosophers_img.PNG
Executable file
Binary file not shown.
After Width: | Height: | Size: 152 KiB |
4
TestDining.sh
Executable file
4
TestDining.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
rm DiningPhilosophers
|
||||
gcc DiningPhilosophers.c -o DiningPhilosophers
|
||||
./DiningPhilosophers 5
|
Loading…
Reference in New Issue
Block a user