diff --git a/A2/fauxgrep-mt b/A2/fauxgrep-mt new file mode 100755 index 0000000..9e6d729 Binary files /dev/null and b/A2/fauxgrep-mt differ diff --git a/A2/fauxgrep-mt.c b/A2/fauxgrep-mt.c index 427d265..aff6241 100644 --- a/A2/fauxgrep-mt.c +++ b/A2/fauxgrep-mt.c @@ -19,8 +19,46 @@ #include "job_queue.h" +struct job_queue q; + +int fauxgrep_file(char const *needle, char const *path) { + 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); + } + + lineno++; + } + + free(line); + fclose(f); + + return 0; +} + +void* fauxgrep_thread(void* arg) { + //printf("thread initialized\n"); + char* needle = arg; + char const* path; + while (job_queue_pop(&q, (void**) &path) == 0) { + fauxgrep_file(needle, path); + } + return NULL; +} + int main(int argc, char * const *argv) { - if (argc < 2) { + if (argc < 3 || (argc == 4 && strcmp(argv[1], "-n") == 0)) { err(1, "usage: [-n INT] STRING paths..."); exit(1); } @@ -51,7 +89,15 @@ int main(int argc, char * const *argv) { paths = &argv[2]; } - assert(0); // Initialise the job queue and some worker threads here. + //printf("Initializing job queue\n"); + job_queue_init(&q, 64); + pthread_t threads[num_threads]; + + for (int i = 0 ; i < num_threads ; i++) { + //printf("Initializing thread %i\n", i); + pthread_create(&threads[i], NULL, fauxgrep_thread, strdup(needle)); + } + //printf("finished initializing threads\n"); // FTS_LOGICAL = follow symbolic links // FTS_NOCHDIR = do not change the working directory of the process @@ -72,7 +118,7 @@ int main(int argc, char * const *argv) { case FTS_D: break; case FTS_F: - assert(0); // Process the file p->fts_path, somehow. + job_queue_push(&q, strdup(p->fts_path)); break; default: break; @@ -81,7 +127,11 @@ int main(int argc, char * const *argv) { fts_close(ftsp); - assert(0); // Shut down the job queue and the worker threads here. + job_queue_destroy(&q); + + for (int i = 0 ; i < num_threads ; i++) { + pthread_join(threads[i], NULL); + } return 0; } diff --git a/A2/job_queue.c b/A2/job_queue.c index 19a4f24..58435d4 100644 --- a/A2/job_queue.c +++ b/A2/job_queue.c @@ -31,6 +31,7 @@ int job_queue_destroy(struct job_queue *job_queue) { pthread_mutex_lock(&queue_operation); free(job_queue->jobs); + job_queue->jobs = NULL; pthread_mutex_unlock(&queue_push); pthread_mutex_unlock(&queue_pop); @@ -42,6 +43,7 @@ int job_queue_destroy(struct job_queue *job_queue) { int job_queue_push(struct job_queue *job_queue, void *data) { pthread_mutex_lock(&queue_push); pthread_mutex_lock(&queue_operation); + //printf("push start\n"); job_queue->jobs[job_queue->size] = data; job_queue->size = job_queue->size + 1; @@ -52,9 +54,10 @@ int job_queue_push(struct job_queue *job_queue, void *data) { if (job_queue->size == 1) { pthread_mutex_unlock(&queue_pop); - pthread_mutex_lock(&queue_destroy); + pthread_mutex_trylock(&queue_destroy); } + //printf("push end\n"); pthread_mutex_unlock(&queue_operation); return 0; } @@ -62,12 +65,15 @@ int job_queue_push(struct job_queue *job_queue, void *data) { int job_queue_pop(struct job_queue *job_queue, void **data) { pthread_mutex_lock(&queue_pop); pthread_mutex_lock(&queue_operation); + //printf("pop start\n"); - if (job_queue == NULL) { + if (job_queue->jobs == NULL) { + //printf("no more job queue\n"); pthread_mutex_unlock(&queue_pop); pthread_mutex_unlock(&queue_operation); return -1; } + //printf("job queue\n"); job_queue->size = job_queue->size - 1; *data = job_queue->jobs[job_queue->size]; @@ -84,6 +90,7 @@ int job_queue_pop(struct job_queue *job_queue, void **data) { pthread_mutex_unlock(&queue_pop); } + //printf("pop end\n"); pthread_mutex_unlock(&queue_operation); return 0; } diff --git a/A2/testfile b/A2/testfile index c0911b9..80374c6 100755 Binary files a/A2/testfile and b/A2/testfile differ