From 6cfd5a6995d9f5a7cba5d9743850a5f1321ef578 Mon Sep 17 00:00:00 2001 From: RossTheRoss Date: Tue, 8 Dec 2020 08:49:33 -0600 Subject: oops --- csci4061/112320_breakout/sol-condition_variables.c | 128 +++++++++++++++++++++ csci4061/112320_breakout/sol-semaphore.c | 128 +++++++++++++++++++++ 2 files changed, 256 insertions(+) create mode 100644 csci4061/112320_breakout/sol-condition_variables.c create mode 100644 csci4061/112320_breakout/sol-semaphore.c (limited to 'csci4061') 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)); + + } diff --git a/csci4061/112320_breakout/sol-semaphore.c b/csci4061/112320_breakout/sol-semaphore.c new file mode 100644 index 0000000..4af3a5b --- /dev/null +++ b/csci4061/112320_breakout/sol-semaphore.c @@ -0,0 +1,128 @@ +#define NUM_ARGS 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long semTotal = 0; + +struct buffer { + + int vals[100]; + int index; +}; + +struct semBuffer { + + struct buffer* q; + sem_t* psem; + sem_t* csem; + pthread_mutex_t* mutex; +}; + +void insert(struct buffer* q, int val) { + + q->vals[q->index] = val; + ++q->index; +} + +int delete(struct buffer* q) { + + --q->index; + int val = q->vals[q->index]; + return val; +} + +// TODO: Insert code to use a semaphore. +void* semProducer(void* arg) { + + // Random delay. DO NOT REMOVE! + usleep(rand() % 1000); + + struct semBuffer* sq = (struct semBuffer*) arg; + sem_wait(sq->psem); + pthread_mutex_lock(sq->mutex); + + static int in = 0; + ++in; + // Add an element to the queue. + insert(sq->q, in); + + pthread_mutex_unlock(sq->mutex); + sem_post(sq->csem); + +} + +// TODO: Insert code to use a semaphore. +void* semConsumer(void* arg) { + + // Random delay. DO NOT REMOVE! + usleep(rand() % 1000); + + struct semBuffer* sq = (struct semBuffer*) arg; + + sem_wait(sq->csem); + pthread_mutex_lock(sq->mutex); + + // Reove an element from the queue. + semTotal += delete(sq->q); + + pthread_mutex_unlock(sq->mutex); + sem_post(sq->psem); +} + +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 semPool[100]; + + struct timeval start; + gettimeofday(&start, NULL); + + // Create task queue. + struct semBuffer* sq = (struct semBuffer*) malloc(sizeof(struct semBuffer)); + + sq->q = (struct buffer*) malloc(sizeof(struct buffer)); + sq->q->index=0; + sq->psem = (sem_t*) malloc(sizeof(sem_t)); + sq->csem = (sem_t*) malloc(sizeof(sem_t)); + sq->mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); + + // TODO: Initilaize semaphores + sem_init(sq->psem, 0, 50); + sem_init(sq->csem, 0, 0); + + pthread_mutex_init(sq->mutex, NULL); + + for (int i=0; i < 50; ++i) { + + pthread_create(&semPool[i], NULL, semProducer, (void*) sq); + pthread_create(&semPool[50 + i], NULL, semConsumer, (void*) sq); + } + + for (int i=0; i < 100; ++i) pthread_join(semPool[i], NULL); + + struct timeval end; + gettimeofday(&end, NULL); + printf("Sem Test: \nTotal of buffer = %ld\n", semTotal); + printf("Time (in us) to complete = %ld\n", ((end.tv_sec - start.tv_sec) * 1000000) + (end.tv_usec - start.tv_usec)); +} -- cgit v1.2.3