[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 10:47:12 PDT 2020


yannic created this revision.
Herald added subscribers: llvm-commits, jfb.
Herald added a project: LLVM.

Repository:
  rG LLVM Github Monorepo

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
@@ -41,8 +41,12 @@
 #define LLVM_THREADING_USE_STD_CALL_ONCE 0
 #endif
 
+#define LLVM_THREADING_USE_ATOMIC_CALL_ONCE 1
+
 #if LLVM_THREADING_USE_STD_CALL_ONCE
 #include <mutex>
+#elif LLVM_THREADING_USE_ATOMIC_CALL_ONCE
+#include <atomic>
 #else
 #include "llvm/Support/Atomic.h"
 #endif
@@ -98,7 +102,15 @@
   /// 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 {
+#if LLVM_THREADING_USE_ATOMIC_CALL_ONCE
+
+    std::atomic<InitStatus> status(Uninitialized);
+
+#else
+
     volatile sys::cas_flag status = Uninitialized;
+
+#endif
   };
 
 #endif
@@ -120,6 +132,24 @@
 #if LLVM_THREADING_USE_STD_CALL_ONCE
     std::call_once(flag, std::forward<Function>(F),
                    std::forward<Args>(ArgList)...);
+#elif LLVM_THREADING_USE_ATOMIC_CALL_ONCE
+    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)...);
+      flag.status.store(Done);
+      break;
+
+    case Wait:
+      while (flag.status.load() != Done) {
+        // Wait for function to finish.
+      }
+      break;
+
+    case Done:
+      break;
+    }
+    TsanHappensAfter(&flag.status);
 #else
     // For other platforms we use a generic (if brittle) version based on our
     // atomics.


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


More information about the llvm-commits mailing list