From 7a73162607544204032aa66cce755daf21edebda Mon Sep 17 00:00:00 2001 From: Matt Strapp Date: Tue, 24 May 2022 11:18:46 -0500 Subject: Graduate Signed-off-by: Matt Strapp --- csci4061/112320_breakout/sol-condition_variables.c | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 csci4061/112320_breakout/sol-condition_variables.c (limited to 'csci4061/112320_breakout/sol-condition_variables.c') diff --git a/csci4061/112320_breakout/sol-condition_variables.c b/csci4061/112320_breakout/sol-condition_variables.c new file mode 100644 index 0000000..86cafb1 --- /dev/null +++ b/csci4061/112320_breakout/sol-condition_variables.c @@ -0,0 +1,128 @@ +#define NUM_ARGS 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long condTotal = 0; + +struct queue { + + int vals[100]; + int index; //indicates the next available spot +}; + +struct condQueue { + + struct queue* q; + pthread_cond_t* cond; + pthread_mutex_t* mutex; +}; + + + +void insert(struct queue* q, int val) { + + q->vals[q->index] = val; + ++q->index; +} + +int delete(struct queue* q) { + + --q->index; + int val = q->vals[q->index]; + return val; +} + +// TODO: Insert code to use a condition variable. +void *condProducer(void* arg) { + + // Random delay. DO NOT REMOVE! + usleep(rand() % 1000); + + struct condQueue* cq = (struct condQueue*) arg; + + pthread_mutex_lock(cq->mutex); + + // Counter. + static int in = 0; + ++in; + + // Add an element to the queue. + insert(cq->q, in); + + pthread_cond_signal(cq->cond); //to send signal to any waiting consumer + pthread_mutex_unlock(cq->mutex); +} + +// TODO: Insert code to use a condition variable. +void *condConsumer(void* arg) { + + // Random delay. DO NOT REMOVE! + usleep(rand() % 1000); + + struct condQueue* cq = (struct condQueue*) arg; + + pthread_mutex_lock(cq->mutex); + while (cq->q->index < 1) pthread_cond_wait(cq->cond, cq->mutex);//wait if buffer is empty + + // Remove an element from the queue. + condTotal += delete(cq->q); + + pthread_mutex_unlock(cq->mutex); +} + +int main(int argc, char** argv) { + + if (argc != NUM_ARGS + 1) { + + printf("Wrong number of args, expected %d, given %d\n", NUM_ARGS, argc - 1); + exit(1); + } + + // Seed the random generator. + srand(time(NULL)); + + // Create threads. + pthread_t condPool[100]; + + struct timeval start; + gettimeofday(&start, NULL); + + // Create the cond variable controlled task queue. + struct condQueue* cq = (struct condQueue*) malloc(sizeof(struct condQueue)); + cq->q = (struct queue*) malloc(sizeof(struct queue)); + cq->q->index=0; + + // Allocate memory and initialize condition variable and mutex + cq->cond = (pthread_cond_t*) malloc(sizeof(pthread_cond_t)); + cq->mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); + pthread_cond_init(cq->cond, NULL); + pthread_mutex_init(cq->mutex, NULL); + + // Launch them. + for (int i=0; i < 50; ++i) { + + pthread_create(&condPool[i], NULL, condProducer, (void*) cq); //start 50 producer threads + pthread_create(&condPool[50 + i], NULL, condConsumer, (void*) cq); //start 50 consumer threads + } + + for (int i=0; i < 100; ++i) pthread_join(condPool[i], NULL); //wait for all the threads to be finished + + struct timeval end; + gettimeofday(&end, NULL); + + printf("Cond Test: \nTotal of buffer = %ld\n", condTotal); + printf("Time (in us) to run = %ld\n\n", ((end.tv_sec - start.tv_sec) * 1000000) + (end.tv_usec - start.tv_usec)); + + } -- cgit v1.2.3