Skip to content

Commit

Permalink
8234562: Move OrderAccess::release_store*/load_acquire to Atomic
Browse files Browse the repository at this point in the history
Reviewed-by: rehn, dholmes
  • Loading branch information
stefank committed Nov 25, 2019
1 parent e06c17c commit e527ce4
Show file tree
Hide file tree
Showing 97 changed files with 554 additions and 570 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/cpu/ppc/nativeInst_ppc.cpp
Expand Up @@ -374,7 +374,7 @@ void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer)
// Finally patch out the jump.
volatile juint *jump_addr = (volatile juint*)instr_addr;
// Release not needed because caller uses invalidate_range after copying the remaining bytes.
//OrderAccess::release_store(jump_addr, *((juint*)code_buffer));
//Atomic::release_store(jump_addr, *((juint*)code_buffer));
*jump_addr = *((juint*)code_buffer); // atomically store code over branch instruction
ICache::ppc64_flush_icache_bytes(instr_addr, NativeGeneralJump::instruction_size);
}
Expand Down
5 changes: 2 additions & 3 deletions src/hotspot/os/bsd/os_bsd.cpp
Expand Up @@ -51,7 +51,6 @@
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/osThread.hpp"
#include "runtime/perfMemory.hpp"
#include "runtime/semaphore.hpp"
Expand Down Expand Up @@ -3209,7 +3208,7 @@ static volatile int* volatile apic_to_processor_mapping = NULL;
static volatile int next_processor_id = 0;

static inline volatile int* get_apic_to_processor_mapping() {
volatile int* mapping = OrderAccess::load_acquire(&apic_to_processor_mapping);
volatile int* mapping = Atomic::load_acquire(&apic_to_processor_mapping);
if (mapping == NULL) {
// Calculate possible number space for APIC ids. This space is not necessarily
// in the range [0, number_of_processors).
Expand Down Expand Up @@ -3240,7 +3239,7 @@ static inline volatile int* get_apic_to_processor_mapping() {

if (!Atomic::replace_if_null(mapping, &apic_to_processor_mapping)) {
FREE_C_HEAP_ARRAY(int, mapping);
mapping = OrderAccess::load_acquire(&apic_to_processor_mapping);
mapping = Atomic::load_acquire(&apic_to_processor_mapping);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/os/windows/os_windows.cpp
Expand Up @@ -3747,15 +3747,15 @@ int os::win32::exit_process_or_thread(Ept what, int exit_code) {
// The first thread that reached this point, initializes the critical section.
if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
} else if (OrderAccess::load_acquire(&process_exiting) == 0) {
} else if (Atomic::load_acquire(&process_exiting) == 0) {
if (what != EPT_THREAD) {
// Atomically set process_exiting before the critical section
// to increase the visibility between racing threads.
Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0);
}
EnterCriticalSection(&crit_sect);

if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
if (what == EPT_THREAD && Atomic::load_acquire(&process_exiting) == 0) {
// Remove from the array those handles of the threads that have completed exiting.
for (i = 0, j = 0; i < handle_count; ++i) {
res = WaitForSingleObject(handles[i], 0 /* don't wait */);
Expand Down Expand Up @@ -3868,7 +3868,7 @@ int os::win32::exit_process_or_thread(Ept what, int exit_code) {
}

if (!registered &&
OrderAccess::load_acquire(&process_exiting) != 0 &&
Atomic::load_acquire(&process_exiting) != 0 &&
process_exiting != GetCurrentThreadId()) {
// Some other thread is about to call exit(), so we don't let
// the current unregistered thread proceed to exit() or _endthreadex()
Expand Down
12 changes: 12 additions & 0 deletions src/hotspot/os_cpu/aix_ppc/atomic_aix_ppc.hpp
Expand Up @@ -30,6 +30,7 @@
#error "Atomic currently only implemented for PPC64"
#endif

#include "orderAccess_aix_ppc.hpp"
#include "utilities/debug.hpp"

// Implementation of class atomic
Expand Down Expand Up @@ -399,4 +400,15 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
return old_value;
}

template<size_t byte_size>
struct Atomic::PlatformOrderedLoad<byte_size, X_ACQUIRE> {
template <typename T>
T operator()(const volatile T* p) const {
T t = Atomic::load(p);
// Use twi-isync for load_acquire (faster than lwsync).
__asm__ __volatile__ ("twi 0,%0,0\n isync\n" : : "r" (t) : "memory");
return t;
}
};

#endif // OS_CPU_AIX_PPC_ATOMIC_AIX_PPC_HPP
9 changes: 0 additions & 9 deletions src/hotspot/os_cpu/aix_ppc/orderAccess_aix_ppc.hpp
Expand Up @@ -64,8 +64,6 @@
#define inlasm_lwsync() __asm__ __volatile__ ("lwsync" : : : "memory");
#define inlasm_eieio() __asm__ __volatile__ ("eieio" : : : "memory");
#define inlasm_isync() __asm__ __volatile__ ("isync" : : : "memory");
// Use twi-isync for load_acquire (faster than lwsync).
#define inlasm_acquire_reg(X) __asm__ __volatile__ ("twi 0,%0,0\n isync\n" : : "r" (X) : "memory");

inline void OrderAccess::loadload() { inlasm_lwsync(); }
inline void OrderAccess::storestore() { inlasm_lwsync(); }
Expand All @@ -78,13 +76,6 @@ inline void OrderAccess::fence() { inlasm_sync(); }
inline void OrderAccess::cross_modify_fence()
{ inlasm_isync(); }

template<size_t byte_size>
struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const { T t = Atomic::load(p); inlasm_acquire_reg(t); return t; }
};

#undef inlasm_sync
#undef inlasm_lwsync
#undef inlasm_eieio
Expand Down
50 changes: 50 additions & 0 deletions src/hotspot/os_cpu/bsd_x86/atomic_bsd_x86.hpp
Expand Up @@ -169,4 +169,54 @@ inline void Atomic::PlatformStore<8>::operator()(T store_value,

#endif // AMD64

template<>
struct Atomic::PlatformOrderedStore<1, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgb (%2),%0"
: "=q" (v)
: "0" (v), "r" (p)
: "memory");
}
};

template<>
struct Atomic::PlatformOrderedStore<2, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgw (%2),%0"
: "=r" (v)
: "0" (v), "r" (p)
: "memory");
}
};

template<>
struct Atomic::PlatformOrderedStore<4, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgl (%2),%0"
: "=r" (v)
: "0" (v), "r" (p)
: "memory");
}
};

#ifdef AMD64
template<>
struct Atomic::PlatformOrderedStore<8, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgq (%2), %0"
: "=r" (v)
: "0" (v), "r" (p)
: "memory");
}
};
#endif // AMD64

#endif // OS_CPU_BSD_X86_ATOMIC_BSD_X86_HPP
50 changes: 0 additions & 50 deletions src/hotspot/os_cpu/bsd_x86/orderAccess_bsd_x86.hpp
Expand Up @@ -64,54 +64,4 @@ inline void OrderAccess::cross_modify_fence() {
__asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory");
}

template<>
struct OrderAccess::PlatformOrderedStore<1, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgb (%2),%0"
: "=q" (v)
: "0" (v), "r" (p)
: "memory");
}
};

template<>
struct OrderAccess::PlatformOrderedStore<2, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgw (%2),%0"
: "=r" (v)
: "0" (v), "r" (p)
: "memory");
}
};

template<>
struct OrderAccess::PlatformOrderedStore<4, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgl (%2),%0"
: "=r" (v)
: "0" (v), "r" (p)
: "memory");
}
};

#ifdef AMD64
template<>
struct OrderAccess::PlatformOrderedStore<8, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const {
__asm__ volatile ( "xchgq (%2), %0"
: "=r" (v)
: "0" (v), "r" (p)
: "memory");
}
};
#endif // AMD64

#endif // OS_CPU_BSD_X86_ORDERACCESS_BSD_X86_HPP
25 changes: 21 additions & 4 deletions src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp
Expand Up @@ -32,10 +32,6 @@
// Note that memory_order_conservative requires a full barrier after atomic stores.
// See https://patchwork.kernel.org/patch/3575821/

#define FULL_MEM_BARRIER __sync_synchronize()
#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE);
#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE);

template<size_t byte_size>
struct Atomic::PlatformAdd
: Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
Expand Down Expand Up @@ -81,4 +77,25 @@ inline T Atomic::PlatformCmpxchg<byte_size>::operator()(T exchange_value,
}
}

template<size_t byte_size>
struct Atomic::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const { T data; __atomic_load(const_cast<T*>(p), &data, __ATOMIC_ACQUIRE); return data; }
};

template<size_t byte_size>
struct Atomic::PlatformOrderedStore<byte_size, RELEASE_X>
{
template <typename T>
void operator()(T v, volatile T* p) const { __atomic_store(const_cast<T*>(p), &v, __ATOMIC_RELEASE); }
};

template<size_t byte_size>
struct Atomic::PlatformOrderedStore<byte_size, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const { release_store(p, v); OrderAccess::fence(); }
};

#endif // OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP
25 changes: 4 additions & 21 deletions src/hotspot/os_cpu/linux_aarch64/orderAccess_linux_aarch64.hpp
Expand Up @@ -37,6 +37,10 @@ inline void OrderAccess::storestore() { release(); }
inline void OrderAccess::loadstore() { acquire(); }
inline void OrderAccess::storeload() { fence(); }

#define FULL_MEM_BARRIER __sync_synchronize()
#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE);
#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE);

inline void OrderAccess::acquire() {
READ_MEM_BARRIER;
}
Expand All @@ -51,25 +55,4 @@ inline void OrderAccess::fence() {

inline void OrderAccess::cross_modify_fence() { }

template<size_t byte_size>
struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const { T data; __atomic_load(const_cast<T*>(p), &data, __ATOMIC_ACQUIRE); return data; }
};

template<size_t byte_size>
struct OrderAccess::PlatformOrderedStore<byte_size, RELEASE_X>
{
template <typename T>
void operator()(T v, volatile T* p) const { __atomic_store(const_cast<T*>(p), &v, __ATOMIC_RELEASE); }
};

template<size_t byte_size>
struct OrderAccess::PlatformOrderedStore<byte_size, RELEASE_X_FENCE>
{
template <typename T>
void operator()(T v, volatile T* p) const { release_store(p, v); fence(); }
};

#endif // OS_CPU_LINUX_AARCH64_ORDERACCESS_LINUX_AARCH64_HPP
13 changes: 13 additions & 0 deletions src/hotspot/os_cpu/linux_ppc/atomic_linux_ppc.hpp
Expand Up @@ -30,6 +30,7 @@
#error "Atomic currently only implemented for PPC64"
#endif

#include "orderAccess_linux_ppc.hpp"
#include "utilities/debug.hpp"

// Implementation of class atomic
Expand Down Expand Up @@ -399,4 +400,16 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
return old_value;
}

template<size_t byte_size>
struct Atomic::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const {
T t = Atomic::load(p);
// Use twi-isync for load_acquire (faster than lwsync).
__asm__ __volatile__ ("twi 0,%0,0\n isync\n" : : "r" (t) : "memory");
return t;
}
};

#endif // OS_CPU_LINUX_PPC_ATOMIC_LINUX_PPC_HPP
10 changes: 0 additions & 10 deletions src/hotspot/os_cpu/linux_ppc/orderAccess_linux_ppc.hpp
Expand Up @@ -68,8 +68,6 @@
#define inlasm_lwsync() __asm__ __volatile__ ("lwsync" : : : "memory");
#define inlasm_eieio() __asm__ __volatile__ ("eieio" : : : "memory");
#define inlasm_isync() __asm__ __volatile__ ("isync" : : : "memory");
// Use twi-isync for load_acquire (faster than lwsync).
#define inlasm_acquire_reg(X) __asm__ __volatile__ ("twi 0,%0,0\n isync\n" : : "r" (X) : "memory");

inline void OrderAccess::loadload() { inlasm_lwsync(); }
inline void OrderAccess::storestore() { inlasm_lwsync(); }
Expand All @@ -82,17 +80,9 @@ inline void OrderAccess::fence() { inlasm_sync(); }
inline void OrderAccess::cross_modify_fence()
{ inlasm_isync(); }

template<size_t byte_size>
struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const { T t = Atomic::load(p); inlasm_acquire_reg(t); return t; }
};

#undef inlasm_sync
#undef inlasm_lwsync
#undef inlasm_eieio
#undef inlasm_isync
#undef inlasm_acquire_reg

#endif // OS_CPU_LINUX_PPC_ORDERACCESS_LINUX_PPC_HPP
7 changes: 7 additions & 0 deletions src/hotspot/os_cpu/linux_s390/atomic_linux_s390.hpp
Expand Up @@ -335,4 +335,11 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T xchg_val,
return old;
}

template<size_t byte_size>
struct Atomic::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const { T t = *p; OrderAccess::acquire(); return t; }
};

#endif // OS_CPU_LINUX_S390_ATOMIC_LINUX_S390_HPP
7 changes: 0 additions & 7 deletions src/hotspot/os_cpu/linux_s390/orderAccess_linux_s390.hpp
Expand Up @@ -76,13 +76,6 @@ inline void OrderAccess::release() { inlasm_zarch_release(); }
inline void OrderAccess::fence() { inlasm_zarch_sync(); }
inline void OrderAccess::cross_modify_fence() { inlasm_zarch_sync(); }

template<size_t byte_size>
struct OrderAccess::PlatformOrderedLoad<byte_size, X_ACQUIRE>
{
template <typename T>
T operator()(const volatile T* p) const { T t = *p; inlasm_zarch_acquire(); return t; }
};

#undef inlasm_compiler_barrier
#undef inlasm_zarch_sync
#undef inlasm_zarch_release
Expand Down

0 comments on commit e527ce4

Please sign in to comment.