1 /* 2 * Copyright 2016-present Facebook, Inc. 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 <utility> 21 22 #include <folly/lang/Align.h> 23 24 namespace folly { 25 26 /** 27 * Holds a type T, in addition to enough padding to ensure that it isn't subject 28 * to false sharing within the range used by folly. 29 * 30 * If `sizeof(T) <= alignof(T)` then the inner `T` will be entirely within one 31 * false sharing range (AKA cache line). 32 */ 33 template <typename T> 34 class CachelinePadded { 35 static_assert( 36 alignof(T) <= max_align_v, 37 "CachelinePadded does not support over-aligned types."); 38 39 public: 40 template <typename... Args> CachelinePadded(Args &&...args)41 explicit CachelinePadded(Args&&... args) 42 : inner_(std::forward<Args>(args)...) {} 43 get()44 T* get() { 45 return &inner_; 46 } 47 get()48 const T* get() const { 49 return &inner_; 50 } 51 52 T* operator->() { 53 return get(); 54 } 55 56 const T* operator->() const { 57 return get(); 58 } 59 60 T& operator*() { 61 return *get(); 62 } 63 64 const T& operator*() const { 65 return *get(); 66 } 67 68 private: paddingSize()69 static constexpr size_t paddingSize() noexcept { 70 return hardware_destructive_interference_size - 71 (alignof(T) % hardware_destructive_interference_size); 72 } 73 char paddingPre_[paddingSize()]; 74 T inner_; 75 char paddingPost_[paddingSize()]; 76 }; 77 } // namespace folly 78