diff --git a/A2/Makefile b/A2/Makefile index e10c2f4..0211b6d 100644 --- a/A2/Makefile +++ b/A2/Makefile @@ -1,5 +1,6 @@ CC=gcc -CFLAGS=-g -Wall -Wextra -pedantic -std=gnu99 -pthread +#CFLAGS=-g -Wall -Wextra -pedantic -std=gnu99 -pthread +CFLAGS=-g -pthread EXAMPLES=fibs fauxgrep fauxgrep-mt fhistogram fhistogram-mt .PHONY: all test clean ../src.zip diff --git a/A2/fauxgrep-mt.c b/A2/fauxgrep-mt.c index 25b47ce..427d265 100644 --- a/A2/fauxgrep-mt.c +++ b/A2/fauxgrep-mt.c @@ -20,68 +20,68 @@ #include "job_queue.h" int main(int argc, char * const *argv) { - if (argc < 2) { - err(1, "usage: [-n INT] STRING paths..."); - exit(1); - } - - int num_threads = 1; - char const *needle = argv[1]; - char * const *paths = &argv[2]; - - - if (argc > 3 && strcmp(argv[1], "-n") == 0) { - // Since atoi() simply returns zero on syntax errors, we cannot - // distinguish between the user entering a zero, or some - // non-numeric garbage. In fact, we cannot even tell whether the - // given option is suffixed by garbage, i.e. '123foo' returns - // '123'. A more robust solution would use strtol(), but its - // interface is more complicated, so here we are. - num_threads = atoi(argv[2]); - - if (num_threads < 1) { - err(1, "invalid thread count: %s", argv[2]); + if (argc < 2) { + err(1, "usage: [-n INT] STRING paths..."); + exit(1); } - needle = argv[3]; - paths = &argv[4]; + int num_threads = 1; + char const *needle = argv[1]; + char * const *paths = &argv[2]; - } else { - needle = argv[1]; - paths = &argv[2]; - } - assert(0); // Initialise the job queue and some worker threads here. + if (argc > 3 && strcmp(argv[1], "-n") == 0) { + // Since atoi() simply returns zero on syntax errors, we cannot + // distinguish between the user entering a zero, or some + // non-numeric garbage. In fact, we cannot even tell whether the + // given option is suffixed by garbage, i.e. '123foo' returns + // '123'. A more robust solution would use strtol(), but its + // interface is more complicated, so here we are. + num_threads = atoi(argv[2]); - // FTS_LOGICAL = follow symbolic links - // FTS_NOCHDIR = do not change the working directory of the process - // - // (These are not particularly important distinctions for our simple - // uses.) - int fts_options = FTS_LOGICAL | FTS_NOCHDIR; + if (num_threads < 1) { + err(1, "invalid thread count: %s", argv[2]); + } - FTS *ftsp; - if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { - err(1, "fts_open() failed"); - return -1; - } + needle = argv[3]; + paths = &argv[4]; - FTSENT *p; - while ((p = fts_read(ftsp)) != NULL) { - switch (p->fts_info) { - case FTS_D: - break; - case FTS_F: - assert(0); // Process the file p->fts_path, somehow. - break; - default: - break; + } else { + needle = argv[1]; + paths = &argv[2]; } - } - fts_close(ftsp); + assert(0); // Initialise the job queue and some worker threads here. - assert(0); // Shut down the job queue and the worker threads here. + // FTS_LOGICAL = follow symbolic links + // FTS_NOCHDIR = do not change the working directory of the process + // + // (These are not particularly important distinctions for our simple + // uses.) + int fts_options = FTS_LOGICAL | FTS_NOCHDIR; - return 0; + FTS *ftsp; + if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { + err(1, "fts_open() failed"); + return -1; + } + + FTSENT *p; + while ((p = fts_read(ftsp)) != NULL) { + switch (p->fts_info) { + case FTS_D: + break; + case FTS_F: + assert(0); // Process the file p->fts_path, somehow. + break; + default: + break; + } + } + + fts_close(ftsp); + + assert(0); // Shut down the job queue and the worker threads here. + + return 0; } diff --git a/A2/fauxgrep.c b/A2/fauxgrep.c index 80eedc8..4e92c88 100644 --- a/A2/fauxgrep.c +++ b/A2/fauxgrep.c @@ -16,67 +16,67 @@ #include int fauxgrep_file(char const *needle, char const *path) { - FILE *f = fopen(path, "r"); + FILE *f = fopen(path, "r"); - if (f == NULL) { - warn("failed to open %s", path); - return -1; - } - - char *line = NULL; - size_t linelen = 0; - int lineno = 1; - - while (getline(&line, &linelen, f) != -1) { - if (strstr(line, needle) != NULL) { - printf("%s:%d: %s", path, lineno, line); + if (f == NULL) { + warn("failed to open %s", path); + return -1; } - lineno++; - } + char *line = NULL; + size_t linelen = 0; + int lineno = 1; - free(line); - fclose(f); + while (getline(&line, &linelen, f) != -1) { + if (strstr(line, needle) != NULL) { + printf("%s:%d: %s", path, lineno, line); + } - return 0; + lineno++; + } + + free(line); + fclose(f); + + return 0; } int main(int argc, char * const *argv) { - if (argc < 2) { - err(1, "usage: STRING paths..."); - exit(1); - } - - char const *needle = argv[1]; - char * const *paths = &argv[2]; - - // FTS_LOGICAL = follow symbolic links - // FTS_NOCHDIR = do not change the working directory of the process - // - // (These are not particularly important distinctions for our simple - // uses.) - int fts_options = FTS_LOGICAL | FTS_NOCHDIR; - - FTS *ftsp; - if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { - err(1, "fts_open() failed"); - return -1; - } - - FTSENT *p; - while ((p = fts_read(ftsp)) != NULL) { - switch (p->fts_info) { - case FTS_D: - break; - case FTS_F: - fauxgrep_file(needle, p->fts_path); - break; - default: - break; + if (argc < 2) { + err(1, "usage: STRING paths..."); + exit(1); } - } - fts_close(ftsp); + char const *needle = argv[1]; + char * const *paths = &argv[2]; - return 0; + // FTS_LOGICAL = follow symbolic links + // FTS_NOCHDIR = do not change the working directory of the process + // + // (These are not particularly important distinctions for our simple + // uses.) + int fts_options = FTS_LOGICAL | FTS_NOCHDIR; + + FTS *ftsp; + if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { + err(1, "fts_open() failed"); + return -1; + } + + FTSENT *p; + while ((p = fts_read(ftsp)) != NULL) { + switch (p->fts_info) { + case FTS_D: + break; + case FTS_F: + fauxgrep_file(needle, p->fts_path); + break; + default: + break; + } + } + + fts_close(ftsp); + + return 0; } diff --git a/A2/fhistogram-mt.c b/A2/fhistogram-mt.c index b6b4537..25f28db 100644 --- a/A2/fhistogram-mt.c +++ b/A2/fhistogram-mt.c @@ -23,65 +23,65 @@ pthread_mutex_t stdout_mutex = PTHREAD_MUTEX_INITIALIZER; #include "histogram.h" int main(int argc, char * const *argv) { - if (argc < 2) { - err(1, "usage: paths..."); - exit(1); - } - - int num_threads = 1; - char * const *paths = &argv[1]; - - if (argc > 3 && strcmp(argv[1], "-n") == 0) { - // Since atoi() simply returns zero on syntax errors, we cannot - // distinguish between the user entering a zero, or some - // non-numeric garbage. In fact, we cannot even tell whether the - // given option is suffixed by garbage, i.e. '123foo' returns - // '123'. A more robust solution would use strtol(), but its - // interface is more complicated, so here we are. - num_threads = atoi(argv[2]); - - if (num_threads < 1) { - err(1, "invalid thread count: %s", argv[2]); + if (argc < 2) { + err(1, "usage: paths..."); + exit(1); } - paths = &argv[3]; - } else { - paths = &argv[1]; - } + int num_threads = 1; + char * const *paths = &argv[1]; - assert(0); // Initialise the job queue and some worker threads here. + if (argc > 3 && strcmp(argv[1], "-n") == 0) { + // Since atoi() simply returns zero on syntax errors, we cannot + // distinguish between the user entering a zero, or some + // non-numeric garbage. In fact, we cannot even tell whether the + // given option is suffixed by garbage, i.e. '123foo' returns + // '123'. A more robust solution would use strtol(), but its + // interface is more complicated, so here we are. + num_threads = atoi(argv[2]); - // FTS_LOGICAL = follow symbolic links - // FTS_NOCHDIR = do not change the working directory of the process - // - // (These are not particularly important distinctions for our simple - // uses.) - int fts_options = FTS_LOGICAL | FTS_NOCHDIR; + if (num_threads < 1) { + err(1, "invalid thread count: %s", argv[2]); + } - FTS *ftsp; - if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { - err(1, "fts_open() failed"); - return -1; - } - - FTSENT *p; - while ((p = fts_read(ftsp)) != NULL) { - switch (p->fts_info) { - case FTS_D: - break; - case FTS_F: - assert(0); // Process the file p->fts_path, somehow. - break; - default: - break; + paths = &argv[3]; + } else { + paths = &argv[1]; } - } - fts_close(ftsp); + assert(0); // Initialise the job queue and some worker threads here. - assert(0); // Shut down the job queue and the worker threads here. + // FTS_LOGICAL = follow symbolic links + // FTS_NOCHDIR = do not change the working directory of the process + // + // (These are not particularly important distinctions for our simple + // uses.) + int fts_options = FTS_LOGICAL | FTS_NOCHDIR; - move_lines(9); + FTS *ftsp; + if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { + err(1, "fts_open() failed"); + return -1; + } - return 0; + FTSENT *p; + while ((p = fts_read(ftsp)) != NULL) { + switch (p->fts_info) { + case FTS_D: + break; + case FTS_F: + assert(0); // Process the file p->fts_path, somehow. + break; + default: + break; + } + } + + fts_close(ftsp); + + assert(0); // Shut down the job queue and the worker threads here. + + move_lines(9); + + return 0; } diff --git a/A2/fhistogram.c b/A2/fhistogram.c index e070983..3f56d3e 100644 --- a/A2/fhistogram.c +++ b/A2/fhistogram.c @@ -21,73 +21,73 @@ int global_histogram[8] = { 0 }; int fhistogram(char const *path) { - FILE *f = fopen(path, "r"); + FILE *f = fopen(path, "r"); - int local_histogram[8] = { 0 }; + int local_histogram[8] = { 0 }; - if (f == NULL) { - fflush(stdout); - warn("failed to open %s", path); - return -1; - } - - int i = 0; - - char c; - while (fread(&c, sizeof(c), 1, f) == 1) { - i++; - update_histogram(local_histogram, c); - if ((i % 100000) == 0) { - merge_histogram(local_histogram, global_histogram); - print_histogram(global_histogram); + if (f == NULL) { + fflush(stdout); + warn("failed to open %s", path); + return -1; } - } - fclose(f); + int i = 0; - merge_histogram(local_histogram, global_histogram); - print_histogram(global_histogram); + char c; + while (fread(&c, sizeof(c), 1, f) == 1) { + i++; + update_histogram(local_histogram, c); + if ((i % 100000) == 0) { + merge_histogram(local_histogram, global_histogram); + print_histogram(global_histogram); + } + } - return 0; + fclose(f); + + merge_histogram(local_histogram, global_histogram); + print_histogram(global_histogram); + + return 0; } int main(int argc, char * const *argv) { - if (argc < 2) { - err(1, "usage: paths..."); - exit(1); - } - - char * const *paths = &argv[1]; - - // FTS_LOGICAL = follow symbolic links - // FTS_NOCHDIR = do not change the working directory of the process - // - // (These are not particularly important distinctions for our simple - // uses.) - int fts_options = FTS_LOGICAL | FTS_NOCHDIR; - - FTS *ftsp; - if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { - err(1, "fts_open() failed"); - return -1; - } - - FTSENT *p; - while ((p = fts_read(ftsp)) != NULL) { - switch (p->fts_info) { - case FTS_D: - break; - case FTS_F: - fhistogram(p->fts_path); - break; - default: - break; + if (argc < 2) { + err(1, "usage: paths..."); + exit(1); } - } - fts_close(ftsp); + char * const *paths = &argv[1]; - move_lines(9); + // FTS_LOGICAL = follow symbolic links + // FTS_NOCHDIR = do not change the working directory of the process + // + // (These are not particularly important distinctions for our simple + // uses.) + int fts_options = FTS_LOGICAL | FTS_NOCHDIR; - return 0; + FTS *ftsp; + if ((ftsp = fts_open(paths, fts_options, NULL)) == NULL) { + err(1, "fts_open() failed"); + return -1; + } + + FTSENT *p; + while ((p = fts_read(ftsp)) != NULL) { + switch (p->fts_info) { + case FTS_D: + break; + case FTS_F: + fhistogram(p->fts_path); + break; + default: + break; + } + } + + fts_close(ftsp); + + move_lines(9); + + return 0; } diff --git a/A2/fibs.c b/A2/fibs.c index e92c6d7..98d11b2 100644 --- a/A2/fibs.c +++ b/A2/fibs.c @@ -1,6 +1,6 @@ // This program reads a newline-separated sequence of integers from -// standard input. For each such integer, the corresponding Fibonacci -// number is printed. This is similar to the programs we saw at the +// standard input. For each such integer, the corresponding Fibonacci +// number is printed. This is similar to the programs we saw at the // November 20 lecture. // Setting _DEFAULT_SOURCE is necessary to activate visibility of @@ -31,92 +31,92 @@ pthread_mutex_t stdout_mutex = PTHREAD_MUTEX_INITIALIZER; // A simple recursive (inefficient) implementation of the Fibonacci // function. int fib (int n) { - if (n < 2) { - return 1; - } else { - return fib(n-1) + fib(n-2); - } + if (n < 2) { + return 1; + } else { + return fib(n-1) + fib(n-2); + } } // This function converts a line to an integer, computes the // corresponding Fibonacci number, then prints the result to the // screen. void fib_line(const char *line) { - int n = atoi(line); - int fibn = fib(n); - assert(pthread_mutex_lock(&stdout_mutex) == 0); - printf("fib(%d) = %d\n", n, fibn); - assert(pthread_mutex_unlock(&stdout_mutex) == 0); + int n = atoi(line); + int fibn = fib(n); + assert(pthread_mutex_lock(&stdout_mutex) == 0); + printf("fib(%d) = %d\n", n, fibn); + assert(pthread_mutex_unlock(&stdout_mutex) == 0); } -// Each thread will run this function. The thread argument is a +// Each thread will run this function. The thread argument is a // pointer to a job queue. void* worker(void *arg) { - struct job_queue *jq = arg; + struct job_queue *jq = arg; - while (1) { - char *line; - if (job_queue_pop(jq, (void**)&line) == 0) { - fib_line(line); - free(line); - } else { - // If job_queue_pop() returned non-zero, that means the queue is - // being killed (or some other error occured). In any case, - // that means it's time for this thread to die. - break; + while (1) { + char *line; + if (job_queue_pop(jq, (void**)&line) == 0) { + fib_line(line); + free(line); + } else { + // If job_queue_pop() returned non-zero, that means the queue is + // being killed (or some other error occured). In any case, + // that means it's time for this thread to die. + break; + } } - } - return NULL; + return NULL; } int main(int argc, char * const *argv) { - int num_threads = 1; + int num_threads = 1; - if (argc == 3 && strcmp(argv[1], "-n") == 0) { - // Since atoi() simply returns zero on syntax errors, we cannot - // distinguish between the user entering a zero, or some - // non-numeric garbage. In fact, we cannot even tell whether the - // given option is suffixed by garbage, i.e. '123foo' returns - // '123'. A more robust solution would use strtol(), but its - // interface is more complicated, so here we are. - num_threads = atoi(argv[2]); + if (argc == 3 && strcmp(argv[1], "-n") == 0) { + // Since atoi() simply returns zero on syntax errors, we cannot + // distinguish between the user entering a zero, or some + // non-numeric garbage. In fact, we cannot even tell whether the + // given option is suffixed by garbage, i.e. '123foo' returns + // '123'. A more robust solution would use strtol(), but its + // interface is more complicated, so here we are. + num_threads = atoi(argv[2]); - if (num_threads < 1) { - err(1, "invalid thread count: %s", argv[2]); + if (num_threads < 1) { + err(1, "invalid thread count: %s", argv[2]); + } } - } - // Create job queue. - struct job_queue jq; - job_queue_init(&jq, 64); + // Create job queue. + struct job_queue jq; + job_queue_init(&jq, 64); - // Start up the worker threads. - pthread_t *threads = calloc(num_threads, sizeof(pthread_t)); - for (int i = 0; i < num_threads; i++) { - if (pthread_create(&threads[i], NULL, &worker, &jq) != 0) { - err(1, "pthread_create() failed"); + // Start up the worker threads. + pthread_t *threads = calloc(num_threads, sizeof(pthread_t)); + for (int i = 0; i < num_threads; i++) { + if (pthread_create(&threads[i], NULL, &worker, &jq) != 0) { + err(1, "pthread_create() failed"); + } } - } - // Now read lines from stdin until EOF. - char *line = NULL; - ssize_t line_len; - size_t buf_len = 0; - while ((line_len = getline(&line, &buf_len, stdin)) != -1) { - job_queue_push(&jq, (void*)strdup(line)); - } - free(line); - - // Destroy the queue. - job_queue_destroy(&jq); - - // Wait for all threads to finish. This is important, at some may - // still be working on their job. - for (int i = 0; i < num_threads; i++) { - if (pthread_join(threads[i], NULL) != 0) { - err(1, "pthread_join() failed"); + // Now read lines from stdin until EOF. + char *line = NULL; + ssize_t line_len; + size_t buf_len = 0; + while ((line_len = getline(&line, &buf_len, stdin)) != -1) { + job_queue_push(&jq, (void*)strdup(line)); + } + free(line); + + // Destroy the queue. + job_queue_destroy(&jq); + + // Wait for all threads to finish. This is important, at some may + // still be working on their job. + for (int i = 0; i < num_threads; i++) { + if (pthread_join(threads[i], NULL) != 0) { + err(1, "pthread_join() failed"); + } } - } } diff --git a/A2/histogram.h b/A2/histogram.h index 967e00a..a94d96a 100644 --- a/A2/histogram.h +++ b/A2/histogram.h @@ -1,5 +1,5 @@ // This header file contains not just function prototypes, but also -// the definitions. This means it does not need to be compiled +// the definitions. This means it does not need to be compiled // separately. // // You should not need to modify this file. @@ -7,65 +7,65 @@ #ifndef HISTOGRAM_H #define HISTOGRAM_H -// Move the cursor down 'n' lines. Negative 'n' supported. +// Move the cursor down 'n' lines. Negative 'n' supported. static void move_lines(int n) { - if (n < 0) { - printf("\033[%dA", -n); - } else { - printf("\033[%dB", n); - } + if (n < 0) { + printf("\033[%dA", -n); + } else { + printf("\033[%dB", n); + } } // Clear from cursor to end of line. static void clear_line() { - printf("\033[K"); + printf("\033[K"); } -// Print a visual representation of a histogram to the screen. After +// Print a visual representation of a histogram to the screen. After // printing, the cursor is moved back to the beginning of the output. // This means that next time print_histogram() is called, the previous // output will be overwritten. static void print_histogram(int histogram[8]) { - int64_t bits_seen = 0; + int64_t bits_seen = 0; - for (int i = 0; i < 8; i++) { - bits_seen += histogram[i]; - } - - for (int i = 0; i < 8; i++) { - clear_line(); - printf("Bit %d: ", i); - - double proportion = histogram[i] / ((double)bits_seen); - for (int i = 0; i < 60*proportion; i++) { - printf("*"); + for (int i = 0; i < 8; i++) { + bits_seen += histogram[i]; } - printf("\n"); - } - clear_line(); - printf("%ld bits processed.\n", (long)bits_seen); - move_lines(-9); + for (int i = 0; i < 8; i++) { + clear_line(); + printf("Bit %d: ", i); + + double proportion = histogram[i] / ((double)bits_seen); + for (int i = 0; i < 60*proportion; i++) { + printf("*"); + } + printf("\n"); + } + + clear_line(); + printf("%ld bits processed.\n", (long)bits_seen); + move_lines(-9); } // Merge the former histogram into the latter, setting the former to // zero in the process. static void merge_histogram(int from[8], int to[8]) { - for (int i = 0; i < 8; i++) { - to[i] += from[i]; - from[i] = 0; - } + for (int i = 0; i < 8; i++) { + to[i] += from[i]; + from[i] = 0; + } } // Update the histogram with the bits of a byte. static void update_histogram(int histogram[8], unsigned char byte) { - // For all bits in a byte... - for (int i = 0; i < 8; i++) { - // count if bit 'i' is set. - if (byte & (1<capacity = capacity; + job_queue->size = 0; + job_queue->jobs = malloc(capacity); + + pthread_mutex_unlock(&queue_operation); + pthread_mutex_unlock(&queue_push); + pthread_mutex_unlock(&queue_destroy); + return 0; } int job_queue_destroy(struct job_queue *job_queue) { - assert(0); + printf("esauc\n"); + pthread_mutex_lock(&queue_destroy); + pthread_mutex_lock(&queue_operation); + + printf("esauc\n"); + //free(job_queue->jobs); + printf("esauc\n"); + //free(job_queue); + printf("esauc\n"); + + pthread_mutex_unlock(&queue_push); + pthread_mutex_unlock(&queue_pop); + pthread_mutex_unlock(&queue_destroy); + pthread_mutex_unlock(&queue_operation); + return 0; } int job_queue_push(struct job_queue *job_queue, void *data) { - assert(0); + pthread_mutex_lock(&queue_push); + pthread_mutex_lock(&queue_operation); + + (&job_queue->jobs)[job_queue->size] = data; + job_queue->size = job_queue->size + 1; + + if (job_queue->size != job_queue->capacity) { + pthread_mutex_unlock(&queue_push); + } + + if (job_queue->size == 1) { + pthread_mutex_unlock(&queue_pop); + pthread_mutex_lock(&queue_destroy); + } + + pthread_mutex_unlock(&queue_operation); + return 0; } int job_queue_pop(struct job_queue *job_queue, void **data) { - assert(0); + pthread_mutex_lock(&queue_pop); + pthread_mutex_lock(&queue_operation); + + if (job_queue == NULL) { + pthread_mutex_unlock(&queue_pop); + pthread_mutex_unlock(&queue_operation); + return -1; + } + + job_queue->size = job_queue->size - 1; + *data = (&job_queue->jobs)[job_queue->size]; + + if (job_queue->size == 0) { + pthread_mutex_unlock(&queue_destroy); + } + + if (job_queue->size != 0) { + pthread_mutex_unlock(&queue_pop); + } + + if (job_queue->size == job_queue->capacity - 1) { + pthread_mutex_unlock(&queue_pop); + } + + pthread_mutex_unlock(&queue_operation); + return 0; } diff --git a/A2/job_queue.h b/A2/job_queue.h index e21a00f..a20275d 100644 --- a/A2/job_queue.h +++ b/A2/job_queue.h @@ -4,25 +4,27 @@ #include struct job_queue { - int dummy; + int capacity; + int size; + void* jobs; }; -// Initialise a job queue with the given capacity. The queue starts out -// empty. Returns non-zero on error. +// Initialise a job queue with the given capacity. The queue starts out +// empty. Returns non-zero on error. int job_queue_init(struct job_queue *job_queue, int capacity); -// Destroy the job queue. Blocks until the queue is empty before it +// Destroy the job queue. Blocks until the queue is empty before it // is destroyed. int job_queue_destroy(struct job_queue *job_queue); -// Push an element onto the end of the job queue. Blocks if the -// job_queue is full (its size is equal to its capacity). Returns -// non-zero on error. It is an error to push a job onto a queue that +// Push an element onto the end of the job queue. Blocks if the +// job_queue is full (its size is equal to its capacity). Returns +// non-zero on error. It is an error to push a job onto a queue that // has been destroyed. int job_queue_push(struct job_queue *job_queue, void *data); -// Pop an element from the front of the job queue. Blocks if the -// job_queue contains zero elements. Returns non-zero on error. If +// Pop an element from the front of the job queue. Blocks if the +// job_queue contains zero elements. Returns non-zero on error. If // job_queue_destroy() has been called (possibly after the call to // job_queue_pop() blocked), this function will return -1. int job_queue_pop(struct job_queue *job_queue, void **data); diff --git a/A2/testfile b/A2/testfile new file mode 100755 index 0000000..3cb9c7f Binary files /dev/null and b/A2/testfile differ diff --git a/A2/testfile.c b/A2/testfile.c new file mode 100644 index 0000000..341a6c7 --- /dev/null +++ b/A2/testfile.c @@ -0,0 +1,16 @@ +#include +#include + +#include "job_queue.h" + +int main() { + struct job_queue q; + int b = 5; + job_queue_init(&q, 64); + job_queue_push(&q, &b); + void* a = malloc(1); + job_queue_pop(&q, &a); + printf("%i\n",*((int *) a)); + printf("esauc\n"); + job_queue_destroy(&q); +} \ No newline at end of file