[libcxx-commits] [libcxx] [libc++] Speed up classic locale (PR #72112)
Dmitry Vyukov via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Nov 16 07:33:36 PST 2023
================
@@ -538,16 +543,31 @@ locale::__imp::use_facet(long id) const
// locale
+std::atomic<locale::__imp*> locale::__imp::classic_;
+
const locale&
locale::__imp::make_classic()
{
// only one thread can get in here and it only gets in once
alignas(locale) static std::byte buf[sizeof(locale)];
locale* c = reinterpret_cast<locale*>(&buf);
c->__locale_ = &make<__imp>(1u);
+ classic_.store(c->__locale_, std::memory_order_relaxed);
----------------
dvyukov wrote:
The visibility of classic_ is provided by the dynamic local static initialization of c in this case:
```
static const locale& c = __imp::make_classic();
```
Any thread that called classic() and passed though this statement must have visibility over c and and any side effects of make_classic(). The store to classic_ is a side effect of make_classic().
I can't find the wording in the standard that says that completion of the dynamic initialization happens-before any uses of the variable, but it's definitely the intention and the code would be broken today otherwise (along with tons of other C++ code out there).
Think of this local static initialization as call_one:
```
32.5.6.2
3 Synchronization: For any given once_flag: all active executions occur in a total order; completion
of an active execution synchronizes with (6.9.2) the start of the next one in this total order; and the
returning execution synchronizes with the return from all passive executions.
```
https://github.com/llvm/llvm-project/pull/72112
More information about the libcxx-commits
mailing list