From a78974f9f3d7be15d5355983d941ea404213d867 Mon Sep 17 00:00:00 2001 From: Stephan Hageboeck Date: Tue, 13 Jan 2026 17:58:56 +0100 Subject: [PATCH] [hist] Disable thread-safe TH3D on 32-bit platforms. On 32 bits, the alignment of double is less strict than for atomic_ref, so TH3D::FillThreadSafe cannot be used. Fix #20834. --- hist/hist/inc/TH3.h | 7 ++++++- hist/hist/src/TH3.cxx | 2 +- hist/hist/test/test_TH3.cxx | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/hist/hist/inc/TH3.h b/hist/hist/inc/TH3.h index 5adfb157ae18f..cd67e02c2da2d 100644 --- a/hist/hist/inc/TH3.h +++ b/hist/hist/inc/TH3.h @@ -28,6 +28,11 @@ class TH2D; class TProfile2D; +#if defined R__B64 && defined __cpp_lib_atomic_ref +// ROOT-20834 Atomic_ref on 32 bit can fail because of alignment problems +#define TH3D_FILL_THREADSAFE +#endif + namespace ROOT::Internal { /// Entrypoint for thread-safe filling from RDataFrame. template @@ -455,7 +460,7 @@ class TH3D : public TH3, public TArrayD { Double_t RetrieveBinContent(Int_t bin) const override { return fArray[bin]; } void UpdateBinContent(Int_t bin, Double_t content) override { fArray[bin] = content; } private: -#ifdef __cpp_lib_atomic_ref +#ifdef TH3D_FILL_THREADSAFE void FillThreadSafe(Double_t x, Double_t y, Double_t z, Double_t w = 1.); template friend auto ROOT::Internal::FillThreadSafe(T &histo, Args... args) diff --git a/hist/hist/src/TH3.cxx b/hist/hist/src/TH3.cxx index 05577ee61f039..cb5fdc29d2062 100644 --- a/hist/hist/src/TH3.cxx +++ b/hist/hist/src/TH3.cxx @@ -438,7 +438,7 @@ Int_t TH3::Fill(Double_t x, Double_t y, Double_t z, Double_t w) return bin; } -#ifdef __cpp_lib_atomic_ref +#ifdef TH3D_FILL_THREADSAFE //////////////////////////////////////////////////////////////////////////////// /// Atomically increment cell defined by x,y,z by a weight w. /// diff --git a/hist/hist/test/test_TH3.cxx b/hist/hist/test/test_TH3.cxx index 71ef365280005..5cf080eb90317 100644 --- a/hist/hist/test/test_TH3.cxx +++ b/hist/hist/test/test_TH3.cxx @@ -14,7 +14,7 @@ TEST(TH3L, SetBinContent) EXPECT_EQ(h.GetBinContent(1, 1, 1), Large); } -#ifdef __cpp_lib_atomic_ref +#ifdef TH3D_FILL_THREADSAFE TEST(TH3D, FillThreadSafe) {