aboutsummaryrefslogtreecommitdiffstats
path: root/csci4061/112320_breakout
diff options
context:
space:
mode:
authorMatt Strapp <matt@mattstrapp.net>2022-05-24 11:18:46 -0500
committerMatt Strapp <matt@mattstrapp.net>2022-05-24 11:19:55 -0500
commit7a73162607544204032aa66cce755daf21edebda (patch)
tree58578e01f15f34a855d99c32898db9d7a1603e67 /csci4061/112320_breakout
parentdo some stuff (diff)
downloadhomework-7a73162607544204032aa66cce755daf21edebda.tar
homework-7a73162607544204032aa66cce755daf21edebda.tar.gz
homework-7a73162607544204032aa66cce755daf21edebda.tar.bz2
homework-7a73162607544204032aa66cce755daf21edebda.tar.lz
homework-7a73162607544204032aa66cce755daf21edebda.tar.xz
homework-7a73162607544204032aa66cce755daf21edebda.tar.zst
homework-7a73162607544204032aa66cce755daf21edebda.zip
Graduate
Signed-off-by: Matt Strapp <matt@mattstrapp.net>
Diffstat (limited to 'csci4061/112320_breakout')
-rw-r--r--csci4061/112320_breakout/sol-condition_variables.c128
-rw-r--r--csci4061/112320_breakout/sol-semaphore.c128
2 files changed, 256 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sys/time.h>
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include<sys/time.h>
+
+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));
+}