Skip to content

Commit 36f8637

Browse files
shipilevpull[bot]
authored andcommitted
8316961: Fallback implementations for 64-bit Atomic::{add,xchg} on 32-bit platforms
Reviewed-by: eosterlund, dholmes, kbarrett, simonis
1 parent d623507 commit 36f8637

File tree

5 files changed

+100
-11
lines changed

5 files changed

+100
-11
lines changed

src/hotspot/os_cpu/bsd_x86/atomic_bsd_x86.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T volatile* dest,
153153
return cmpxchg_using_helper<int64_t>(_Atomic_cmpxchg_long, dest, compare_value, exchange_value);
154154
}
155155

156+
// No direct support for 8-byte xchg; emulate using cmpxchg.
157+
template<>
158+
struct Atomic::PlatformXchg<8> : Atomic::XchgUsingCmpxchg<8> {};
159+
160+
// No direct support for 8-byte add; emulate using cmpxchg.
161+
template<>
162+
struct Atomic::PlatformAdd<8> : Atomic::AddUsingCmpxchg<8> {};
163+
156164
template<>
157165
template<typename T>
158166
inline T Atomic::PlatformLoad<8>::operator()(T const volatile* src) const {

src/hotspot/os_cpu/linux_arm/atomic_linux_arm.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ inline T Atomic::PlatformXchg<4>::operator()(T volatile* dest,
128128
return xchg_using_helper<int32_t>(ARMAtomicFuncs::_xchg_func, dest, exchange_value);
129129
}
130130

131+
// No direct support for 8-byte xchg; emulate using cmpxchg.
132+
template<>
133+
struct Atomic::PlatformXchg<8> : Atomic::XchgUsingCmpxchg<8> {};
134+
135+
// No direct support for 8-byte add; emulate using cmpxchg.
136+
template<>
137+
struct Atomic::PlatformAdd<8> : Atomic::AddUsingCmpxchg<8> {};
131138

132139
// The memory_order parameter is ignored - we always provide the strongest/most-conservative ordering
133140

src/hotspot/os_cpu/linux_x86/atomic_linux_x86.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T volatile* dest,
153153
return cmpxchg_using_helper<int64_t>(_Atomic_cmpxchg_long, dest, compare_value, exchange_value);
154154
}
155155

156+
// No direct support for 8-byte xchg; emulate using cmpxchg.
157+
template<>
158+
struct Atomic::PlatformXchg<8> : Atomic::XchgUsingCmpxchg<8> {};
159+
160+
// No direct support for 8-byte add; emulate using cmpxchg.
161+
template<>
162+
struct Atomic::PlatformAdd<8> : Atomic::AddUsingCmpxchg<8> {};
163+
156164
template<>
157165
template<typename T>
158166
inline T Atomic::PlatformLoad<8>::operator()(T const volatile* src) const {

src/hotspot/share/runtime/atomic.hpp

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,15 @@ class Atomic : AllStatic {
398398
T compare_value,
399399
T exchange_value);
400400

401-
// Support platforms that do not provide Read-Modify-Write
402-
// byte-level atomic access. To use, derive PlatformCmpxchg<1> from
403-
// this class.
401+
// Support platforms that do not provide Read-Modify-Write atomic
402+
// accesses for 1-byte and 8-byte widths. To use, derive PlatformCmpxchg<1>,
403+
// PlatformAdd<S>, PlatformXchg<S> from these classes.
404404
public: // Temporary, can't be private: C++03 11.4/2. Fixed by C++11.
405405
struct CmpxchgByteUsingInt;
406+
template<size_t byte_size>
407+
struct XchgUsingCmpxchg;
408+
template<size_t byte_size>
409+
class AddUsingCmpxchg;
406410
private:
407411

408412
// Dispatch handler for xchg. Provides type-based validity
@@ -677,6 +681,47 @@ struct Atomic::CmpxchgByteUsingInt {
677681
atomic_memory_order order) const;
678682
};
679683

684+
// Define the class before including platform file, which may use this
685+
// as a base class, requiring it be complete. The definition is later
686+
// in this file, near the other definitions related to xchg.
687+
template<size_t byte_size>
688+
struct Atomic::XchgUsingCmpxchg {
689+
template<typename T>
690+
T operator()(T volatile* dest,
691+
T exchange_value,
692+
atomic_memory_order order) const;
693+
};
694+
695+
// Define the class before including platform file, which may use this
696+
// as a base class, requiring it be complete.
697+
template<size_t byte_size>
698+
class Atomic::AddUsingCmpxchg {
699+
public:
700+
template<typename D, typename I>
701+
static inline D add_then_fetch(D volatile* dest,
702+
I add_value,
703+
atomic_memory_order order) {
704+
D addend = add_value;
705+
return fetch_then_add(dest, add_value, order) + add_value;
706+
}
707+
708+
template<typename D, typename I>
709+
static inline D fetch_then_add(D volatile* dest,
710+
I add_value,
711+
atomic_memory_order order) {
712+
STATIC_ASSERT(byte_size == sizeof(I));
713+
STATIC_ASSERT(byte_size == sizeof(D));
714+
715+
D old_value;
716+
D new_value;
717+
do {
718+
old_value = Atomic::load(dest);
719+
new_value = old_value + add_value;
720+
} while (old_value != Atomic::cmpxchg(dest, old_value, new_value, order));
721+
return old_value;
722+
}
723+
};
724+
680725
// Define the class before including platform file, which may specialize
681726
// the operator definition. No generic definition of specializations
682727
// of the operator template are provided, nor are there any generic
@@ -1170,4 +1215,18 @@ inline D Atomic::xchg(volatile D* dest, T exchange_value, atomic_memory_order or
11701215
return XchgImpl<D, T>()(dest, exchange_value, order);
11711216
}
11721217

1218+
template<size_t byte_size>
1219+
template<typename T>
1220+
inline T Atomic::XchgUsingCmpxchg<byte_size>::operator()(T volatile* dest,
1221+
T exchange_value,
1222+
atomic_memory_order order) const {
1223+
STATIC_ASSERT(byte_size == sizeof(T));
1224+
1225+
T old_value;
1226+
do {
1227+
old_value = Atomic::load(dest);
1228+
} while (old_value != Atomic::cmpxchg(dest, old_value, exchange_value, order));
1229+
return old_value;
1230+
}
1231+
11731232
#endif // SHARE_RUNTIME_ATOMIC_HPP

test/hotspot/gtest/runtime/test_atomic.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ TEST_VM(AtomicAddTest, int32) {
5959
Support().test_fetch_add();
6060
}
6161

62-
// 64bit Atomic::add is only supported on 64bit platforms.
63-
#ifdef _LP64
6462
TEST_VM(AtomicAddTest, int64) {
63+
// Check if 64-bit atomics are available on the machine.
64+
if (!VM_Version::supports_cx8()) return;
65+
6566
using Support = AtomicAddTestSupport<int64_t>;
6667
Support().test_add();
6768
Support().test_fetch_add();
6869
}
69-
#endif // _LP64
7070

7171
TEST_VM(AtomicAddTest, ptr) {
7272
uint _test_values[10] = {};
@@ -108,13 +108,13 @@ TEST_VM(AtomicXchgTest, int32) {
108108
Support().test();
109109
}
110110

111-
// 64bit Atomic::xchg is only supported on 64bit platforms.
112-
#ifdef _LP64
113111
TEST_VM(AtomicXchgTest, int64) {
112+
// Check if 64-bit atomics are available on the machine.
113+
if (!VM_Version::supports_cx8()) return;
114+
114115
using Support = AtomicXchgTestSupport<int64_t>;
115116
Support().test();
116117
}
117-
#endif // _LP64
118118

119119
template<typename T>
120120
struct AtomicCmpxchgTestSupport {
@@ -142,6 +142,9 @@ TEST_VM(AtomicCmpxchgTest, int32) {
142142
}
143143

144144
TEST_VM(AtomicCmpxchgTest, int64) {
145+
// Check if 64-bit atomics are available on the machine.
146+
if (!VM_Version::supports_cx8()) return;
147+
145148
using Support = AtomicCmpxchgTestSupport<int64_t>;
146149
Support().test();
147150
}
@@ -345,12 +348,16 @@ TEST_VM(AtomicBitopsTest, uint32) {
345348
AtomicBitopsTestSupport<uint32_t>()();
346349
}
347350

348-
#ifdef _LP64
349351
TEST_VM(AtomicBitopsTest, int64) {
352+
// Check if 64-bit atomics are available on the machine.
353+
if (!VM_Version::supports_cx8()) return;
354+
350355
AtomicBitopsTestSupport<int64_t>()();
351356
}
352357

353358
TEST_VM(AtomicBitopsTest, uint64) {
359+
// Check if 64-bit atomics are available on the machine.
360+
if (!VM_Version::supports_cx8()) return;
361+
354362
AtomicBitopsTestSupport<uint64_t>()();
355363
}
356-
#endif // _LP64

0 commit comments

Comments
 (0)