Browse Source

fix tsan warnings in library/cpp/threading unit tests

- blocking_counter: fix destroy order;

- thread_local: Head_.load must use std::memory_order_acquire to match memory_order_release in compare_exchange and ensure all writes are visible; also fix always null node value in first compare_exchange call;

-  work_stealing: use atomics.
commit_hash:53f01a16bb40dd3eb890b0eb60388ecb0ce9c908
kulikov 6 months ago
parent
commit
20a8c1bdb3
1 changed files with 5 additions and 5 deletions
  1. 5 5
      library/cpp/threading/thread_local/thread_local.h

+ 5 - 5
library/cpp/threading/thread_local/thread_local.h

@@ -222,16 +222,16 @@ public:
 
     template <typename ...ConsturctArgs>
     T* Get(TThread::TId tid, ConsturctArgs&& ...args) {
-        TNode* node = Head_.load(std::memory_order_relaxed);
-        for (; node; node = node->Next) {
+        TNode* head = Head_.load(std::memory_order_acquire);
+        for (TNode* node = head; node; node = node->Next) {
             if (node->Key == tid) {
                 return &node->Value;
             }
         }
 
-        TNode* newNode = AllocateNode(tid, node, std::forward<ConsturctArgs>(args)...);
-        while (!Head_.compare_exchange_weak(node, newNode, std::memory_order_release, std::memory_order_relaxed)) {
-            newNode->Next = node;
+        TNode* newNode = AllocateNode(tid, head, std::forward<ConsturctArgs>(args)...);
+        while (!Head_.compare_exchange_weak(head, newNode, std::memory_order_release, std::memory_order_relaxed)) {
+            newNode->Next = head;
         }
 
         return &newNode->Value;