From 2af04d6ec602b2068d35d5b976f070a1b065f307 Mon Sep 17 00:00:00 2001
From: dec05eba <dec05eba@protonmail.com>
Date: Fri, 1 Mar 2019 05:04:45 +0100
Subject: Fix compiler join thread, fix compiliation with clang

---
 include/compiler.h             |  2 +-
 include/defs.h                 |  2 +-
 include/std/buffer.h           |  2 +-
 include/std/defs.h             |  2 +-
 include/std/file.h             |  2 +-
 include/std/log.h              |  2 +-
 include/std/mem.h              |  2 +-
 include/std/misc.h             |  2 +-
 include/std/scoped_allocator.h |  2 +-
 include/std/thread.h           |  2 +-
 src/ast.c                      |  2 +-
 src/compiler.c                 | 52 ++++++++++++++++++++++++++++++++++--------
 src/parser.c                   |  8 ++-----
 src/std/buffer.c               |  2 +-
 src/std/buffer_view.c          |  2 +-
 src/std/file.c                 |  2 +-
 src/std/log.c                  |  2 +-
 src/std/mem.c                  |  2 +-
 src/std/scoped_allocator.c     |  2 +-
 src/std/thread.c               |  2 +-
 src/tokenizer.c                |  2 +-
 21 files changed, 64 insertions(+), 34 deletions(-)

diff --git a/include/compiler.h b/include/compiler.h
index 691263a..d01c756 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -28,4 +28,4 @@ CHECK_RESULT int amal_compiler_deinit(amal_compiler *self);
 CHECK_RESULT int amal_compiler_load_file(amal_compiler *self, BufferView filepath);
 /* TODO: amal_compiler_unload_file */
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/defs.h b/include/defs.h
index 9b754d8..2baceb4 100644
--- a/include/defs.h
+++ b/include/defs.h
@@ -4,4 +4,4 @@
 typedef struct ParserThreadData ParserThreadData;
 typedef struct amal_compiler amal_compiler;
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/buffer.h b/include/std/buffer.h
index ed87f29..02cc20a 100644
--- a/include/std/buffer.h
+++ b/include/std/buffer.h
@@ -20,4 +20,4 @@ CHECK_RESULT int buffer_append(Buffer *self, void *data, usize size);
 void* buffer_get(Buffer *self, usize index, usize type_size);
 CHECK_RESULT int buffer_pop(Buffer *self, void *data, usize size);
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/defs.h b/include/std/defs.h
index 1376e16..653bf73 100644
--- a/include/std/defs.h
+++ b/include/std/defs.h
@@ -4,4 +4,4 @@
 typedef struct amal_thread amal_thread;
 typedef struct amal_mutex amal_mutex;
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/file.h b/include/std/file.h
index 53d9da3..4224346 100644
--- a/include/std/file.h
+++ b/include/std/file.h
@@ -26,4 +26,4 @@ CHECK_RESULT int mapped_file_deinit(MappedFile *self);
 
 CHECK_RESULT int read_whole_file(const char *filepath, char **data, usize *size);
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/log.h b/include/std/log.h
index 6ce9e4c..d13c5bf 100644
--- a/include/std/log.h
+++ b/include/std/log.h
@@ -10,4 +10,4 @@ void amal_log_info(const char *fmt, ...);
 void amal_log_warning(const char *fmt, ...);
 void amal_log_perror(const char *prefix);
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/mem.h b/include/std/mem.h
index a5fe9b4..8d91a5a 100644
--- a/include/std/mem.h
+++ b/include/std/mem.h
@@ -8,4 +8,4 @@ void am_memcpy(void *dest, const void *src, usize size);
 bool am_memeql(const void *lhs, const void *rhs, usize size);
 void am_memset(void *dest, int value, usize size);
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/misc.h b/include/std/misc.h
index 3ac524a..b979d9c 100644
--- a/include/std/misc.h
+++ b/include/std/misc.h
@@ -30,4 +30,4 @@ typedef enum {
 #define NULL ((void*)0)
 #endif
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/scoped_allocator.h b/include/std/scoped_allocator.h
index fdaee2a..ad6e2dd 100644
--- a/include/std/scoped_allocator.h
+++ b/include/std/scoped_allocator.h
@@ -28,4 +28,4 @@ void scoped_allocator_deinit(ScopedAllocator *self);
 CHECK_RESULT int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem);
 CHECK_RESULT int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer);
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/std/thread.h b/include/std/thread.h
index dd09039..972ce3a 100644
--- a/include/std/thread.h
+++ b/include/std/thread.h
@@ -47,4 +47,4 @@ bool amal_thread_is_main();
 /* Returns 0 if the number of usable threads is unknown */
 int amal_get_usable_thread_count();
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/ast.c b/src/ast.c
index 0acc69c..56eb34f 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -29,4 +29,4 @@ void lhsexpr_init(LhsExpr *self, int isConst, BufferView var_name) {
 
 void import_init(Import *self, BufferView path) {
     self->path = path;
-}
\ No newline at end of file
+}
diff --git a/src/compiler.c b/src/compiler.c
index 3e04ef2..b8bca1c 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -158,22 +158,56 @@ static CHECK_RESULT int amal_compiler_load_file_select_thread(amal_compiler *sel
     return result;
 }
 
+static CHECK_RESULT int amal_compiler_all_threads_done(amal_compiler *self, bool *done) {
+    int i;
+    int result;
+    result = AMAL_COMPILER_OK;
+    *done = bool_false;
+
+    cleanup_if_error(amal_mutex_lock(&self->mutex, "amal_compiler_all_threads_done"));
+    for(i = 0; i < self->usable_thread_count; ++i) {
+        ParserThreadData *parser_thread_data;
+        parser_thread_data = &self->threads[i];
+        if(parser_thread_data->status == PARSER_THREAD_STATUS_RUNNING) {
+            result = AMAL_COMPILER_ERR;
+            goto cleanup;
+        }
+    }
+
+    *done = bool_true;
+    cleanup:
+    amal_mutex_tryunlock(&self->mutex);
+    return result;
+}
+
 static CHECK_RESULT int amal_compiler_load_file_join_threads(amal_compiler *self) {
     int i;
-    int _;
     int result;
     void *thread_return_data;
     ParserThreadData *parser_thread_data;
     result = AMAL_COMPILER_ERR;
-    (void)_;
     assert(amal_thread_is_main());
 
-    for(i = 0; i < self->usable_thread_count; ++i) {
-        cleanup_if_error(amal_mutex_lock(&self->mutex, "amal_compiler_load_file_join_threads, waiting for workers"));
-        parser_thread_data = &self->threads[i];
-        amal_mutex_tryunlock(&self->mutex);
-        amal_log_debug("Joining thread %d, status %d", i, parser_thread_data->status);
-        _ = parser_thread_data_join(parser_thread_data, &thread_return_data);
+    for(;;) {
+        bool done;
+        /*
+        Joining running threads. After checking one running thread another one might start up,
+        so this is mostly to wait for threads to finish and to sleep without doing work.
+        The check after that (amal_compiler_all_threads_done) check that all threads are done correctly
+        */
+        for(i = 0; i < self->usable_thread_count; ++i) {
+            result = amal_mutex_lock(&self->mutex, "amal_compiler_load_file_join_threads, waiting for workers");
+            parser_thread_data = &self->threads[i];
+            amal_mutex_tryunlock(&self->mutex);
+            if(result != 0)
+                goto cleanup;
+            amal_log_debug("Joining thread %d, status %d", i, parser_thread_data->status);
+            ignore_result_int(parser_thread_data_join(parser_thread_data, &thread_return_data));
+        }
+
+        cleanup_if_error(amal_compiler_all_threads_done(self, &done));
+        if(done)
+            break;
     }
 
     result = AMAL_COMPILER_OK;
@@ -209,4 +243,4 @@ int amal_compiler_load_file(amal_compiler *self, BufferView filepath) {
     cleanup:
     amal_mutex_tryunlock(&self->mutex);
     return result;
-}
\ No newline at end of file
+}
diff --git a/src/parser.c b/src/parser.c
index bb7c8d3..81f0a92 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -33,13 +33,9 @@ int parser_thread_data_start(ParserThreadData *self, AmalThreadCallbackFunc call
 }
 
 int parser_thread_data_join(ParserThreadData *self, void **result) {
-    int retval;
     if(self->status == PARSER_THREAD_STATUS_NEW)
         return 0;
-    retval = amal_thread_join(&self->thread, result);
-    if(retval == 0 || retval == AMAL_THREAD_NOT_JOINABLE)
-        self->status = PARSER_THREAD_STATUS_IDLE;
-    return retval;
+    return amal_thread_join(&self->thread, result);
 }
 
 int parser_init(Parser *self, amal_compiler *compiler, ScopedAllocator *allocator) {
@@ -250,4 +246,4 @@ int parser_queue_file(Parser *self, BufferView path) {
     /* TODO: Parse special path (to include library path with dots) */
     return_if_error(amal_compiler_load_file(self->compiler, path));
     return PARSER_OK;
-}
\ No newline at end of file
+}
diff --git a/src/std/buffer.c b/src/std/buffer.c
index f32c515..c4c9845 100644
--- a/src/std/buffer.c
+++ b/src/std/buffer.c
@@ -59,4 +59,4 @@ int buffer_pop(Buffer *self, void *data, usize size) {
     am_memcpy(data, &self->data[self->size - size], size);
     self->size -= size;
     return 0;
-}
\ No newline at end of file
+}
diff --git a/src/std/buffer_view.c b/src/std/buffer_view.c
index 977626c..8ddfab9 100644
--- a/src/std/buffer_view.c
+++ b/src/std/buffer_view.c
@@ -12,4 +12,4 @@ BufferView create_buffer_view(const char *data, usize size) {
     buffer_view.data = data;
     buffer_view.size = size;
     return buffer_view;
-}
\ No newline at end of file
+}
diff --git a/src/std/file.c b/src/std/file.c
index 3cd0798..46099b4 100644
--- a/src/std/file.c
+++ b/src/std/file.c
@@ -201,4 +201,4 @@ int read_whole_file(const char *filepath, char **data, usize *size) {
     cleanup:
     fclose(file);
     return result;
-}
\ No newline at end of file
+}
diff --git a/src/std/log.c b/src/std/log.c
index 1fd0e4e..2563bdc 100644
--- a/src/std/log.c
+++ b/src/std/log.c
@@ -73,4 +73,4 @@ void amal_log_perror(const char *prefix) {
     ignore_result_int(amal_mutex_lock(&mutex, NULL));
     perror(prefix);
     ignore_result_int(amal_mutex_unlock(&mutex));
-}
\ No newline at end of file
+}
diff --git a/src/std/mem.c b/src/std/mem.c
index 5bdb73b..ec7520c 100644
--- a/src/std/mem.c
+++ b/src/std/mem.c
@@ -11,4 +11,4 @@ bool am_memeql(const void *lhs, const void *rhs, usize size) {
 
 void am_memset(void *dest, int value, usize size) {
     memset(dest, value, size);
-}
\ No newline at end of file
+}
diff --git a/src/std/scoped_allocator.c b/src/std/scoped_allocator.c
index deb9e1e..dfed0b7 100644
--- a/src/std/scoped_allocator.c
+++ b/src/std/scoped_allocator.c
@@ -100,4 +100,4 @@ int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) {
 
 int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer) {
     return buffer_append(&self->buffers, buffer, sizeof(Buffer));
-}
\ No newline at end of file
+}
diff --git a/src/std/thread.c b/src/std/thread.c
index 4f27c1d..c8dba9a 100644
--- a/src/std/thread.c
+++ b/src/std/thread.c
@@ -141,4 +141,4 @@ bool amal_thread_is_main() {
 
 int amal_get_usable_thread_count() {
     return get_nprocs();
-}
\ No newline at end of file
+}
diff --git a/src/tokenizer.c b/src/tokenizer.c
index e85c952..742f9ca 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -256,4 +256,4 @@ void tokenizer_print_error(Tokenizer *self, const char *fmt, ...) {
     fprintf(stderr, "\x1b[1;32m^\x1b[0m\n");
     va_end(args);
     ignore_result_int(amal_mutex_unlock(mutex));
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3-70-g09d2