diff options
| author | Aargh Rai <aargh.rai+git@gmail.com> | 2026-08-15 14:28:35 +0530 |
|---|---|---|
| committer | Aargh Rai <aargh.rai+git@gmail.com> | 2026-08-15 14:28:35 +0530 |
| commit | f97ea63ac29c08530b1aaff89277262b44ef7a11 (patch) | |
| tree | 2534d597b2356de9dda0412665cf8ba06870526c /src/engine | |
| parent | 2bf47937bcc5cd29cf8081f922b7615b7e57ed57 (diff) | |
phase A
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/thread.c | 14 | ||||
| -rw-r--r-- | src/engine/threads.c | 94 |
2 files changed, 92 insertions, 16 deletions
diff --git a/src/engine/thread.c b/src/engine/thread.c index 25e583e..912b70f 100644 --- a/src/engine/thread.c +++ b/src/engine/thread.c @@ -1,6 +1,20 @@ +#define ENGINE_THREADS_INTERNAL #include "engine/threads.h" #include <stdio.h> +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 + ); + } +} + void *child_thread(void *_args) { struct child_thread_args *args = (struct child_thread_args*)_args; args->stop = 0; 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 |
