Skip to content

Commit

Permalink
8230392: Define AArch64 as MULTI_COPY_ATOMIC
Browse files Browse the repository at this point in the history
Reviewed-by: adinn, dholmes
  • Loading branch information
Andrew Haley committed Jan 23, 2020
1 parent 3eb71de commit 0dd3aaf
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
9 changes: 4 additions & 5 deletions src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;

#define SUPPORTS_NATIVE_CX8

// Aarch64 was not originally defined as multi-copy-atomic, but now is.
// See: "Simplifying ARM Concurrency: Multicopy-atomic Axiomatic and
// Operational Models for ARMv8"
// So we could #define CPU_MULTI_COPY_ATOMIC but historically we have
// not done so.
// Aarch64 was not originally defined to be multi-copy-atomic, but now
// is. See: "Simplifying ARM Concurrency: Multicopy-atomic Axiomatic
// and Operational Models for ARMv8"
#define CPU_MULTI_COPY_ATOMIC

// According to the ARMv8 ARM, "Concurrent modification and execution
// of instructions can lead to the resulting instruction performing
Expand Down
20 changes: 17 additions & 3 deletions src/hotspot/share/gc/shared/taskqueue.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,25 @@ bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t)
template<class E, MEMFLAGS F, unsigned int N>
bool GenericTaskQueue<E, F, N>::pop_global(volatile E& t) {
Age oldAge = _age.get();
// Architectures with weak memory model require a barrier here
// to guarantee that bottom is not older than age,
// which is crucial for the correctness of the algorithm.
#ifndef CPU_MULTI_COPY_ATOMIC
// Architectures with non-multi-copy-atomic memory model require a
// full fence here to guarantee that bottom is not older than age,
// which is crucial for the correctness of the algorithm.
//
// We need a full fence here for this case:
//
// Thread1: set bottom (push)
// Thread2: read age, read bottom, set age (pop_global)
// Thread3: read age, read bottom (pop_global)
//
// The requirement is that Thread3 must never read an older bottom
// value than Thread2 after Thread3 has seen the age value from
// Thread2.
OrderAccess::fence();
#else
// Everyone else can make do with a LoadLoad barrier to keep reads
// from _age and _bottom in order.
OrderAccess::loadload();
#endif
uint localBot = Atomic::load_acquire(&_bottom);
uint n_elems = size(localBot, oldAge.top());
Expand Down

0 comments on commit 0dd3aaf

Please sign in to comment.