[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