Skip to content

Make the cached hardware support atomic in the C++ build too - #949

Closed
moshap-firebolt wants to merge 1 commit into
RoaringBitmap:masterfrom
firebolt-db:fix-hardware-support-race-upstream
Closed

moshap-firebolt wants to merge 1 commit into
RoaringBitmap:masterfrom
firebolt-db:fix-hardware-support-race-upstream

Conversation

@moshap-firebolt

Copy link
Copy Markdown
Contributor

croaring_hardware_support() caches the detected CPU features in a function-local static int, which every thread calling it for the first time reads and writes. It is declared _Atomic only when CROARING_ATOMIC_IMPL == CROARING_ATOMIC_IMPL_C, so a build that compiles the sources as C++ (where CROARING_ATOMIC_IMPL_CPP is selected) leaves a data race on a plain int. ThreadSanitizer reports it when several threads reach roaring code for the first time together; we hit it in a server running under TSan.

This adds a croaring_atomic_int typedef next to the other atomic selections: std::atomic<int> for the C++ implementation, _Atomic int for C as before, and a plain int where no atomics are available. All three copies of the cache (x64 AVX2, x64 generic, arm64) use it.

The read still compiles to a plain mov on x86-64 (and a load on arm64); only the one-time store becomes an xchg.

Testing: a small TSan program calling croaring_hardware_support() from 8 threads, with isadetection.c compiled as C++, reports the race on 5 of 5 runs before this change and on none after, with and without -mavx2. The file still compiles as C11, and for aarch64 as both C11 and C++17.

croaring_hardware_support() caches its result in a function-local static
that every thread calling it for the first time writes. It is _Atomic only
when compiled as C, so building the sources as C++ leaves a data race on a
plain int, which ThreadSanitizer reports. Use std::atomic<int> there, as
the refcounts already do. The read still compiles to a plain load.
@lemire

lemire commented Nov 3, 2026

Copy link
Copy Markdown
Member

Will go with #950 thanks, and we credit you.

@lemire lemire closed this Nov 3, 2026
lemire added a commit that referenced this pull request Nov 3, 2026
* Make the cached hardware support atomic in the C++ build too

croaring_hardware_support() caches the detected CPU features in a
function-local static int that was _Atomic only for the C11 atomic
implementation, leaving a data race when the sources are compiled as
C++. Use std::atomic<int> in C++, initialized with braces so that it
compiles before C++17 (std::atomic has no copy constructor).

Based on #949.

Co-authored-by: moshap <moshap@firebolt.io>

* Apply clang-format

---------

Co-authored-by: moshap <moshap@firebolt.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants