diff --git a/Main.c b/Main.c index 47a55efb9c84b8dc745b310c8ef1560725fe9d71..1deb17e2a89f0081e6cf5f4b3945b86115cc5a6b 100644 --- a/Main.c +++ b/Main.c @@ -23,15 +23,21 @@ #define brodriguez_helper_functions #include "brodriguez_helper_functions.h" #endif +#include <time.h> +#include <pthread.h> +#include <unistd.h> +#include "buffer.h" // Constant Defines. - +#define SLEEP_MIN 2 // Variable Declaration. // Method Declaration. +void* producer(); +void* consumer(); /** @@ -39,6 +45,14 @@ * Initializes and runs program. */ int main(int argc, char* argv[]) { + int index; + int nap_length; + int producer_count; + int consumer_count; + int result_int; + int* max_time; + pthread_t* producer_array; + pthread_t* consumer_array; // Ensure correct number of commands. if (argc < 4) { @@ -49,18 +63,131 @@ int main(int argc, char* argv[]) { exit(1); } - // Initialize. + printf("Initializing...\n"); + // Validate user input. + nap_length = atoi(argv[1]); + if (nap_length < SLEEP_MIN) { + fprintf(stderr, "Invalid sleep length. Must be a minimum of %d seconds.\n", SLEEP_MIN); + exit(1); + } + producer_count = atoi(argv[2]); + if (producer_count <= 0) { + fprintf(stderr, "Invalid number of producers. Must be greater than 0.\n"); + exit(1); + } + consumer_count = atoi(argv[3]); + if (consumer_count <= 0) { + fprintf(stderr, "Invalid number of consumers. Must be greater than 0.\n"); + exit(1); + } + max_time = calloc(1, sizeof(int)); + *max_time = nap_length; + + // Seeding random generator. + // srand(time(NULL)); TODO: Commented for debugging. Uncomment later. // Create producer thread(s). printf("Creating producers...\n"); + producer_array = calloc(producer_count, sizeof(pthread_t)); + for (index = 0; index < producer_count; index++) { + printf("Main creating producer #%d.\n", index); + pthread_create(&producer_array[index], NULL, producer, (void*) max_time); + } // Create consumer thread(s). printf("Creating consumers...\n"); + consumer_array = calloc(consumer_count, sizeof(pthread_t)); + for (index = 0; index < consumer_count; index++) { + printf("Main creating consumer #%d.\n", index); + pthread_create(&consumer_array[index], NULL, consumer, (void*) max_time); + } // Sleep main. + printf("Main will now sleep for %d seconds.\n", nap_length); + sleep(atoi(argv[1])); + + + // Terminate program. + for (index = 0; index < producer_count; index++) { + printf("Terminating producer #%d.\n", index); + result_int = pthread_cancel(producer_array[index]); + if (result_int < 0) { + fprintf(stderr, "Error terminating producer thread #%d.\n", index); + } + } + for (index = 0; index < consumer_count; index++) { + printf("Terminating consumer #%d.\n", index); + result_int = pthread_cancel(consumer_array[index]); + if (result_int < 0) { + fprintf(stderr, "Error terminating consumer thread #%d.\n", index); + } + } + free(max_time); + free(producer_array); + free(consumer_array); exit(0); } + + +/** + * Function for producer threads to run. + */ +void* producer(void* max_time) { + int sleep_time; + buffer_item item; + + printf("Producer thread created.\n"); + + // Loop until thread is terminated. + while(1) { + // printf("Looping producer thread.\n"); + + // Sleep thread for random time. + sleep_time = rand() % *(int*)max_time; + printf("Sleeping producer for %d seconds.\n", sleep_time); + sleep(sleep_time); + + // item = rand(); + // if (insert_item(item) < 0) { + // fprintf(stderr, "Producer failed to insert item %d.\n", item); + // } else { + // printf("Producer inserted item %d.\n", item); + // } + } + + return NULL; +} + + +/** + * Function for consumer threads to run. + */ +void* consumer(void* max_time) { + int sleep_time; + int* item; + + printf("Consumer thread created.\n"); + + // Loop until thread is terminated. + while(1) { + // printf("Looping consumer thread.\n"); + + // Sleep thread for random time. + sleep_time = rand() % *(int*)max_time; + printf("Sleeping consumer for %d seconds.\n", sleep_time); + sleep(sleep_time); + + // item = calloc(1, sizeof(int)); + // if ((*item = remove_item(item)) < 0) { + // fprintf(stderr, "Consumer failed to remove item.\n"); + // } else { + // printf("Consumer removed item %d.\n", *item); + // } + // free(item); + } + return NULL; +} diff --git a/buffer.c b/buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..56626f6717a8d8c0a62c6d080f059538d1ce3f72 --- /dev/null +++ b/buffer.c @@ -0,0 +1,41 @@ +/** + * Brandon Rodriguez + * CS 4540 + * 02-27-18 + * a4 (Assignment 4) + */ + + +// Import headers. +#import "buffer.h" + + +// Variable Declaration. +buffer_item buffer[BUFFER_SIZE]; + + +/** + * + */ +int intialize_buffer() { + + return 0; +} + + +/** + * Inserts item into buffer. + */ +int insert_item(buffer_item item) { + + return 0; +} + + +/** + * Removes item from buffer. + */ +int remove_item(buffer_item item) { + + return 0; +} diff --git a/buffer.h b/buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..4d5b7e201b143e3daf92622bb0d9ccd51bab2d0d --- /dev/null +++ b/buffer.h @@ -0,0 +1,22 @@ +/** + * Brandon Rodriguez + * CS 4540 + * 02-27-18 + * a4 (Assignment 4) + */ + + +// Constant Defines. +#define BUFFER_SIZE 5 + + +// Define an item type to create buffer for. +// In this instance, it is a standard int. But it could easily be changed +// to a different/more complex data type and still function the same. +typedef int buffer_item; + + +// Function prototypes. +int initialize_buffer(); +int insert_item(); +int remove_item(); diff --git a/makefile b/makefile index 6672a85912db523ea66e8ad1c3f5d444be56110e..f24bd52f0aba8ec8347d4fff3594449e7d85794c 100644 --- a/makefile +++ b/makefile @@ -1,2 +1,2 @@ all: - gcc -Wall -Wpedantic -std=c99 *.c -g -o a4 + gcc -Wall -Wpedantic -std=c99 *.c -g -o a4 -pthread