Skip to content

Commit

Permalink
threadpool: make ggml_barrier play nice with the thread sanitizer
Browse files Browse the repository at this point in the history
  • Loading branch information
max-krasnyansky committed Sep 13, 2024
1 parent 03e97e1 commit 2d9bb63
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions ggml/src/ggml.c
Original file line number Diff line number Diff line change
Expand Up @@ -3198,16 +3198,27 @@ static void ggml_barrier(struct ggml_threadpool * threadpool) {

int passed_old = atomic_load_explicit(n_barrier_passed, memory_order_relaxed);

if (atomic_fetch_add(n_barrier, 1) == n_threads - 1) {
// All threads go through the full fence (memory barrier) operation once to ensure
// that all previos updates have completed.
// The rest of the reads and writes can be relaxed, but the thread sanitizer wants
// to see an explicit acquire / release sequence to declare all futher accesses
// as safe.

#if defined(__has_feature) && __has_feature(thread_sanitizer)
#define passed_acquire memory_order_acquire
#define passed_release memory_order_release
#else
#define passed_acquire memory_order_relaxed
#define passed_release memory_order_relaxed
#endif

if (atomic_fetch_add_explicit(n_barrier, 1, memory_order_seq_cst) == n_threads - 1) {
// last thread
atomic_store(n_barrier, 0);
atomic_fetch_add_explicit(n_barrier_passed, 1, memory_order_relaxed);
atomic_store_explicit(n_barrier, 0, memory_order_relaxed);
atomic_fetch_add_explicit(n_barrier_passed, 1, passed_release);
} else {
// wait for other threads
while (true) {
if (atomic_load_explicit(n_barrier_passed, memory_order_relaxed) != passed_old) {
return;
}
while (atomic_load_explicit(n_barrier_passed, passed_acquire) == passed_old) {
ggml_thread_cpu_relax();
}
}
Expand Down

0 comments on commit 2d9bb63

Please sign in to comment.