--- /dev/null
+#include "queue.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+#include <time.h>
+
+#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;
+}
+
--- /dev/null
+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
+
--- /dev/null
+#include "queue.h"
+#include <stdlib.h>
+#include <pthread.h>
+
+/* 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;
+}
--- /dev/null
+#include <pthread.h>
+#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);
+
+
--- /dev/null
+.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
+
--- /dev/null
+.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
+
--- /dev/null
+.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
+
--- /dev/null
+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
+
--- /dev/null
+#include "matrix.h"
+#include <stdlib.h>
+#include <pthread.h>
+
+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;
+}
+
+
--- /dev/null
+#include "matrix.h"
+#include <string.h>
+#include <stdio.h>
+
+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;
+}
+
--- /dev/null
+#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]);
+
--- /dev/null
+.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
+
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <string.h>
+#include <signal.h>
+
+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;
+}
+
+