diff --git a/third-party/folly/folly/Portability.h b/third-party/folly/folly/Portability.h index 61c05ff22..93a4e41a5 100644 --- a/third-party/folly/folly/Portability.h +++ b/third-party/folly/folly/Portability.h @@ -82,3 +82,11 @@ constexpr bool kIsSanitizeThread = true; constexpr bool kIsSanitizeThread = false; #endif } // namespace folly + +namespace folly { +#if defined(__linux__) && !FOLLY_MOBILE +constexpr auto kIsLinux = true; +#else +constexpr auto kIsLinux = false; +#endif +} // namespace folly diff --git a/third-party/folly/folly/lang/Align.h b/third-party/folly/folly/lang/Align.h index 5257e2f6f..fd00b14ff 100644 --- a/third-party/folly/folly/lang/Align.h +++ b/third-party/folly/folly/lang/Align.h @@ -1,14 +1,101 @@ -// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. -// This source code is licensed under both the GPLv2 (found in the -// COPYING file in the root directory) and Apache 2.0 License -// (found in the LICENSE.Apache file in the root directory). +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * 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 #include +#include +#include + namespace folly { +// has_extended_alignment +// +// True if it may be presumed that the platform has static extended alignment; +// false if it may not be so presumed, even when the platform might actually +// have it. Static extended alignment refers to extended alignment of objects +// with automatic, static, or thread storage. Whether the there is support for +// dynamic extended alignment is a property of the allocator which is used for +// each given dynamic allocation. +// +// Currently, very heuristical - only non-mobile 64-bit linux gets the extended +// alignment treatment. Theoretically, this could be tuned better. +constexpr bool has_extended_alignment = + kIsLinux && sizeof(void*) >= sizeof(std::uint64_t); + +namespace detail { + +// Implemented this way because of a bug in Clang for ARMv7, which gives the +// wrong result for `alignof` a `union` with a field of each scalar type. +// Modified for RocksDB to use C++11 only +constexpr std::size_t max_align_v = constexpr_max( + alignof(long double), + alignof(double), + alignof(float), + alignof(long long int), + alignof(long int), + alignof(int), + alignof(short int), + alignof(bool), + alignof(char), + alignof(char16_t), + alignof(char32_t), + alignof(wchar_t), + alignof(void*), + alignof(std::max_align_t)); + +} // 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 = detail::max_align_v; +struct alignas(max_align_v) max_align_t {}; + // Memory locations within the same cache line are subject to destructive // interference, also known as false sharing, which is when concurrent // accesses to these different memory locations from different cores, where at @@ -23,7 +110,9 @@ namespace folly { // to avoid destructive interference. // // mimic: std::hardware_destructive_interference_size, C++17 -constexpr std::size_t hardware_destructive_interference_size = 128; +constexpr std::size_t hardware_destructive_interference_size = + kIsArchArm ? 64 : 128; +static_assert(hardware_destructive_interference_size >= max_align_v, "math?"); // Memory locations within the same cache line are subject to constructive // interference, also known as true sharing, which is when accesses to some @@ -33,6 +122,14 @@ constexpr std::size_t hardware_destructive_interference_size = 128; // // mimic: std::hardware_constructive_interference_size, C++17 constexpr std::size_t hardware_constructive_interference_size = 64; +static_assert(hardware_constructive_interference_size >= max_align_v, "math?"); -} // namespace folly +// A value corresponding to hardware_constructive_interference_size but which +// may be used with alignas, since hardware_constructive_interference_size may +// be too large on some platforms to be used with alignas. +constexpr std::size_t cacheline_align_v = has_extended_alignment + ? hardware_constructive_interference_size + : max_align_v; +struct alignas(cacheline_align_v) cacheline_align_t {}; +} // namespace folly