1/*
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_MEMORY_PADDED_HPP
26#define SHARE_MEMORY_PADDED_HPP
27
28#include "memory/allocation.hpp"
29#include "utilities/align.hpp"
30#include "utilities/globalDefinitions.hpp"
31
32// Bytes needed to pad type to avoid cache-line sharing; alignment should be the
33// expected cache line size (a power of two). The first addend avoids sharing
34// when the start address is not a multiple of alignment; the second maintains
35// alignment of starting addresses that happen to be a multiple.
36#define PADDING_SIZE(type, alignment) \
37 ((alignment) + align_up_(sizeof(type), (alignment)))
38
39// Templates to create a subclass padded to avoid cache line sharing. These are
40// effective only when applied to derived-most (leaf) classes.
41
42// When no args are passed to the base ctor.
43template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
44class Padded : public T {
45 private:
46 char _pad_buf_[PADDING_SIZE(T, alignment)];
47};
48
49// When either 0 or 1 args may be passed to the base ctor.
50template <class T, typename Arg1T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
51class Padded01 : public T {
52 public:
53 Padded01(): T() { }
54 Padded01(Arg1T arg1): T(arg1) { }
55 private:
56 char _pad_buf_[PADDING_SIZE(T, alignment)];
57};
58
59// Super class of PaddedEnd when pad_size != 0.
60template <class T, size_t pad_size>
61class PaddedEndImpl : public T {
62 private:
63 char _pad_buf[pad_size];
64};
65
66// Super class of PaddedEnd when pad_size == 0.
67template <class T>
68class PaddedEndImpl<T, /*pad_size*/ 0> : public T {
69 // No padding.
70};
71
72#define PADDED_END_SIZE(type, alignment) (align_up_(sizeof(type), (alignment)) - sizeof(type))
73
74// More memory conservative implementation of Padded. The subclass adds the
75// minimal amount of padding needed to make the size of the objects be aligned.
76// This will help reducing false sharing,
77// if the start address is a multiple of alignment.
78template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
79class PaddedEnd : public PaddedEndImpl<T, PADDED_END_SIZE(T, alignment)> {
80 // C++ doesn't allow zero-length arrays. The padding is put in a
81 // super class that is specialized for the pad_size == 0 case.
82};
83
84// Similar to PaddedEnd, this macro defines a _pad_buf#id field
85// that is (alignment - size) bytes in size. This macro is used
86// to add padding in between non-class fields in a class or struct.
87#define DEFINE_PAD_MINUS_SIZE(id, alignment, size) \
88 char _pad_buf##id[(alignment) - (size)]
89
90// Helper class to create an array of PaddedEnd<T> objects. All elements will
91// start at a multiple of alignment and the size will be aligned to alignment.
92template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
93class PaddedArray {
94 public:
95 // Creates an aligned padded array.
96 // The memory can't be deleted since the raw memory chunk is not returned.
97 static PaddedEnd<T>* create_unfreeable(uint length);
98};
99
100// Helper class to create an array of references to arrays of primitive types
101// Both the array of references and the data arrays are aligned to the given
102// alignment. The allocated memory is zero-filled.
103template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
104class Padded2DArray {
105 public:
106 // Creates an aligned padded 2D array.
107 // The memory cannot be deleted since the raw memory chunk is not returned.
108 // Always uses mmap to reserve memory. Only the first few pages with the index to
109 // the rows are touched. Allocation size should be "large" to cover page overhead.
110 static T** create_unfreeable(uint rows, uint columns, size_t* allocation_size = NULL);
111};
112
113// Helper class to create an array of T objects. The array as a whole will
114// start at a multiple of alignment and its size will be aligned to alignment.
115template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
116class PaddedPrimitiveArray {
117 public:
118 static T* create_unfreeable(size_t length);
119};
120
121#endif // SHARE_MEMORY_PADDED_HPP
122