#include <folly/Portability.h>
#include <folly/concurrency/CacheLocality.h>
+#include <folly/lang/Align.h>
namespace folly {
template <typename T>
class CachelinePadded {
static_assert(
- alignof(T) <= folly::max_align_v,
+ alignof(T) <= max_align_v,
"CachelinePadded does not support over-aligned types.");
public:
io/async/test/UndelayedDestruction.h \
io/async/test/Util.h \
json.h \
+ lang/Align.h \
lang/Assume.h \
lang/Bits.h \
lang/ColdClass.h \
#include <folly/Portability.h>
#include <folly/detail/Sleeper.h>
+#include <folly/lang/Align.h>
namespace folly {
#define FOLLY_CACHE_LINE_SIZE 64
template <class T, size_t N>
-struct FOLLY_ALIGNED_MAX SpinLockArray {
+struct alignas(max_align_v) SpinLockArray {
T& operator[](size_t i) {
return data_[i].lock;
}
// Check if T can theoretically cross a cache line.
static_assert(
- folly::max_align_v > 0 &&
- FOLLY_CACHE_LINE_SIZE % folly::max_align_v == 0 &&
- sizeof(T) <= folly::max_align_v,
+ max_align_v > 0 && FOLLY_CACHE_LINE_SIZE % max_align_v == 0 &&
+ sizeof(T) <= max_align_v,
"T can cross cache line boundaries");
char padding_[FOLLY_CACHE_LINE_SIZE];
#pragma once
#include <cstddef>
-#include <type_traits>
#include <folly/portability/Config.h>
#else
constexpr bool kHasUnalignedAccess = false;
#endif
-
-namespace portability_detail {
-
-template <typename I, I A, I B>
-using integral_max = std::integral_constant<I, (A < B) ? B : A>;
-
-template <typename I, I A, I... Bs>
-struct integral_sequence_max
- : integral_max<I, A, integral_sequence_max<I, Bs...>::value> {};
-
-template <typename I, I A>
-struct integral_sequence_max<I, A> : std::integral_constant<I, A> {};
-
-template <typename... Ts>
-using max_alignment = integral_sequence_max<size_t, alignof(Ts)...>;
-
-using max_basic_alignment = max_alignment<
- std::max_align_t,
- long double,
- double,
- float,
- long long int,
- long int,
- int,
- short int,
- bool,
- char,
- char16_t,
- char32_t,
- wchar_t,
- std::nullptr_t>;
-} // namespace portability_detail
-
-constexpr size_t max_align_v = portability_detail::max_basic_alignment::value;
-
-// max_align_t is a type which is aligned at least as strictly as the
-// most-aligned basic type (see the specification of std::max_align_t). This
-// implementation exists because 32-bit iOS platforms have a broken
-// std::max_align_t (see below).
-//
-// You should refer to this as `::folly::max_align_t` in portable code, even if
-// you have `using namespace folly;` because C11 defines a global namespace
-// `max_align_t` type.
-//
-// To be certain, we consider every non-void fundamental type specified by the
-// standard. On most platforms `long double` would be enough, but iOS 32-bit
-// has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
-// `long double`.
-//
-// So far we've covered locals and other non-allocated storage, but we also need
-// confidence that allocated storage from `malloc`, `new`, etc will also be
-// suitable for objects with this alignment reuirement.
-//
-// Apple document that their implementation of malloc will issue 16-byte
-// granularity chunks for small allocations (large allocations are page-size
-// granularity and page-aligned). We think that allocated storage will be
-// suitable for these objects based on the following assumptions:
-//
-// 1. 16-byte granularity also means 16-byte aligned.
-// 2. `new` and other allocators follow the `malloc` rules.
-//
-// We also have some anecdotal evidence: we don't see lots of misaligned-storage
-// crashes on 32-bit iOS apps that use `double`.
-//
-// Apple's allocation reference: http://bit.ly/malloc-small
-struct alignas(max_align_v) max_align_t {};
-
} // namespace folly
// compiler specific attribute translation
#else
# error Cannot define FOLLY_ALIGNED on this platform
#endif
-#define FOLLY_ALIGNED_MAX FOLLY_ALIGNED(::folly::max_align_v)
// NOTE: this will only do checking in msvc with versions that support /analyze
#if _MSC_VER
// Install a pointer to ourselves as the allocator.
*reinterpret_cast<SimpleAllocator**>(mem_) = this;
- static_assert(
- folly::max_align_v >= sizeof(SimpleAllocator*), "alignment too small");
- mem_ += std::min(sz_, folly::max_align_v);
+ static_assert(max_align_v >= sizeof(SimpleAllocator*), "alignment too small");
+ mem_ += std::min(sz_, max_align_v);
// New allocation.
auto mem = mem_;
#include <folly/Memory.h>
#include <folly/Portability.h>
#include <folly/hash/Hash.h>
+#include <folly/lang/Align.h>
#include <folly/portability/BitsFunctexcept.h>
#include <folly/portability/Memory.h>
#include <folly/system/ThreadId.h>
if (intptr_t(mem_) % 128 == 0) {
// Avoid allocating pointers that may look like malloc
// pointers.
- mem_ += std::min(sz_, folly::max_align_v);
+ mem_ += std::min(sz_, max_align_v);
}
if (mem_ && (mem_ + sz_ <= end_)) {
auto mem = mem_;
memory_resource* new_delete_resource() {
class new_delete : public memory_resource {
public:
- void* allocate(
- const size_t bytes,
- const size_t alignment = folly::max_align_v) override {
+ void* allocate(const size_t bytes, const size_t alignment = max_align_v)
+ override {
(void)alignment;
void* p = static_cast<void*>(new char[bytes]);
DEBUG_PRINT(this << " " << p << " " << bytes);
void deallocate(
void* p,
const size_t bytes,
- const size_t alignment = folly::max_align_v) override {
+ const size_t alignment = max_align_v) override {
(void)alignment;
(void)bytes;
DEBUG_PRINT(p << " " << bytes);
/// hazptr prototype.
////////////////////////////////////////////////////////////////////////////////
-#include <folly/Portability.h>
#include <memory>
+#include <folly/Portability.h>
+#include <folly/lang/Align.h>
+
namespace folly {
namespace hazptr {
virtual ~memory_resource() = default;
virtual void* allocate(
const size_t bytes,
- const size_t alignment = folly::max_align_v) = 0;
+ const size_t alignment = max_align_v) = 0;
virtual void deallocate(
void* p,
const size_t bytes,
- const size_t alignment = folly::max_align_v) = 0;
+ const size_t alignment = max_align_v) = 0;
};
memory_resource* get_default_resource();
#include <folly/ScopeGuard.h>
#include <folly/hash/SpookyHashV2.h>
#include <folly/io/Cursor.h>
+#include <folly/lang/Align.h>
#include <folly/memory/Malloc.h>
using std::unique_ptr;
--- /dev/null
+/*
+ * Copyright 2017-present Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstddef>
+
+namespace folly {
+
+namespace detail {
+
+union max_align_ {
+ std::max_align_t mat;
+ long double ld;
+ double d;
+ float f;
+ long long int lli;
+ long int li;
+ int i;
+ short int si;
+ bool b;
+ char c;
+ char16_t c16;
+ char32_t c32;
+ wchar_t wc;
+ std::nullptr_t n;
+};
+
+} // namespace detail
+
+// max_align_v is the alignment of max_align_t.
+//
+// max_align_t is a type which is aligned at least as strictly as the
+// most-aligned basic type (see the specification of std::max_align_t). This
+// implementation exists because 32-bit iOS platforms have a broken
+// std::max_align_t (see below).
+//
+// You should refer to this as `::folly::max_align_t` in portable code, even if
+// you have `using namespace folly;` because C11 defines a global namespace
+// `max_align_t` type.
+//
+// To be certain, we consider every non-void fundamental type specified by the
+// standard. On most platforms `long double` would be enough, but iOS 32-bit
+// has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
+// `long double`.
+//
+// So far we've covered locals and other non-allocated storage, but we also need
+// confidence that allocated storage from `malloc`, `new`, etc will also be
+// suitable for objects with this alignment requirement.
+//
+// Apple document that their implementation of malloc will issue 16-byte
+// granularity chunks for small allocations (large allocations are page-size
+// granularity and page-aligned). We think that allocated storage will be
+// suitable for these objects based on the following assumptions:
+//
+// 1. 16-byte granularity also means 16-byte aligned.
+// 2. `new` and other allocators follow the `malloc` rules.
+//
+// We also have some anecdotal evidence: we don't see lots of misaligned-storage
+// crashes on 32-bit iOS apps that use `double`.
+//
+// Apple's allocation reference: http://bit.ly/malloc-small
+constexpr std::size_t max_align_v = alignof(detail::max_align_);
+struct alignas(max_align_v) max_align_t {};
+
+} // namespace folly
#include <folly/Conv.h>
#include <folly/Likely.h>
#include <folly/Memory.h>
+#include <folly/lang/Align.h>
#include <folly/memory/Malloc.h>
namespace folly {
typedef boost::intrusive::slist_member_hook<
boost::intrusive::tag<Arena>> BlockLink;
- struct FOLLY_ALIGNED_MAX Block {
+ struct alignas(max_align_v) Block {
BlockLink link;
// Allocate a block with at least size bytes of storage.
#include <folly/Benchmark.h>
#include <folly/Memory.h>
#include <folly/Range.h>
+#include <folly/lang/Align.h>
#include <folly/portability/GTest.h>
using namespace folly;
} // namespace
TEST(ThreadCachedArena, BlockSize) {
- static const size_t alignment = folly::max_align_v;
+ static const size_t alignment = max_align_v;
static const size_t requestedBlockSize = 64;
ThreadCachedArena arena(requestedBlockSize);
#include <type_traits>
+#include <folly/lang/Align.h>
#include <folly/portability/GTest.h>
using folly::CachelinePadded;