Update thread_unix logic

This commit is contained in:
gingerBill
2020-06-27 11:36:48 +01:00
parent f92b4c7849
commit 858c5f8fd8
2 changed files with 15 additions and 7 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ foreign pthread {
pthread_create :: proc(t: ^pthread_t, attrs: ^pthread_attr_t, routine: proc(data: rawptr) -> rawptr, arg: rawptr) -> c.int ---; pthread_create :: proc(t: ^pthread_t, attrs: ^pthread_attr_t, routine: proc(data: rawptr) -> rawptr, arg: rawptr) -> c.int ---;
// retval is a pointer to a location to put the return value of the thread proc. // retval is a pointer to a location to put the return value of the thread proc.
pthread_join :: proc(t: pthread_t, retval: rawptr) -> c.int ---; pthread_join :: proc(t: pthread_t, retval: ^rawptr) -> c.int ---;
pthread_self :: proc() -> pthread_t ---; pthread_self :: proc() -> pthread_t ---;
+14 -6
View File
@@ -120,7 +120,9 @@ is_done :: proc(t: ^Thread) -> bool {
} }
join :: proc(t: ^Thread) { join :: proc(t: ^Thread) {
if unix.pthread_equal(unix.pthread_self(), t.unix_thread) do return; if unix.pthread_equal(unix.pthread_self(), t.unix_thread) {
return;
}
// if unix.pthread_self().x == t.unix_thread.x do return; // if unix.pthread_self().x == t.unix_thread.x do return;
// NOTE(tetra): It's apparently UB for multiple threads to join the same thread // NOTE(tetra): It's apparently UB for multiple threads to join the same thread
@@ -131,7 +133,9 @@ join :: proc(t: ^Thread) {
// sure it makes sense to need to join from multiple threads? // sure it makes sense to need to join from multiple threads?
if sync.atomic_swap(&t.already_joined, true, .Sequentially_Consistent) { if sync.atomic_swap(&t.already_joined, true, .Sequentially_Consistent) {
for { for {
if sync.atomic_load(&t.done, .Sequentially_Consistent) do return; if sync.atomic_load(&t.done, .Sequentially_Consistent) {
return;
}
intrinsics.cpu_relax(); intrinsics.cpu_relax();
} }
} }
@@ -141,11 +145,15 @@ join :: proc(t: ^Thread) {
// We do this instead because I don't know if there is a danger // We do this instead because I don't know if there is a danger
// that you may join a different thread from the one you called join on, // that you may join a different thread from the one you called join on,
// if the thread handle is reused. // if the thread handle is reused.
if sync.atomic_load(&t.done, .Sequentially_Consistent) do return; if sync.atomic_load(&t.done, .Sequentially_Consistent) {
return;
}
ret := unix.pthread_join(t.unix_thread, nil); ret_val: rawptr;
assert(ret == 0, "cannot join thread"); _ = unix.pthread_join(t.unix_thread, &ret_val);
assert(sync.atomic_load(&t.done, .Sequentially_Consistent), "thread not done after join"); if !sync.atomic_load(&t.done, .Sequentially_Consistent) {
panic("thread not done after join");
}
} }
destroy :: proc(t: ^Thread) { destroy :: proc(t: ^Thread) {