diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2022-05-11 13:43:29 +0200 |
|---|---|---|
| committer | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2022-05-11 13:43:29 +0200 |
| commit | 56e3b7cb7d96a467ace98ebdca11d2baeef0a8c0 (patch) | |
| tree | 8740d8b97585389eaaf55def0a442fe75bd46584 /core/thread | |
| parent | ae1f5d21816928c976b44fd562fa4745b1ee2223 (diff) | |
Fix join on *nix.
Diffstat (limited to 'core/thread')
| -rw-r--r-- | core/thread/thread_unix.odin | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 8452df112..3897f6100 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -7,6 +7,8 @@ import "core:intrinsics" import "core:sync" import "core:sys/unix" +CAS :: intrinsics.atomic_compare_exchange_strong + Thread_State :: enum u8 { Started, Joined, @@ -98,7 +100,7 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ } _start :: proc(t: ^Thread) { - sync.guard(&t.mutex) + // sync.guard(&t.mutex) t.flags += { .Started } sync.signal(&t.cond) } @@ -108,15 +110,22 @@ _is_done :: proc(t: ^Thread) -> bool { } _join :: proc(t: ^Thread) { - sync.guard(&t.mutex) + // sync.guard(&t.mutex) - if .Joined in t.flags || unix.pthread_equal(unix.pthread_self(), t.unix_thread) { + if unix.pthread_equal(unix.pthread_self(), t.unix_thread) { return } - unix.pthread_join(t.unix_thread, nil) + // Preserve other flags besides `.Joined`, like `.Started`. + unjoined := intrinsics.atomic_load(&t.flags) - {.Joined} + joined := unjoined + {.Joined} - t.flags += { .Joined } + // Try to set `t.flags` from unjoined to joined. If it returns joined, + // it means the previous value had that flag set and we can return. + if res, ok := CAS(&t.flags, unjoined, joined); res == joined && !ok { + return + } + unix.pthread_join(t.unix_thread, nil) } _join_multiple :: proc(threads: ..^Thread) { |