1 /** 2 * 3 * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_AMU) 4 * info_at_agrum_dot_org 5 * 6 * This library is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 22 /** @file 23 * @brief A wrapper that enables to store data in a way that prevents false 24 * cacheline sharing. 25 * 26 * @author Christophe GONZALES(_at_AMU) and Pierre-Henri WUILLEMIN(_at_LIP6) 27 */ 28 #ifndef GUM_THREAD_DATA_H 29 #define GUM_THREAD_DATA_H 30 31 #include <new> 32 33 #include <agrum/agrum.h> 34 35 namespace gum { 36 37 /** @class ThreadData 38 * @brief A wrapper that enables to store data in a way that prevents false 39 * cacheline sharing. 40 * @headerfile threadData.h <agrum/tools/core/threadData.h> 41 * @ingroup basicstruct_group 42 * 43 * When several threads access to some shared containers like vectors, it 44 * may be the case that they access some data within these containers that 45 * are too close, which results in false sharing of the cacheline. By 46 * wrapping the data into a ThreadData, we guarantee that no false sharing 47 * can occur. 48 * 49 * To create a wrapper data, simply use wrapped_data = ThreadData (data) and 50 * To get the data wrapped, use wrapped_data.data; 51 */ 52 template < typename T_DATA > 53 // @TODO: for C++17, replace by 54 // alignas(std::hardware_destructive_interference_size) 55 struct alignas(128) ThreadData { 56 // ########################################################################## 57 /// @name Constructors / Destructors 58 // ########################################################################## 59 /// @{ 60 61 /// default constructor ThreadDataThreadData62 ThreadData(const T_DATA& theData) : data(theData) {} 63 64 /// default constructor ThreadDataThreadData65 ThreadData(T_DATA&& theData) : data(std::move(theData)) {} 66 67 /// copy constructor ThreadDataThreadData68 ThreadData(const ThreadData< T_DATA >& from) : data(from.data) {} 69 70 /// move constructor ThreadDataThreadData71 ThreadData(ThreadData< T_DATA >&& from) : data(std::move(from.data)) {} 72 73 /// destructor ~ThreadDataThreadData74 ~ThreadData() {} 75 76 /// @} 77 78 // ########################################################################## 79 /// @name Operators 80 // ########################################################################## 81 82 /// @{ 83 84 /// copy operator 85 ThreadData< T_DATA >& operator=(const ThreadData< T_DATA >& from) { 86 if (this != &from) data = from.data; 87 return *this; 88 } 89 90 /// move operator 91 ThreadData< T_DATA >& operator=(ThreadData< T_DATA >&& from) { 92 data = std::move(from.data); 93 return *this; 94 } 95 96 /// @} 97 98 /// the data we wish to store without cacheline parallel problem 99 T_DATA data; 100 }; 101 102 } /* namespace gum */ 103 104 #endif /* GUM_THREAD_DATA_H */ 105