[libcxx-commits] [PATCH] D117372: [libcxx] switch locale from using std::call_once to __libcpp_mutex_t

Daniel McIntosh via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 14 17:01:09 PST 2022


DanielMcIntosh-IBM created this revision.
DanielMcIntosh-IBM added reviewers: ldionne, Mordante, Quuxplusone.
DanielMcIntosh-IBM requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

This is the 2nd of 5 changes to add support for POSIX(OFF) on z/OS.
See D117366 <https://reviews.llvm.org/D117366> for more background, and D110349 <https://reviews.llvm.org/D110349> for discussion of an
alternative implementation.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D117372

Files:
  libcxx/include/__locale
  libcxx/src/locale.cpp


Index: libcxx/src/locale.cpp
===================================================================
--- libcxx/src/locale.cpp
+++ libcxx/src/locale.cpp
@@ -12,6 +12,7 @@
 #define _LCONV_C99
 #endif
 
+#include "__threading_support"
 #include "algorithm"
 #include "clocale"
 #include "codecvt"
@@ -707,36 +708,29 @@
 
 int32_t locale::id::__next_id = 0;
 
-namespace
-{
+#ifndef _LIBCPP_HAS_NO_THREADS
+_LIBCPP_SAFE_STATIC static __libcpp_mutex_t __id_mut = _LIBCPP_MUTEX_INITIALIZER;
+#endif
 
-class __fake_bind
-{
-    locale::id* id_;
-    void (locale::id::* pmf_)();
-public:
-    __fake_bind(void (locale::id::* pmf)(), locale::id* id)
-        : id_(id), pmf_(pmf) {}
+long locale::id::__get() {
+  // Before we do anything as expensive as acquire a mutex, check if __id_ has already been set
+  auto id_copy = __libcpp_atomic_load(&__id_, _AO_Relaxed);
+  if (id_copy != 0)
+    return id_copy - 1;
 
-    void operator()() const
-    {
-        (id_->*pmf_)();
-    }
-};
-
-}
-
-long
-locale::id::__get()
-{
-    call_once(__flag_, __fake_bind(&locale::id::__init, this));
-    return __id_ - 1;
-}
+#ifndef _LIBCPP_HAS_NO_THREADS
+  __libcpp_mutex_lock(&__m_);
+#endif
+  id_copy = __id_;
+  if (id_copy == 0) {
+    id_copy = ++__next_id;
+    __libcpp_relaxed_store(&__id_, id_copy);
+  }
 
-void
-locale::id::__init()
-{
-    __id_ = __libcpp_atomic_add(&__next_id, 1);
+#ifndef _LIBCPP_HAS_NO_THREADS
+  __libcpp_mutex_unlock(&__m_);
+#endif
+  return id_copy - 1;
 }
 
 // template <> class collate_byname<char>
Index: libcxx/include/__locale
===================================================================
--- libcxx/include/__locale
+++ libcxx/include/__locale
@@ -203,7 +203,8 @@
 
 class _LIBCPP_TYPE_VIS locale::id
 {
-    once_flag      __flag_;
+    // Reserve space for a once_flag to preserve ABI compatibility
+    once_flag      __reserved;
     int32_t        __id_;
 
     static int32_t __next_id;
@@ -212,8 +213,6 @@
     void operator=(const id&) = delete;
     id(const id&) = delete;
 
-private:
-    void __init();
 public:  // only needed for tests
     long __get();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117372.400199.patch
Type: text/x-patch
Size: 2108 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220115/1200c610/attachment.bin>


More information about the libcxx-commits mailing list