From 8623aec882e4eadfb53232d63949abf05af8a921 Mon Sep 17 00:00:00 2001 From: Chris Seymour Date: Wed, 26 Apr 2023 23:05:01 +0100 Subject: [PATCH] TSan complains that this read of |ktf_worker_t::i| is unsynchronised wrt the stores on the other worker threads. Unlike the __atomic_* family of functions the __sync_* functions don't have a relaxed read without modification, so to emulate this behaviour I've used the existing __sync_fetch_and_add() with an increment of 0. --- kthread.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kthread.c b/kthread.c index ffdf9408..2273d7ba 100644 --- a/kthread.c +++ b/kthread.c @@ -29,10 +29,12 @@ typedef struct kt_for_t { static inline long steal_work(kt_for_t *t) { - int i, min_i = -1; + int i, w_i, min_i = -1; long k, min = LONG_MAX; - for (i = 0; i < t->n_threads; ++i) - if (min > t->w[i].i) min = t->w[i].i, min_i = i; + for (i = 0; i < t->n_threads; ++i) { + w_i = __sync_fetch_and_add(&t->w[i].i, 0); + if (min > w_i) min = w_i, min_i = i; + } k = __sync_fetch_and_add(&t->w[min_i].i, t->n_threads); return k >= t->n? -1 : k; }