[PATCH] D79588: [llvm][Support] Use std::atomic for llvm::call_once

Yannic Bonenberger via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 11:55:21 PDT 2020


yannic updated this revision to Diff 262710.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79588/new/

https://reviews.llvm.org/D79588

Files:
  llvm/include/llvm/Support/Threading.h


Index: llvm/include/llvm/Support/Threading.h
===================================================================
--- llvm/include/llvm/Support/Threading.h
+++ llvm/include/llvm/Support/Threading.h
@@ -44,7 +44,7 @@
 #if LLVM_THREADING_USE_STD_CALL_ONCE
 #include <mutex>
 #else
-#include "llvm/Support/Atomic.h"
+#include <atomic>
 #endif
 
 namespace llvm {
@@ -98,7 +98,7 @@
   /// This structure must be used as an opaque object. It is a struct to force
   /// autoinitialization and behave like std::once_flag.
   struct once_flag {
-    volatile sys::cas_flag status = Uninitialized;
+    std::atomic<InitStatus> status(Uninitialized);
   };
 
 #endif
@@ -121,24 +121,21 @@
     std::call_once(flag, std::forward<Function>(F),
                    std::forward<Args>(ArgList)...);
 #else
-    // For other platforms we use a generic (if brittle) version based on our
-    // atomics.
-    sys::cas_flag old_val = sys::CompareAndSwap(&flag.status, Wait, Uninitialized);
-    if (old_val == Uninitialized) {
+    switch (flag.status.compare_exchange_strong(Uninitialized, Wait)) {
+    case Uninitialized:
+      // This is the first time the function is invoked.
       std::forward<Function>(F)(std::forward<Args>(ArgList)...);
-      sys::MemoryFence();
-      TsanIgnoreWritesBegin();
-      TsanHappensBefore(&flag.status);
-      flag.status = Done;
-      TsanIgnoreWritesEnd();
-    } else {
-      // Wait until any thread doing the call has finished.
-      sys::cas_flag tmp = flag.status;
-      sys::MemoryFence();
-      while (tmp != Done) {
-        tmp = flag.status;
-        sys::MemoryFence();
+      flag.status.store(Done);
+      break;
+
+    case Wait:
+      while (flag.status.load() != Done) {
+        // Wait for function to finish.
       }
+      break;
+
+    case Done:
+      break;
     }
     TsanHappensAfter(&flag.status);
 #endif


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79588.262710.patch
Type: text/x-patch
Size: 1872 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200507/b8a2e518/attachment.bin>


More information about the llvm-commits mailing list