test: pre-fill libstdc++ ctype caches before threads exist

- std::ctype<char> caches narrow()/widen() results per character in
  plain char arrays of the global classic-locale facet, written without
  synchronization from header-inlined code (locale_facets.h); two
  threads exercising an uncached character concurrently (e.g. compiling
  a std::regex in Channel::Validate) constitute a true data race that
  ThreadSanitizer rightfully reports
- the stores are real and unsynchronized, so a tsan-instrumented
  libstdc++ cannot help here; instead fill the caches before any thread
  is spawned, which turns every later access into a pure read
- warm the lazily-installed num_put/num_get caches used by stream
  insertion/extraction as well, via a small format/parse round-trip
- wire the warm-up into the gtest runner main() and, via a static
  initializer, into the test device runner
This commit is contained in:
Dennis Klein
2026-06-10 16:14:15 +02:00
committed by Dennis Klein
parent fc69b5e7ae
commit 2bd9a072a9
4 changed files with 71 additions and 0 deletions

View File

@@ -6,6 +6,7 @@
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "LocaleWarmup.h"
#include "devices/TestPairLeft.h"
#include "devices/TestPairRight.h"
#include "devices/TestPollIn.h"
@@ -30,6 +31,10 @@
namespace bpo = boost::program_options;
namespace {
[[maybe_unused]] fair::mq::test::LocaleWarmup const gLocaleWarmup{};
}
auto addCustomOptions(bpo::options_description& options) -> void
{
options.add_options()