From: kremlin Date: Fri, 14 Nov 2014 06:26:49 +0000 (-0500) Subject: lots of stuff X-Git-Url: https://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=assignments.git;a=commitdiff_plain lots of stuff --- diff --git a/homework/assgn9/hw9.c b/homework/assgn9/hw9.c new file mode 100644 index 0000000..b6b6149 --- /dev/null +++ b/homework/assgn9/hw9.c @@ -0,0 +1,47 @@ +#include "queue.h" +#include +#include + +#include +#include + +#define MAX_NUMS 100000 + +void* producer(void* arg) +{ + queue_t* queue = (queue_t*)arg; + size_t i = 0; + for(i = 0; i < MAX_NUMS; ++i) + { + queue_add(queue, i); + } + return NULL; +} + +void* consumer(void* arg) +{ + queue_t* queue = (queue_t*)arg; + size_t i = 0; + for(i = 0; i < MAX_NUMS; ++i) + { + printf("got %d from producer\n", queue_pop(queue)); + } + return NULL; +} + +int main(int argc, char* argv[]) +{ + pthread_t prod_thr, cons_thr; + pthread_cond_t valid_root; + pthread_mutex_t mx_cond; + queue_t myqueue; + queue_init(&myqueue); + + pthread_create(&cons_thr, NULL, producer, &myqueue); + pthread_create(&prod_thr, NULL, consumer, &myqueue); + + pthread_exit(0x0); + queue_clear(&myqueue); + return 0; +} + diff --git a/homework/assgn9/hw9.tar.gz b/homework/assgn9/hw9.tar.gz new file mode 100644 index 0000000..b851a52 Binary files /dev/null and b/homework/assgn9/hw9.tar.gz differ diff --git a/homework/assgn9/main b/homework/assgn9/main new file mode 100755 index 0000000..9d6d976 Binary files /dev/null and b/homework/assgn9/main differ diff --git a/homework/assgn9/makefile b/homework/assgn9/makefile new file mode 100644 index 0000000..1dc6efb --- /dev/null +++ b/homework/assgn9/makefile @@ -0,0 +1,12 @@ +main: hw9.c queue.h queue.c + gcc -g -o main hw9.c queue.c -pthread + +clean: + rm main + +tar: + tar -cf hw9.tar hw9.c queue.h queue.c makefile + +optimized: hw9.c queue.h queue.c + gcc -o main_optimized hw9.c queue.c -pthread -O5 + diff --git a/homework/assgn9/queue.c b/homework/assgn9/queue.c new file mode 100644 index 0000000..d47df16 --- /dev/null +++ b/homework/assgn9/queue.c @@ -0,0 +1,107 @@ +#include "queue.h" +#include +#include + +/* Requirements 4 & 5 for Homework 09 indicate that you should modify the add + * and pop methods for the queue to provide for thread safety. If you modify + * the producer and consumer methods instead you will not receive full credit + * for the solution. Additionally, the due date for the homework is now + * Thursday to provide for the necessary modifications to fulfill requirements + * 4 & 5. Please note that you should NOT be using a global mutex. Any + * structures you use to protect the queue should be associated with the + * particular queue that is being used (the one given to the add/pop methods). + * */ + +/* private methods */ + +static void clear_node(queue_node_t* node) +{ + if (node != NULL) + { + clear_node(node->next); + free(node); + } +} + +static queue_node_t* create_node(int value) +{ + queue_node_t* node = malloc(sizeof(queue_node_t)); + node->value = value; + node->next = NULL; + return node; +} + +/* public methods */ + +void queue_init(queue_t* queue) +{ + queue->root = NULL; + + queue->mx_pop = (pthread_mutex_t *) calloc(1, sizeof(pthread_mutex_t)); + queue->mx_push = (pthread_mutex_t *) calloc(1, sizeof(pthread_mutex_t)); + queue->mx_valid_root = (pthread_mutex_t *) calloc(1, sizeof(pthread_mutex_t)); + queue->valid_root = (pthread_cond_t *) calloc(1, sizeof(pthread_cond_t)); + + pthread_mutex_init(queue->mx_pop, NULL); + pthread_mutex_init(queue->mx_push, NULL); + pthread_mutex_init(queue->mx_valid_root, NULL); + + pthread_cond_init(queue->valid_root, NULL); + + return; +} + +void queue_clear(queue_t* queue) +{ + clear_node(queue->root); + free(queue->mx_pop); + free(queue->mx_push); + free(queue->valid_root); + return; +} + +/* edit */ +void queue_add(queue_t* queue, int value) +{ + pthread_mutex_lock(queue->mx_push); + pthread_mutex_lock(queue->mx_valid_root); + + if (queue->root == NULL) + { + queue->root = create_node(value); + pthread_cond_signal(queue->valid_root); + pthread_mutex_unlock(queue->mx_valid_root); + } + else + { + pthread_cond_signal(queue->valid_root); + pthread_mutex_unlock(queue->mx_valid_root); + + queue_node_t* last = queue->root; + while (last->next != NULL) + { + last = last->next; + } + last->next = create_node(value); + } + pthread_mutex_unlock(queue->mx_push); + return; +} + +/* edit */ +int queue_pop(queue_t* queue) +{ + if(queue->root == NULL) { + + pthread_mutex_lock(queue->mx_valid_root); + pthread_cond_wait(queue->valid_root, queue->mx_valid_root); + pthread_mutex_unlock(queue->mx_valid_root); + } + pthread_mutex_lock(queue->mx_pop); + queue_node_t* temp = queue->root->next; + int value = queue->root->value; + free(queue->root); + queue->root = temp; + pthread_mutex_unlock(queue->mx_pop); + return value; +} diff --git a/homework/assgn9/queue.h b/homework/assgn9/queue.h new file mode 100644 index 0000000..8ef2f7f --- /dev/null +++ b/homework/assgn9/queue.h @@ -0,0 +1,21 @@ +#include +#pragma once + +typedef struct queue_node { + int value; + struct queue_node* next; +} queue_node_t; + +typedef struct queue { + queue_node_t* root; + pthread_mutex_t *mx_push, *mx_pop, *mx_valid_root; /* critical funcs are per-instance */ + pthread_cond_t *valid_root; +} queue_t; + +void queue_init(queue_t* queue); +void queue_clear(queue_t* queue); + +void queue_add(queue_t* queue, int value); +int queue_pop(queue_t* queue); + + diff --git a/lab/.sighandler.c.swp b/lab/.sighandler.c.swp new file mode 100644 index 0000000..be4b179 Binary files /dev/null and b/lab/.sighandler.c.swp differ diff --git a/lab/Makefile b/lab/Makefile new file mode 100644 index 0000000..f4116d5 --- /dev/null +++ b/lab/Makefile @@ -0,0 +1,12 @@ +.PHONY: all + +cc=/usr/bin/gcc +CARGS=-Wall -Werror -Wextra -pedantic -Wno-unused-parameter -Wno-unused -std=c99 +SRC=sighandler.c -o sighandler + +all: + $(CC) $(CARGS) $(SRC) + +debug: + $(CC) $(CARGS) $(SRC) -g -O0 + diff --git a/lab/lab4/.Makefile.swp b/lab/lab4/.Makefile.swp new file mode 100644 index 0000000..e0eac3d Binary files /dev/null and b/lab/lab4/.Makefile.swp differ diff --git a/lab/lab4/Makefile b/lab/lab4/Makefile new file mode 100644 index 0000000..fec97f3 --- /dev/null +++ b/lab/lab4/Makefile @@ -0,0 +1,12 @@ +.PHONY: all + +cc=/usr/bin/gcc +CARGS=-Wall -Werror -Wextra -pedantic -Wno-unused-parameter -Wno-unused -std=c99 +SRC=zombie.c -o zombie + +all: + $(CC) $(CARGS) $(SRC) + +debug: + $(CC) $(CARGS) $(SRC) -g -O0 + diff --git a/lab/lab5/lab5.tar.gz b/lab/lab5/lab5.tar.gz new file mode 100644 index 0000000..9f61ba4 Binary files /dev/null and b/lab/lab5/lab5.tar.gz differ diff --git a/lab/lab6/Makefile b/lab/lab6/Makefile new file mode 100644 index 0000000..fec97f3 --- /dev/null +++ b/lab/lab6/Makefile @@ -0,0 +1,12 @@ +.PHONY: all + +cc=/usr/bin/gcc +CARGS=-Wall -Werror -Wextra -pedantic -Wno-unused-parameter -Wno-unused -std=c99 +SRC=zombie.c -o zombie + +all: + $(CC) $(CARGS) $(SRC) + +debug: + $(CC) $(CARGS) $(SRC) -g -O0 + diff --git a/lab/lab5/zombie.c b/lab/lab6/zombie.c similarity index 100% rename from lab/lab5/zombie.c rename to lab/lab6/zombie.c diff --git a/lab/lab7/Makefile b/lab/lab7/Makefile new file mode 100644 index 0000000..90aba20 --- /dev/null +++ b/lab/lab7/Makefile @@ -0,0 +1,9 @@ +lab7: main.c matrix.h matrix.c + gcc -g -o lab7 main.c matrix.c -pthread + +clean: + rm lab7 + +tar: + tar -cf lab7.tar main.c matrix.h matrix.c makefile + diff --git a/lab/lab7/lab7.tar.gz b/lab/lab7/lab7.tar.gz new file mode 100644 index 0000000..54a3042 Binary files /dev/null and b/lab/lab7/lab7.tar.gz differ diff --git a/lab/lab7/main.c b/lab/lab7/main.c new file mode 100644 index 0000000..853e923 --- /dev/null +++ b/lab/lab7/main.c @@ -0,0 +1,66 @@ +#include "matrix.h" +#include +#include + +struct point { + + int r; + int c; +} pt; + +int gResult[MATRIX_SIZE][MATRIX_SIZE]; + +void mult_entry(void *ptr) { + + struct point *deref_pt = (struct point*) ptr; + + gResult[deref_pt->r][deref_pt->c] = matrix_multiply(deref_pt->r, deref_pt->c); +} + +int main(int argc, char* argv[]) +{ + int row, col; + int left[MATRIX_SIZE][MATRIX_SIZE]; + int right[MATRIX_SIZE][MATRIX_SIZE]; + pthread_t threads[100]; + + for(row = 0; row < MATRIX_SIZE; ++row) + { + for(col = 0; col < MATRIX_SIZE; ++col) + { + left[row][col] = (rand() % 2) + 1; + right[row][col] = (rand() % 3) + 1; + } + } + + // this causes setleft and setright to operate in parallel + { + pthread_t init_thread; + pthread_create(&init_thread, NULL, + ({ + void* setleft(void* arg) { set_left(left); return NULL; } + setleft; + }), NULL); + + set_right(right); + pthread_join(init_thread, NULL); + } + + /* change this loop to execute on 100 different threads (each thread does 1 row) */ + for(row = 0; row < MATRIX_SIZE; ++row) + { + for(col = 0; col < MATRIX_SIZE; ++col) + { + + struct point curPoint = { row, col }; + + pthread_create(&threads[(row * 10) + col], NULL, mult_entry, (void *) &curPoint); + } + } + /* make the above line run in parallel */ + + print_matrix(gResult); + return EXIT_SUCCESS; +} + + diff --git a/lab/lab7/matrix.c b/lab/lab7/matrix.c new file mode 100644 index 0000000..6a559b8 --- /dev/null +++ b/lab/lab7/matrix.c @@ -0,0 +1,48 @@ +#include "matrix.h" +#include +#include + +const int gLeft[MATRIX_SIZE][MATRIX_SIZE]; +const int gRight[MATRIX_SIZE][MATRIX_SIZE]; + +void set_left(int matrix[MATRIX_SIZE][MATRIX_SIZE]) +{ + memcpy(gLeft, matrix, MATRIX_SIZE * MATRIX_SIZE * sizeof(int)); + return; +} + +void set_right(int matrix[MATRIX_SIZE][MATRIX_SIZE]) +{ + memcpy(gRight, matrix, MATRIX_SIZE * MATRIX_SIZE * sizeof(int)); + return; +} + +int matrix_multiply(int row, int col) +{ + int sum = 0; + int i = 0; + for(i = 0; i < MATRIX_SIZE; ++i) + { + sum += (gLeft[row][i] * gRight[i][col]); + } + if (((row + col) % 10) == 0) + { + sleep(rand() % 3); + } + return sum; +} + +void print_matrix(int matrix[MATRIX_SIZE][MATRIX_SIZE]) +{ + int row, col; + for(row = 0; row < MATRIX_SIZE; ++row) + { + for(col = 0; col < MATRIX_SIZE; ++col) + { + printf("%d,", matrix[row][col]); + } + printf("\n"); + } + return; +} + diff --git a/lab/lab7/matrix.h b/lab/lab7/matrix.h new file mode 100644 index 0000000..5e6a6f8 --- /dev/null +++ b/lab/lab7/matrix.h @@ -0,0 +1,8 @@ +#define MATRIX_SIZE 100 + +void set_left(int matrix[MATRIX_SIZE][MATRIX_SIZE]); +void set_right(int matrix[MATRIX_SIZE][MATRIX_SIZE]); + +int matrix_multiply(int row, int col); +void print_matrix(int matrix[MATRIX_SIZE][MATRIX_SIZE]); + diff --git a/lab/lab8/.Makefile.swp b/lab/lab8/.Makefile.swp new file mode 100644 index 0000000..90713d9 Binary files /dev/null and b/lab/lab8/.Makefile.swp differ diff --git a/lab/lab8/.trivial_shell.c.swp b/lab/lab8/.trivial_shell.c.swp new file mode 100644 index 0000000..820577e Binary files /dev/null and b/lab/lab8/.trivial_shell.c.swp differ diff --git a/lab/lab8/Makefile b/lab/lab8/Makefile new file mode 100644 index 0000000..c538a93 --- /dev/null +++ b/lab/lab8/Makefile @@ -0,0 +1,12 @@ +.PHONY: all + +cc=/usr/bin/gcc +CARGS=-Wall -Werror -Wextra -pedantic -Wno-unused-parameter -Wno-unused -Wno-format -pthread +SRC=trivial_shell.c -o trivial_shell + +all: + $(CC) $(CARGS) $(SRC) + +debug: + $(CC) $(CARGS) $(SRC) -g -O0 + diff --git a/lab/lab8/lab8.tar.gz b/lab/lab8/lab8.tar.gz new file mode 100644 index 0000000..e688b0d Binary files /dev/null and b/lab/lab8/lab8.tar.gz differ diff --git a/lab/lab8/trivial_shell b/lab/lab8/trivial_shell new file mode 100755 index 0000000..5768ff0 Binary files /dev/null and b/lab/lab8/trivial_shell differ diff --git a/lab/lab8/trivial_shell.c b/lab/lab8/trivial_shell.c new file mode 100644 index 0000000..85f8f6d --- /dev/null +++ b/lab/lab8/trivial_shell.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +pthread_t threads[255]; + +void cleanup_handler(void *pipe) { + + FILE *cast_pipe; + + cast_pipe = (FILE *) pipe; + + pclose(pipe); +} + +void *exec_newthread(void *input) { + + char *cast_input, *out_buf; + FILE *out_pipe; + + out_buf = (char *) calloc(1, 512); + cast_input = (char *) input; + + out_pipe = popen(cast_input, "r"); + pthread_cleanup_push(cleanup_handler, (void *) out_pipe); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + for(;;) { + + fgets(out_buf, 255, out_pipe); + + if(feof(out_pipe)) + break; + + printf("%s", out_buf); + } + + pthread_cleanup_pop(1); + + return 0x0; +} + +int main(int argc, char *argv[]) { + + int thread_counter; + char *input_buf; + + thread_counter = 0; + input_buf = (char *) calloc(1, 512); + + while(strncmp(input_buf, "quit", 4)) { + + fgets(input_buf, 255, stdin); + + if(!strncmp(input_buf, "quit", 4)) + break; + + pthread_create(&threads[thread_counter], NULL, exec_newthread, input_buf); + pthread_detach(threads[thread_counter]); + ++thread_counter; + } + + return 0; +} + +