aboutsummaryrefslogtreecommitdiff
path: root/src/thread_pool.cpp
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2026-02-02 11:37:19 +0000
committerGitHub <noreply@github.com>2026-02-02 11:37:19 +0000
commitadf56ced22de0ef84100c70b394641c272231c3f (patch)
treeee049d3ffa61d7ce1de1b774b4844a0ea7bfcc00 /src/thread_pool.cpp
parentb9e4007cb190c1a5d96e7786e726dcbcac1d08c9 (diff)
parentb183b1219c3b336988e53235a0671958b5079c09 (diff)
Merge pull request #6215 from odin-lang/bill/fix-data-races-2026-02
Fix numerous data races
Diffstat (limited to 'src/thread_pool.cpp')
-rw-r--r--src/thread_pool.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp
index ca6483fd9..a0afbd269 100644
--- a/src/thread_pool.cpp
+++ b/src/thread_pool.cpp
@@ -1,5 +1,15 @@
// thread_pool.cpp
+// TODO(bill): make work on MSVC
+// #if defined(__SANITIZE_THREAD__) || (defined(__has_feature) && __has_feature(thread_sanitizer))
+// #include <sanitizer/tsan_interface.h>
+// #define TSAN_RELEASE(addr) __tsan_release(addr)
+// #define TSAN_ACQUIRE(addr) __tsan_acquire(addr)
+// #else
+#define TSAN_RELEASE(addr)
+#define TSAN_ACQUIRE(addr)
+// #endif
+
struct WorkerTask;
struct ThreadPool;
@@ -88,6 +98,7 @@ void thread_pool_queue_push(Thread *thread, WorkerTask task) {
}
cur_ring->buffer[bot % cur_ring->size] = task;
+ TSAN_RELEASE(cur_ring->buffer[bot % cur_ring->size]);
std::atomic_thread_fence(std::memory_order_release);
thread->queue.bottom.store(bot + 1, std::memory_order_relaxed);
@@ -108,6 +119,7 @@ GrabState thread_pool_queue_take(Thread *thread, WorkerTask *task) {
if (top <= bot) {
// Queue is not empty
+ TSAN_ACQUIRE(cur_ring->buffer[bot % cur_ring->size]);
*task = cur_ring->buffer[bot % cur_ring->size];
if (top == bot) {
// Only one entry left in queue
@@ -139,6 +151,8 @@ GrabState thread_pool_queue_steal(Thread *thread, WorkerTask *task) {
if (top < bot) {
// Queue is not empty
TaskRingBuffer *cur_ring = thread->queue.ring.load(std::memory_order_consume);
+
+ TSAN_ACQUIRE(&cur_ring->buffer[top % cur_ring->size]);
*task = cur_ring->buffer[top % cur_ring->size];
if (!thread->queue.top.compare_exchange_strong(top, top + 1, std::memory_order_seq_cst, std::memory_order_relaxed)) {