Skip to content
Snippets Groups Projects
Commit 7d3f43cf authored by Brandon Rodriguez's avatar Brandon Rodriguez
Browse files

Create initial framework for problem

parent 375c72f0
Branches
No related merge requests found
/** /**
* Uses pthreads to implement the "Dining Philosophers" problem. * Uses pthreads to implement the "Dining Philosophers" problem.
*
* Each thread is a "philosopher" that takes "10,000 bites" before being satisfied and stopping eating.
* Each philosopher gives a status update after every 1,000 bites, or after not being able to eat for a full second.
*/ */
// Import headers. // Import headers.
#include <pthread.h> #include <pthread.h>
#include <ctype.h> #include <ctype.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -16,10 +20,17 @@ ...@@ -16,10 +20,17 @@
// Variable Declaration. // Variable Declaration.
pthread_mutex_t mutex_lock;
bool all_ready; // Indicates that all philosophers are ready and at table.
bool* thread_ready; // Indicates which individual philosophers are ready.
bool* fork_ready; // Indicates fork of given index is ready for pickup.
bool* forks; // Indicates fork of given index is currently held.
// Method Declaration. // Method Declaration.
void* start_thread(); void* start_thread();
void get_forks();
void release_forks();
/** /**
...@@ -33,17 +44,38 @@ int main(int argc, char* argv[]) { ...@@ -33,17 +44,38 @@ int main(int argc, char* argv[]) {
pthread_t* thread_array = calloc(10, sizeof(pthread_t)); pthread_t* thread_array = calloc(10, sizeof(pthread_t));
int* thread_results = calloc(10, sizeof(int)); int* thread_results = calloc(10, sizeof(int));
int index = 0; int index = 0;
all_ready = false;
thread_ready = calloc(10, sizeof(bool));
fork_ready = calloc(10, sizeof(bool));
while (index < 10) {
thread_ready[index] = false;
index += 1;
}
// Create threads. // Create threads.
index = 0;
while (index < 10) { while (index < 10) {
// Create new "thread_number" int from index and save to new memory location. Then create thread. // Create new "thread_number" int from index and save to new memory location. Then create thread.
int* thread_number = calloc(1, sizeof(int)); int* thread_number = calloc(1, sizeof(int));
*thread_number = index + 1; *thread_number = index;
pthread_create(&thread_array[index], NULL, start_thread, (void*) thread_number); pthread_create(&thread_array[index], NULL, start_thread, (void*) thread_number);
index += 1; index += 1;
} }
// Join threads and handle results. // Wait until all threads initialize. Aka, all philosophers sit down at the table.
index = 0;
while (index < 10) {
while (thread_ready[index] == false) {
sleep(0.5);
}
index += 1;
}
printf("All philosophers are ready. Time to eat.\n\n");
all_ready = true;
free(thread_ready);
// Philosophers are eating. On finish, join threads and handle results.
index = 0; index = 0;
while (index < 10) { while (index < 10) {
// Get and save return value. Free original pointer for int that was passed into threads. // Get and save return value. Free original pointer for int that was passed into threads.
...@@ -51,11 +83,12 @@ int main(int argc, char* argv[]) { ...@@ -51,11 +83,12 @@ int main(int argc, char* argv[]) {
pthread_join(thread_array[index], &ret_val); pthread_join(thread_array[index], &ret_val);
thread_results[index] = *(int*) ret_val; thread_results[index] = *(int*) ret_val;
free(ret_val); free(ret_val);
printf("Got thread #%d results.\n", thread_results[index]); printf("Philosopher #%d has left the table.\n", thread_results[index]);
index += 1; index += 1;
} }
// Free variables. // Free variables.
free(fork_ready);
free(thread_array); free(thread_array);
free(thread_results); free(thread_results);
...@@ -67,10 +100,43 @@ int main(int argc, char* argv[]) { ...@@ -67,10 +100,43 @@ int main(int argc, char* argv[]) {
* Function threads call on start. * Function threads call on start.
*/ */
void* start_thread(void* thread_num) { void* start_thread(void* thread_num) {
printf("Started thread #%d.\n", *(int*)thread_num); printf("Philosopher #%d has sat down at the table.\n", *(int*) thread_num);
thread_ready[*(int*) thread_num] = true;
sleep(1); // Wait until all philosophers are at the table and ready. We're polite here.
while (! all_ready) {
sleep(0.1);
}
// Everyone is ready and present. Start eating.
int bites_taken = 0;
while (bites_taken < 10000) {
pthread_mutex_lock(&mutex_lock);
bites_taken += 1;
pthread_mutex_unlock(&mutex_lock);
if ((bites_taken % 1000) == 0) {
printf("Philosopher #%d has taken %d bites. Resting.\n", *(int*) thread_num, bites_taken);
sleep(1);
}
}
printf("Exiting thread #%d.\n", *(int*)thread_num); printf("Philosopher #%d is full.\n", *(int*) thread_num);
pthread_exit(thread_num); pthread_exit(thread_num);
} }
/**
* Function to attempt to get forks. Must have two forks to eat.
*/
void get_forks(int thread_num) {
}
/**
* Function to release all held forks.
*/
void release_forks(int thread_num) {
}
...@@ -21,7 +21,7 @@ run: compile ...@@ -21,7 +21,7 @@ run: compile
# Compile program and run with valgrind (memory checking). # Compile program and run with valgrind (memory checking).
valgrind: compile valgrind: compile
valgrind --leak-check=full ./a.out valgrind --leak-check=full --show-leak-kinds=all ./a.out
# Clean up directory. # Clean up directory.
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment