diff --git a/main.c b/main.c index 4b94e3380ddef0864a620171991f78a0aff921c5..d7079b65368ce3c6cc4231e4105888b4bd009dfb 100755 --- a/main.c +++ b/main.c @@ -1,11 +1,15 @@ /** * 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. #include <pthread.h> #include <ctype.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -16,10 +20,17 @@ // 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. void* start_thread(); +void get_forks(); +void release_forks(); /** @@ -33,17 +44,38 @@ int main(int argc, char* argv[]) { pthread_t* thread_array = calloc(10, sizeof(pthread_t)); int* thread_results = calloc(10, sizeof(int)); 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. + index = 0; while (index < 10) { // Create new "thread_number" int from index and save to new memory location. Then create thread. 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); 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; while (index < 10) { // 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[]) { pthread_join(thread_array[index], &ret_val); thread_results[index] = *(int*) 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; } // Free variables. + free(fork_ready); free(thread_array); free(thread_results); @@ -67,10 +100,43 @@ int main(int argc, char* argv[]) { * Function threads call on start. */ 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); } + + +/** + * 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) { + +} diff --git a/makefile b/makefile index 4837313fc06cf1b1329d77e24e3134635b856afb..162f452313aa70249b5b2c026c882c0773b7beb7 100755 --- a/makefile +++ b/makefile @@ -21,7 +21,7 @@ run: compile # Compile program and run with valgrind (memory checking). valgrind: compile - valgrind --leak-check=full ./a.out + valgrind --leak-check=full --show-leak-kinds=all ./a.out # Clean up directory.