This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/71660] [5/6/7/8 regression] alignment of std::atomic<8 byte primitive type> (long long, double) is wrong on x86
- From: "peter at cordes dot ca" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 05 Sep 2017 13:29:41 +0000
- Subject: [Bug libstdc++/71660] [5/6/7/8 regression] alignment of std::atomic<8 byte primitive type> (long long, double) is wrong on x86
- Auto-submitted: auto-generated
- References: <bug-71660-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71660
--- Comment #7 from Peter Cordes <peter at cordes dot ca> ---
C++11 std::atomic<> is correct, and the change was necessary.
8B alignment is required for 8B objects to be efficiently lock-free (using SSE
load / store for .load() and .store(), see
https://stackoverflow.com/questions/36624881/why-is-integer-assignment-on-a-naturally-aligned-variable-atomic),
and to avoid a factor of ~100 slowdown if lock cmpxchg8b is split across a
cache-line boundary.
What needs to change is the C11 stdatomic default alignment for 64-bit objects
in and out of structs. (This includes _Atomic struct {int a,b;};)
Currently, atomic_llong **is not atomic** in gcc, only in g++. I attached a
testcase showing tearing to the still-unfixed C11 bug
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65146#c4). (It was filed at the
same time as the C++11 bug that led to the change in std::atomic.)
re: long double: it can't be lock-free in -m32. 10-byte x87 load / store
instructions are not guaranteed to be atomic, and in fact even on real Intel
CPUs are done as two separate load or store uops.
alignof(long double) in 32-bit is different from alignof(long double) in
64-bit. std::atomic<long double> or _Atomic long double should always have the
same alignment as long double.