8237842: Separate definitions for default cache line and padding sizes
Reviewed-by: stefank, kvn, stuefe, tschatzl
This commit is contained in:
parent
83564ea5f3
commit
dd517c6404
src/hotspot
cpu
aarch64
arm
ppc
riscv
s390
x86
zero
share
gc
g1
g1ConcurrentMark.hppg1DirtyCardQueue.hppg1MonotonicArena.hppg1ParScanThreadState.cppg1RedirtyCardsQueue.hpp
shared
jfr/utilities
memory
runtime
utilities
test/hotspot/gtest/gc/shared
@ -42,8 +42,12 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
// and Operational Models for ARMv8"
|
||||
#define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
// According to the ARMv8 ARM, "Concurrent modification and execution
|
||||
// of instructions can lead to the resulting instruction performing
|
||||
// any behavior that can be achieved by executing any sequence of
|
||||
|
@ -49,8 +49,12 @@ const bool HaveVFP = true;
|
||||
// arm32 is not specified as multi-copy-atomic
|
||||
// So we must not #define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define STUBROUTINES_MD_HPP "stubRoutines_arm.hpp"
|
||||
#define INTERP_MASM_MD_HPP "interp_masm_arm.hpp"
|
||||
#define TEMPLATETABLE_MD_HPP "templateTable_arm.hpp"
|
||||
|
@ -48,9 +48,12 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
// PPC64 is not specified as multi-copy-atomic
|
||||
// So we must not #define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 128
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define SUPPORT_RESERVED_STACK_AREA
|
||||
|
||||
// If UseSIGTRAP is active, we only use the poll bit and no polling page.
|
||||
|
@ -50,6 +50,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#endif // CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP
|
||||
|
@ -48,6 +48,9 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 256
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define SUPPORT_RESERVED_STACK_AREA
|
||||
|
||||
#endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
|
||||
|
@ -38,29 +38,18 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
#if COMPILER1_AND_COMPILER2
|
||||
#ifdef _LP64
|
||||
// tiered, 64-bit, large machine
|
||||
#define DEFAULT_CACHE_LINE_SIZE 128
|
||||
#define OM_CACHE_LINE_SIZE 64
|
||||
#else
|
||||
// tiered, 32-bit, medium machine
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
#endif
|
||||
#elif defined(COMPILER1)
|
||||
// pure C1, 32-bit, small machine
|
||||
// i486 was the last Intel chip with 16-byte cache line size
|
||||
#define DEFAULT_CACHE_LINE_SIZE 32
|
||||
#elif defined(COMPILER2)
|
||||
#ifdef _LP64
|
||||
// pure C2, 64-bit, large machine
|
||||
#define DEFAULT_CACHE_LINE_SIZE 128
|
||||
#define OM_CACHE_LINE_SIZE 64
|
||||
#else
|
||||
// pure C2, 32-bit, medium machine
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
#endif
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#ifdef _LP64
|
||||
// The common wisdom is that adjacent cache line prefetchers on some hardware
|
||||
// may pull two cache lines on access, so we have to pessimistically assume twice
|
||||
// the cache line size for padding. TODO: Check if this is still true for modern
|
||||
// hardware. If not, DEFAULT_CACHE_LINE_SIZE might as well suffice.
|
||||
#define DEFAULT_PADDING_SIZE (DEFAULT_CACHE_LINE_SIZE*2)
|
||||
#else
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER2)
|
||||
|
@ -30,8 +30,12 @@
|
||||
#define SUPPORTS_NATIVE_CX8
|
||||
#endif
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define SUPPORT_MONITOR_COUNT
|
||||
|
||||
#include <ffi.h>
|
||||
|
@ -167,9 +167,9 @@ private:
|
||||
size_t _num_buckets;
|
||||
bool _should_grow;
|
||||
TaskQueueEntryChunk* volatile* _buckets;
|
||||
char _pad0[DEFAULT_CACHE_LINE_SIZE];
|
||||
char _pad0[DEFAULT_PADDING_SIZE];
|
||||
volatile size_t _size;
|
||||
char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)];
|
||||
char _pad4[DEFAULT_PADDING_SIZE - sizeof(size_t)];
|
||||
|
||||
size_t bucket_size(size_t bucket) {
|
||||
return (bucket == 0) ?
|
||||
@ -232,12 +232,12 @@ private:
|
||||
|
||||
ChunkAllocator _chunk_allocator;
|
||||
|
||||
char _pad0[DEFAULT_CACHE_LINE_SIZE];
|
||||
char _pad0[DEFAULT_PADDING_SIZE];
|
||||
TaskQueueEntryChunk* volatile _free_list; // Linked list of free chunks that can be allocated by users.
|
||||
char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*)];
|
||||
char _pad1[DEFAULT_PADDING_SIZE - sizeof(TaskQueueEntryChunk*)];
|
||||
TaskQueueEntryChunk* volatile _chunk_list; // List of chunks currently containing data.
|
||||
volatile size_t _chunks_in_chunk_list;
|
||||
char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)];
|
||||
char _pad2[DEFAULT_PADDING_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)];
|
||||
|
||||
// Atomically add the given chunk to the list.
|
||||
void add_chunk_to_list(TaskQueueEntryChunk* volatile* list, TaskQueueEntryChunk* elem);
|
||||
|
@ -135,7 +135,7 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
|
||||
// and install the next list, and meanwhile there can be a thread dealing
|
||||
// with the previous list.
|
||||
PausedList* volatile _plist;
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(PausedList*));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(PausedList*));
|
||||
|
||||
NONCOPYABLE(PausedBuffers);
|
||||
|
||||
@ -157,19 +157,19 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
|
||||
HeadTail take_all();
|
||||
};
|
||||
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
// Upper bound on the number of cards in the completed and paused buffers.
|
||||
volatile size_t _num_cards;
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(size_t));
|
||||
// If the queue contains more cards than configured here, the
|
||||
// mutator must start doing some of the concurrent refinement work.
|
||||
volatile size_t _mutator_refinement_threshold;
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(size_t));
|
||||
// Buffers ready for refinement.
|
||||
// NonblockingQueue has inner padding of one cache line.
|
||||
NonblockingQueue<BufferNode, &BufferNode::next_ptr> _completed;
|
||||
// Add a trailer padding after NonblockingQueue.
|
||||
DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
|
||||
DEFINE_PAD_MINUS_SIZE(3, DEFAULT_PADDING_SIZE, sizeof(BufferNode*));
|
||||
// Buffers for which refinement is temporarily paused.
|
||||
// PausedBuffers has inner padding, including trailer.
|
||||
PausedBuffers _paused;
|
||||
|
@ -125,7 +125,7 @@ class G1MonotonicArena::Segment {
|
||||
char* _bottom; // Actual data.
|
||||
// Do not add class member variables beyond this point
|
||||
|
||||
static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_CACHE_LINE_SIZE); }
|
||||
static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_PADDING_SIZE); }
|
||||
|
||||
static size_t payload_size(uint slot_size, uint num_slots) {
|
||||
// The cast (size_t) is required to guard against overflow wrap around.
|
||||
|
@ -95,7 +95,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
|
||||
// entries, since entry 0 keeps track of surviving bytes for non-young regions.
|
||||
// We also add a few elements at the beginning and at the end in
|
||||
// an attempt to eliminate cache contention
|
||||
const size_t padding_elem_num = (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t));
|
||||
const size_t padding_elem_num = (DEFAULT_PADDING_SIZE / sizeof(size_t));
|
||||
size_t array_length = padding_elem_num + _surviving_words_length + padding_elem_num;
|
||||
|
||||
_surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
|
||||
|
@ -66,11 +66,11 @@ public:
|
||||
// collected (and processed) buffers reverts back to collecting, allowing
|
||||
// the set to be reused for another round of redirtying.
|
||||
class G1RedirtyCardsQueueSet : public PtrQueueSet {
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
|
||||
BufferNode::Stack _list;
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t));
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(size_t));
|
||||
volatile size_t _entry_count;
|
||||
DEFINE_PAD_MINUS_SIZE(3, DEFAULT_CACHE_LINE_SIZE, sizeof(BufferNode*));
|
||||
DEFINE_PAD_MINUS_SIZE(3, DEFAULT_PADDING_SIZE, sizeof(BufferNode*));
|
||||
BufferNode* _tail;
|
||||
DEBUG_ONLY(mutable bool _collecting;)
|
||||
|
||||
|
@ -109,10 +109,10 @@ class FreeListAllocator {
|
||||
typedef LockFreeStack<FreeNode, &next_ptr> Stack;
|
||||
|
||||
FreeListConfig* _config;
|
||||
char _name[DEFAULT_CACHE_LINE_SIZE - sizeof(FreeListConfig*)]; // Use name as padding.
|
||||
char _name[DEFAULT_PADDING_SIZE - sizeof(FreeListConfig*)]; // Use name as padding.
|
||||
|
||||
#define DECLARE_PADDED_MEMBER(Id, Type, Name) \
|
||||
Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_CACHE_LINE_SIZE, sizeof(Type))
|
||||
Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_PADDING_SIZE, sizeof(Type))
|
||||
DECLARE_PADDED_MEMBER(1, volatile size_t, _free_count);
|
||||
DECLARE_PADDED_MEMBER(2, Stack, _free_list);
|
||||
DECLARE_PADDED_MEMBER(3, volatile bool, _transfer_lock);
|
||||
|
@ -85,7 +85,7 @@ public:
|
||||
|
||||
class SATBMarkQueueSet: public PtrQueueSet {
|
||||
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
|
||||
PaddedEnd<BufferNode::Stack> _list;
|
||||
volatile size_t _count_and_process_flag;
|
||||
// These are rarely (if ever) changed, so same cache line as count.
|
||||
@ -93,7 +93,7 @@ class SATBMarkQueueSet: public PtrQueueSet {
|
||||
size_t _buffer_enqueue_threshold;
|
||||
// SATB is only active during marking. Enqueuing is only done when active.
|
||||
bool _all_active;
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 4 * sizeof(size_t));
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, 4 * sizeof(size_t));
|
||||
|
||||
BufferNode* get_completed_buffer();
|
||||
void abandon_completed_buffers();
|
||||
|
@ -72,9 +72,9 @@ class TaskTerminator : public CHeapObj<mtGC> {
|
||||
uint _n_threads;
|
||||
TaskQueueSetSuper* _queue_set;
|
||||
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
volatile uint _offered_termination;
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile uint));
|
||||
|
||||
Monitor _blocker;
|
||||
Thread* _spin_master;
|
||||
|
@ -233,11 +233,11 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
|
||||
// Index of the first free element after the last one pushed (mod N).
|
||||
volatile uint _bottom;
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(uint));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(uint));
|
||||
|
||||
// top() is the index of the oldest pushed element (mod N), and tag()
|
||||
// is the associated epoch, to distinguish different modifications of
|
||||
@ -245,7 +245,7 @@ private:
|
||||
// (_bottom - top()) mod N == N-1; the latter indicates underflow
|
||||
// during concurrent pop_local/pop_global.
|
||||
volatile Age _age;
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(Age));
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(Age));
|
||||
|
||||
NONCOPYABLE(TaskQueueSuper);
|
||||
|
||||
@ -396,7 +396,7 @@ private:
|
||||
// Element array.
|
||||
E* _elems;
|
||||
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(E*));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(E*));
|
||||
// Queue owner local variables. Not to be accessed by other threads.
|
||||
|
||||
static const uint InvalidQueueId = uint(-1);
|
||||
@ -404,7 +404,7 @@ private:
|
||||
|
||||
int _seed; // Current random seed used for selecting a random queue during stealing.
|
||||
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(uint) + sizeof(int));
|
||||
DEFINE_PAD_MINUS_SIZE(2, DEFAULT_PADDING_SIZE, sizeof(uint) + sizeof(int));
|
||||
public:
|
||||
int next_random_queue_id();
|
||||
|
||||
|
@ -105,9 +105,9 @@ class JfrVersionSystem : public JfrCHeapObj {
|
||||
NodePtr synchronize_with(Type version, NodePtr last) const;
|
||||
DEBUG_ONLY(void assert_state(const Node* node) const;)
|
||||
struct PaddedTip {
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
volatile Type _value;
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile Type));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile Type));
|
||||
};
|
||||
PaddedTip _tip;
|
||||
NodePtr _head;
|
||||
|
@ -40,14 +40,14 @@
|
||||
// effective only when applied to derived-most (leaf) classes.
|
||||
|
||||
// When no args are passed to the base ctor.
|
||||
template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
template <class T, size_t alignment = DEFAULT_PADDING_SIZE>
|
||||
class Padded : public T {
|
||||
private:
|
||||
char _pad_buf_[PADDING_SIZE(T, alignment)];
|
||||
};
|
||||
|
||||
// When either 0 or 1 args may be passed to the base ctor.
|
||||
template <class T, typename Arg1T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
template <class T, typename Arg1T, size_t alignment = DEFAULT_PADDING_SIZE>
|
||||
class Padded01 : public T {
|
||||
public:
|
||||
Padded01(): T() { }
|
||||
@ -75,7 +75,7 @@ class PaddedEndImpl<T, /*pad_size*/ 0> : public T {
|
||||
// minimal amount of padding needed to make the size of the objects be aligned.
|
||||
// This will help reducing false sharing,
|
||||
// if the start address is a multiple of alignment.
|
||||
template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
template <class T, size_t alignment = DEFAULT_PADDING_SIZE>
|
||||
class PaddedEnd : public PaddedEndImpl<T, PADDED_END_SIZE(T, alignment)> {
|
||||
// C++ doesn't allow zero-length arrays. The padding is put in a
|
||||
// super class that is specialized for the pad_size == 0 case.
|
||||
@ -89,7 +89,7 @@ class PaddedEnd : public PaddedEndImpl<T, PADDED_END_SIZE(T, alignment)> {
|
||||
|
||||
// Helper class to create an array of PaddedEnd<T> objects. All elements will
|
||||
// start at a multiple of alignment and the size will be aligned to alignment.
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_PADDING_SIZE>
|
||||
class PaddedArray {
|
||||
public:
|
||||
// Creates an aligned padded array.
|
||||
@ -100,7 +100,7 @@ class PaddedArray {
|
||||
// Helper class to create an array of references to arrays of primitive types
|
||||
// Both the array of references and the data arrays are aligned to the given
|
||||
// alignment. The allocated memory is zero-filled.
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_PADDING_SIZE>
|
||||
class Padded2DArray {
|
||||
public:
|
||||
// Creates an aligned padded 2D array.
|
||||
@ -112,7 +112,7 @@ class Padded2DArray {
|
||||
|
||||
// Helper class to create an array of T objects. The array as a whole will
|
||||
// start at a multiple of alignment and its size will be aligned to alignment.
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
|
||||
template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_PADDING_SIZE>
|
||||
class PaddedPrimitiveArray {
|
||||
public:
|
||||
static T* create_unfreeable(size_t length);
|
||||
|
@ -221,7 +221,7 @@ class Monitor : public Mutex {
|
||||
|
||||
class PaddedMutex : public Mutex {
|
||||
enum {
|
||||
CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex),
|
||||
CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Mutex),
|
||||
PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
|
||||
};
|
||||
char _padding[PADDING_LEN];
|
||||
@ -232,7 +232,7 @@ public:
|
||||
|
||||
class PaddedMonitor : public Monitor {
|
||||
enum {
|
||||
CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor),
|
||||
CACHE_LINE_PADDING = (int)DEFAULT_PADDING_SIZE - (int)sizeof(Monitor),
|
||||
PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
|
||||
};
|
||||
char _padding[PADDING_LEN];
|
||||
|
@ -121,11 +121,7 @@ class ObjectWaiter : public StackObj {
|
||||
// intptr_t. There's no reason to use a 64-bit type for this field
|
||||
// in a 64-bit JVM.
|
||||
|
||||
#ifndef OM_CACHE_LINE_SIZE
|
||||
// Use DEFAULT_CACHE_LINE_SIZE if not already specified for
|
||||
// the current build platform.
|
||||
#define OM_CACHE_LINE_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
#endif
|
||||
|
||||
class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
|
||||
friend class ObjectSynchronizer;
|
||||
|
@ -46,9 +46,9 @@ class GlobalCounter : public AllStatic {
|
||||
// Since do not know what we will end up next to in BSS, we make sure the
|
||||
// counter is on a separate cacheline.
|
||||
struct PaddedCounter {
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
volatile uintx _counter;
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uintx));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(volatile uintx));
|
||||
};
|
||||
|
||||
// The global counter
|
||||
|
@ -602,11 +602,16 @@ const bool support_IRIW_for_not_multiple_copy_atomic_cpu = false;
|
||||
const bool support_IRIW_for_not_multiple_copy_atomic_cpu = PPC64_ONLY(true) NOT_PPC64(false);
|
||||
#endif
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
// The expected size in bytes of a cache line.
|
||||
#ifndef DEFAULT_CACHE_LINE_SIZE
|
||||
#error "Platform should define DEFAULT_CACHE_LINE_SIZE"
|
||||
#endif
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#ifndef DEFAULT_PADDING_SIZE
|
||||
#error "Platform should define DEFAULT_PADDING_SIZE"
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Utility macros for compilers
|
||||
|
@ -62,7 +62,7 @@ template<typename T, T* volatile* (*next_ptr)(T&)>
|
||||
class NonblockingQueue {
|
||||
T* volatile _head;
|
||||
// Padding of one cache line to avoid false sharing.
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(T*));
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, sizeof(T*));
|
||||
T* volatile _tail;
|
||||
|
||||
NONCOPYABLE(NonblockingQueue);
|
||||
|
@ -38,7 +38,7 @@ private:
|
||||
// This would insulate from stalls when adjacent cells have returning
|
||||
// workers and contend over the cache line for current latency-critical
|
||||
// cell.
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
|
||||
Semaphore _sem;
|
||||
|
||||
@ -81,14 +81,14 @@ private:
|
||||
Cell _cells[CELLS_COUNT];
|
||||
|
||||
// Trailing padding to protect the last cell.
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_PADDING_SIZE, 0);
|
||||
|
||||
volatile int _barrier_tag;
|
||||
|
||||
// Trailing padding to insulate the rest of the barrier from adjacent
|
||||
// data structures. The leading padding is not needed, as cell padding
|
||||
// handles this for us.
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
|
||||
|
||||
NONCOPYABLE(GenericWaitBarrier);
|
||||
|
||||
|
@ -239,7 +239,7 @@ static void run_test(BufferNode::Allocator* allocator, CompletedList* cbl) {
|
||||
}
|
||||
|
||||
TEST_VM(BufferNodeAllocatorTest, stress_free_list_allocator) {
|
||||
const size_t buffer_capacity = DEFAULT_CACHE_LINE_SIZE / sizeof(void*);
|
||||
const size_t buffer_capacity = DEFAULT_PADDING_SIZE / sizeof(void*);
|
||||
BufferNode::Allocator allocator("Test Allocator", buffer_capacity);
|
||||
CompletedList completed;
|
||||
run_test(&allocator, &completed);
|
||||
|
Loading…
x
Reference in New Issue
Block a user