diff options
Diffstat (limited to 'src/engine/threads.c')
| -rw-r--r-- | src/engine/threads.c | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/src/engine/threads.c b/src/engine/threads.c index 541efb1..5bf630a 100644 --- a/src/engine/threads.c +++ b/src/engine/threads.c @@ -41,28 +41,18 @@ void threads_reserve(struct threads *handler, size_t capacity) { handler->capacity = capacity; } -void threads_go(struct threads *handler) { - int running_count = handler->running_count; - for (int i = 0; i < running_count; i++) { - __threads_args_init(handler->args + i, handler, i); - pthread_create( - handler->threads + i, - NULL, - i == 0 ? root_thread : child_thread, - handler->args + i - ); - } -} - bool threads_go_loop(struct threads *handler) { // idk maybe do something while waiting for calculations to flow in + return false; } bool threads_all_done(struct threads *handler) { int running_count = handler->running_count; assert(running_count > 0); for (int i = 0; i < running_count; i++) { - if (atomic_load(&handler->args[i].finished) == 1) continue; + // `finished` is part of the common initial sequence of both union + // members (stop, finished), so reading it via either member is well-defined. + if (atomic_load(&handler->args[i].root_thread_args.finished) == 1) continue; return false; } return true; @@ -83,21 +73,93 @@ void __threads_args_init( int i ) { if (i > 0) { - struct child_thread_args *args = _args; + struct child_thread_args *args = (struct child_thread_args*)_args; atomic_init(&args->stop, 0); atomic_init(&args->finished, 0); args->id = i; args->position = handler->position; args->go_args = handler->go_args; + args->ttable = &handler->ttable; + args->sp_stack = 0; args->message = handler->engine_messages->data[i]; return; } - struct root_thread_args *args = _args; + struct root_thread_args *args = (struct root_thread_args*)_args; atomic_init(&args->stop, 0); atomic_init(&args->finished, 0); args->id = i; args->position = handler->position; args->go_args = handler->go_args; args->message = handler->engine_messages->data[i]; + args->ttable = &handler->ttable; +} + +#ifdef TEST_MOD +bool test_threads_args_init_root_propagates() { + engine_message_handler_t dummy[2]; + engine_message_handler_t *dummy_ptrs[2] = { &dummy[0], &dummy[1] }; + engine_messages_t messages = { + .data = dummy_ptrs, + .count = 2, + .capacity = 2, + }; + + go_args_t go_args = {0}; + position_t pos = {0}; + + struct threads handler = {0}; + handler.engine_messages = &messages; + handler.go_args = &go_args; + handler.position = &pos; + ttable_init(&handler.ttable, 2); + + thread_args_t args; + __threads_args_init(&args, &handler, 0); + + bool ok = true; + ok &= args.root_thread_args.id == 0; + ok &= atomic_load(&args.root_thread_args.stop) == 0; + ok &= atomic_load(&args.root_thread_args.finished) == 0; + ok &= args.root_thread_args.ttable == &handler.ttable; + ok &= args.root_thread_args.go_args == &go_args; + ok &= args.root_thread_args.position == &pos; + ok &= args.root_thread_args.message == &dummy[0]; + + ttable_deinit(handler.ttable); + return ok; +} + +bool test_threads_args_init_child_propagates() { + engine_message_handler_t dummy[2]; + engine_message_handler_t *dummy_ptrs[2] = { &dummy[0], &dummy[1] }; + engine_messages_t messages = { + .data = dummy_ptrs, + .count = 2, + .capacity = 2, + }; + + go_args_t go_args = {0}; + position_t pos = {0}; + + struct threads handler = {0}; + handler.engine_messages = &messages; + handler.go_args = &go_args; + handler.position = &pos; + ttable_init(&handler.ttable, 2); + + thread_args_t args; + __threads_args_init(&args, &handler, 1); + + bool ok = true; + ok &= args.child_thread_args.id == 1; + ok &= args.child_thread_args.ttable == &handler.ttable; + ok &= args.child_thread_args.go_args == &go_args; + ok &= args.child_thread_args.position == &pos; + ok &= args.child_thread_args.message == &dummy[1]; + ok &= args.child_thread_args.sp_stack == 0; + + ttable_deinit(handler.ttable); + return ok; } +#endif |
