package sync /* A barrier enabling multiple threads to synchronize the beginning of some computation Example: package example import "core:fmt" import "core:sync" import "core:thread" barrier := &sync.Barrier{}; main :: proc() { fmt.println("Start"); THREAD_COUNT :: 4; threads: [THREAD_COUNT]^thread.Thread; sync.barrier_init(barrier, THREAD_COUNT); defer sync.barrier_destroy(barrier); for _, i in threads { threads[i] = thread.create_and_start(proc(t: ^thread.Thread) { // Same messages will be printed together but without any interleaving fmt.println("Getting ready!"); sync.barrier_wait(barrier); fmt.println("Off their marks they go!"); }); } for t in threads { thread.destroy(t); // join and free thread } fmt.println("Finished"); } */ Barrier :: struct { mutex: Blocking_Mutex, cond: Condition, index: int, generation_id: int, thread_count: int, } barrier_init :: proc(b: ^Barrier, thread_count: int) { blocking_mutex_init(&b.mutex) condition_init(&b.cond, &b.mutex) b.index = 0 b.generation_id = 0 b.thread_count = thread_count } barrier_destroy :: proc(b: ^Barrier) { blocking_mutex_destroy(&b.mutex) condition_destroy(&b.cond) } // Block the current thread until all threads have rendezvoused // Barrier can be reused after all threads rendezvoused once, and can be used continuously barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) { blocking_mutex_lock(&b.mutex) defer blocking_mutex_unlock(&b.mutex) local_gen := b.generation_id b.index += 1 if b.index < b.thread_count { for local_gen == b.generation_id && b.index < b.thread_count { condition_wait_for(&b.cond) } return false } b.index = 0 b.generation_id += 1 condition_broadcast(&b.cond) return true }