]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/third-party/folly/folly/lang/Align.h
buildsys: change download over to reef release
[ceph.git] / ceph / src / rocksdb / third-party / folly / folly / lang / Align.h
1 /*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <cstddef>
20 #include <cstdint>
21
22 #include <folly/Portability.h>
23 #include <folly/ConstexprMath.h>
24
25 // Work around bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019
26 #ifdef __GNUC__
27 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
28 namespace std {
29 using ::max_align_t;
30 }
31 #endif
32 #endif
33
34 namespace folly {
35
36 // has_extended_alignment
37 //
38 // True if it may be presumed that the platform has static extended alignment;
39 // false if it may not be so presumed, even when the platform might actually
40 // have it. Static extended alignment refers to extended alignment of objects
41 // with automatic, static, or thread storage. Whether the there is support for
42 // dynamic extended alignment is a property of the allocator which is used for
43 // each given dynamic allocation.
44 //
45 // Currently, very heuristical - only non-mobile 64-bit linux gets the extended
46 // alignment treatment. Theoretically, this could be tuned better.
47 constexpr bool has_extended_alignment =
48 kIsLinux && sizeof(void*) >= sizeof(std::uint64_t);
49
50 namespace detail {
51
52 // Implemented this way because of a bug in Clang for ARMv7, which gives the
53 // wrong result for `alignof` a `union` with a field of each scalar type.
54 // Modified for RocksDB to use C++11 only
55 constexpr std::size_t max_align_v = constexpr_max(
56 alignof(long double),
57 alignof(double),
58 alignof(float),
59 alignof(long long int),
60 alignof(long int),
61 alignof(int),
62 alignof(short int),
63 alignof(bool),
64 alignof(char),
65 alignof(char16_t),
66 alignof(char32_t),
67 alignof(wchar_t),
68 alignof(void*),
69 alignof(std::max_align_t));
70
71 } // namespace detail
72
73 // max_align_v is the alignment of max_align_t.
74 //
75 // max_align_t is a type which is aligned at least as strictly as the
76 // most-aligned basic type (see the specification of std::max_align_t). This
77 // implementation exists because 32-bit iOS platforms have a broken
78 // std::max_align_t (see below).
79 //
80 // You should refer to this as `::folly::max_align_t` in portable code, even if
81 // you have `using namespace folly;` because C11 defines a global namespace
82 // `max_align_t` type.
83 //
84 // To be certain, we consider every non-void fundamental type specified by the
85 // standard. On most platforms `long double` would be enough, but iOS 32-bit
86 // has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
87 // `long double`.
88 //
89 // So far we've covered locals and other non-allocated storage, but we also need
90 // confidence that allocated storage from `malloc`, `new`, etc will also be
91 // suitable for objects with this alignment requirement.
92 //
93 // Apple document that their implementation of malloc will issue 16-byte
94 // granularity chunks for small allocations (large allocations are page-size
95 // granularity and page-aligned). We think that allocated storage will be
96 // suitable for these objects based on the following assumptions:
97 //
98 // 1. 16-byte granularity also means 16-byte aligned.
99 // 2. `new` and other allocators follow the `malloc` rules.
100 //
101 // We also have some anecdotal evidence: we don't see lots of misaligned-storage
102 // crashes on 32-bit iOS apps that use `double`.
103 //
104 // Apple's allocation reference: http://bit.ly/malloc-small
105 constexpr std::size_t max_align_v = detail::max_align_v;
106 struct alignas(max_align_v) max_align_t {};
107
108 // Memory locations within the same cache line are subject to destructive
109 // interference, also known as false sharing, which is when concurrent
110 // accesses to these different memory locations from different cores, where at
111 // least one of the concurrent accesses is or involves a store operation,
112 // induce contention and harm performance.
113 //
114 // Microbenchmarks indicate that pairs of cache lines also see destructive
115 // interference under heavy use of atomic operations, as observed for atomic
116 // increment on Sandy Bridge.
117 //
118 // We assume a cache line size of 64, so we use a cache line pair size of 128
119 // to avoid destructive interference.
120 //
121 // mimic: std::hardware_destructive_interference_size, C++17
122 constexpr std::size_t hardware_destructive_interference_size =
123 kIsArchArm ? 64 : 128;
124 static_assert(hardware_destructive_interference_size >= max_align_v, "math?");
125
126 // Memory locations within the same cache line are subject to constructive
127 // interference, also known as true sharing, which is when accesses to some
128 // memory locations induce all memory locations within the same cache line to
129 // be cached, benefiting subsequent accesses to different memory locations
130 // within the same cache line and heping performance.
131 //
132 // mimic: std::hardware_constructive_interference_size, C++17
133 constexpr std::size_t hardware_constructive_interference_size = 64;
134 static_assert(hardware_constructive_interference_size >= max_align_v, "math?");
135
136 // A value corresponding to hardware_constructive_interference_size but which
137 // may be used with alignas, since hardware_constructive_interference_size may
138 // be too large on some platforms to be used with alignas.
139 constexpr std::size_t cacheline_align_v = has_extended_alignment
140 ? hardware_constructive_interference_size
141 : max_align_v;
142 struct alignas(cacheline_align_v) cacheline_align_t {};
143
144 } // namespace folly