[libcxx-commits] [libcxx] [libc++] Avoid a guard variable for the random_shuffle engine (PR #234815)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Oct 22 19:05:59 PDT 2026


https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/234815

The default engine used by std::random_shuffle currently uses a function local static. However, it turns out the thread safe guard variable is unnecessary since we're already under a lock in this case.

It would be even better to constant initialize mt19937 instead, however that's a more difficult change since the standard doesn't define it as constexpr.

>From 025133e4ef5d9e1df4cab11f5a69bccc9ff53148 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 22 Oct 2026 14:47:10 -0400
Subject: [PATCH] [libc++] Avoid a guard variable for the random_shuffle engine

The default engine used by std::random_shuffle currently uses a function
local static. However, it turns out the thread safe guard variable is
unnecessary since we're already under a lock in this case.

It would be even better to constant initialize mt19937 instead, however
that's a more difficult change since the standard doesn't define it as
constexpr.
---
 libcxx/src/random_shuffle.cpp | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/libcxx/src/random_shuffle.cpp b/libcxx/src/random_shuffle.cpp
index aa0f78fafe06e0..6f5627ecf758a1 100644
--- a/libcxx/src/random_shuffle.cpp
+++ b/libcxx/src/random_shuffle.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <__utility/no_destroy.h>
 #include <algorithm>
 #include <random>
 
@@ -42,9 +43,18 @@ __rs_default::~__rs_default() {
 #endif
 }
 
+// The engine is only accessed through a __rs_default, whose construction acquires the mutex (held until
+// the last copy is destroyed), so accesses are already serialized. This allows initializing the engine
+// lazily without a function-local static, which requires a guard variable.
+static constinit __no_destroy<mt19937> __global_mersenne_twister(__uninitialized_tag{});
+static constinit bool __initialized = false;
+
 __rs_default::result_type __rs_default::operator()() {
-  static mt19937 __rs_g;
-  return __rs_g();
+  if (!__initialized) {
+    __global_mersenne_twister.__emplace();
+    __initialized = true;
+  }
+  return __global_mersenne_twister.__get()();
 }
 
 __rs_default __rs_get() { return __rs_default(); }



More information about the libcxx-commits mailing list