1 /* 2 * Copyright (c) 2014-2017, Siemens AG. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef EMBB_BASE_THREAD_SPECIFIC_STORAGE_H_ 28 #define EMBB_BASE_THREAD_SPECIFIC_STORAGE_H_ 29 30 #include <embb/base/c/thread_specific_storage.h> 31 #include <embb/base/c/internal/thread_index.h> 32 #include <embb/base/exceptions.h> 33 34 namespace embb { 35 namespace base { 36 37 namespace test { 38 /** 39 * Forward declaration for friending. 40 */ 41 class ThreadSpecificStorageTest; 42 } 43 44 /** 45 * \defgroup CPP_BASE_TSS Thread-Specific Storage 46 * 47 * %Thread specific storage. 48 * 49 * \ingroup CPP_BASE 50 */ 51 52 /** 53 * Represents thread-specific storage (TSS). 54 * 55 * Provides for each thread a separate slot storing an object of the given type. 56 * 57 * \tparam Type Type of the objects 58 * \ingroup CPP_BASE_TSS 59 */ 60 template<typename Type> 61 class ThreadSpecificStorage { 62 public: 63 /** 64 * Creates the TSS and default initializes all slots. 65 * 66 * \throws NoMemoryException if not enough memory is available to allocate 67 * the TSS slots 68 * \memory Dynamically allocates embb::base::Thread::GetThreadsMaxCount() 69 * pointers and slots of the TSS type 70 * \notthreadsafe 71 */ 72 ThreadSpecificStorage(); 73 74 #ifdef DOXYGEN 75 /** 76 * Creates the TSS and initializes all slots with up to four constructor 77 * arguments. 78 * 79 * The TSS objects are created by calling their constructor as follows: 80 * Type(initializer1, ...). 81 * 82 * \throws NoMemoryException if not enough memory is available to allocate 83 * the TSS slots 84 * \memory Dynamically allocates embb::base::Thread::GetThreadsMaxCount() 85 * pointers and slots of the TSS type 86 * \notthreadsafe 87 */ 88 template<typename Initializer1, ...> 89 explicit ThreadSpecificStorage( 90 Initializer1 initializer1, 91 /**< [IN] First argument for constructor\n ... */ 92 ... 93 ); 94 #else 95 /** 96 * See description of Doxygen variadic constructor above. 97 */ 98 template<typename Initializer> 99 explicit ThreadSpecificStorage(Initializer initializer); 100 101 /** 102 * See description of Doxygen variadic constructor above. 103 */ 104 template<typename Initializer1, typename Initializer2> 105 ThreadSpecificStorage(Initializer1 initializer1, Initializer2 initializer2); 106 107 /** 108 * See description of Doxygen variadic constructor above. 109 */ 110 template<typename Initializer1, typename Initializer2, typename Initializer3> 111 ThreadSpecificStorage(Initializer1 initializer1, Initializer2 initializer2, 112 Initializer3 initializer3); 113 114 /** 115 * See description of Doxygen variadic constructor above. 116 */ 117 template<typename Initializer1, typename Initializer2, typename Initializer3, 118 typename Initializer4> 119 ThreadSpecificStorage(Initializer1 initializer1, Initializer2 initializer2, 120 Initializer3 initializer3, Initializer4 initializer4); 121 #endif // else defined(DOXYGEN) 122 123 /** 124 * Destroys the TSS and frees allocated memory for the TSS slots. 125 */ 126 ~ThreadSpecificStorage(); 127 128 /** 129 * Returns a reference to the TSS slot of the current thread. 130 * 131 * \return Reference to TSS slot 132 * 133 * \throws embb::base::ErrorException if the maximum number of threads has 134 * been exceeded 135 * \lockfree 136 * \see Get() const 137 */ 138 Type& Get(); 139 140 /** 141 * Returns a const reference to the TSS slot of the current thread. 142 * 143 * \return Constant reference to TSS slot 144 * 145 * \throws embb::base::ErrorException if the maximum number of threads has 146 * been exceeded 147 * \lockfree 148 * \see Get() 149 */ 150 const Type& Get() const; 151 152 private: 153 /** 154 * Common construction code. 155 */ 156 void Prepare(); 157 158 /** 159 * Representation of TSS implemented in Base C. 160 */ 161 embb_tss_t rep_; 162 163 /** 164 * Flags to indicate the usage of a TSS value. Are set on first access. 165 */ 166 bool* usage_flags_; 167 168 /** 169 * To allow white-box tests. 170 */ 171 friend class test::ThreadSpecificStorageTest; 172 }; 173 174 } // namespace base 175 } // namespace embb 176 177 #include <embb/base/internal/thread_specific_storage-inl.h> 178 179 #endif // EMBB_BASE_THREAD_SPECIFIC_STORAGE_H_ 180