GemaCoreLib
The GeMA Core library
gmThreadLocalStorage.h
Go to the documentation of this file.
1 /************************************************************************
2 **
3 ** Copyright (C) 2014 by Carlos Augusto Teixera Mendes
4 ** All rights reserved.
5 **
6 ** This file is part of the "GeMA" software. It's use should respect
7 ** the terms in the license agreement that can be found together
8 ** with this source code.
9 ** It is provided AS IS, with NO WARRANTY OF ANY KIND,
10 ** INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11 ** A PARTICULAR PURPOSE.
12 **
13 ************************************************************************/
14 
24 #ifndef _GEMA_THREAD_LOCAL_STORAGE_H_
25 #define _GEMA_THREAD_LOCAL_STORAGE_H_
26 
27 #include "gmMemory.h"
28 #include "gmThreadManager.h"
29 
30 
32 template <class T, bool Align> struct GmTLS_DataT {};
33 
35 template <class T> struct GmTLS_DataT<T, false> { typedef T BaseT; T _value; };
36 
40 template <class T> struct GmTLS_DataT<T, true> { typedef T BaseT; GM_CACHE_ALIGNED T _value; };
41 
47 template <class DataT, bool Align> struct GmTLS_Alloc {};
48 
50 template <class DataT> struct GmTLS_Alloc<DataT, false>
51 {
52  static_assert(sizeof(DataT) == sizeof(typename DataT::BaseT), "Unexpected type size for unaligned GmTLS_Alloc");
53 
55  static DataT* alloc()
56  {
57  assert(GmThreadManager::maxWorkerThreads() >= 0);
58  return new DataT[GmThreadManager::maxWorkerThreads()+1];
59  }
60 
62  static void free(DataT* ptr) { delete[] ptr; }
63 };
64 
66 template <class DataT> struct GmTLS_Alloc<DataT, true>
67 {
68  static_assert(sizeof(DataT) % GM_CACHE_LINE_SIZE == 0, "Unexpected type size for aligned GmTLS_Alloc");
69 
71  static DataT* alloc()
72  {
73  assert(GmThreadManager::maxWorkerThreads() >= 0);
74 
75  int nt = GmThreadManager::maxWorkerThreads() + 1;
76  DataT* ptr = (DataT*)GmAlignedMallocThrow(nt*sizeof(DataT), GM_CACHE_LINE_SIZE);
77  assert(GmIsCacheAligned(ptr));
78 
79  // Calls, if needed, the default object constructor for each thread entry
80  GmConstructAlignedObjectsInMemory<typename DataT::BaseT>((typename DataT::BaseT*)ptr, GM_CACHE_LINE_SIZE, nt);
81  return ptr;
82  }
83 
85  static void free(DataT* ptr)
86  {
87  assert(GmThreadManager::maxWorkerThreads() >= 0);
88 
89  int nt = GmThreadManager::maxWorkerThreads() + 1;
90  GmDestroyAlignedObjectsInMemory<typename DataT::BaseT>((typename DataT::BaseT*)ptr, GM_CACHE_LINE_SIZE, nt);
91  GmAlignedFree(ptr);
92  }
93 };
94 
95 
131 template <class T, bool Align = false> class GmTLS
132 {
133 public:
134 
135  // The type used for storing data
137 
138  // The type used for allocating the stored data
140 
141  static_assert(!Align || (sizeof(DataT)%GM_CACHE_LINE_SIZE) == 0, "Unexpected type size for aligned TLS");
142 
144  GmTLS() { _data = Alloc::alloc(); }
145 
147  GmTLS(const T& defVal) { _data = Alloc::alloc(); init(defVal); }
148 
150  ~GmTLS() { Alloc::free(_data); }
151 
153  void init(const T& val)
154  {
155  for(int i = 0; i<GmThreadManager::maxWorkerThreads()+1; i++)
156  _data[i]._value = val;
157  }
158 
160  int size() const { return GmThreadManager::maxWorkerThreads() + 1; }
161 
163  T& localData(int tid)
164  {
165  assert(tid >= 0 && tid <= GmThreadManager::maxWorkerThreads());
166  return _data[tid]._value;
167  }
168 
170  const T& localData(int tid) const
171  {
172  assert(tid >= 0 && tid <= GmThreadManager::maxWorkerThreads());
173  return _data[tid]._value;
174  }
175 
178 
180  const T& localData() const { return localData(GmThreadManager::currentId()); }
181 
183  void setLocalData(int tid, const T& data) { _data[tid]._value = data; }
184 
186  void setLocalData(const T& data) { setLocalData(GmThreadManager::currentId(), data); }
187 
188 private:
189  Q_DISABLE_COPY(GmTLS)
190 
191  DataT* _data;
192 };
193 
194 #endif
#define GM_CACHE_LINE_SIZE
Cache line size. TODO: Get this from a configuration parameter.
Definition: gmMemory.h:35
void * GmAlignedMallocThrow(size_t size, size_t align)
A version of GmAlignedMalloc that throws a bad_alloc exception on failure.
Definition: gmMemory.h:65
~GmTLS()
Destructor.
Definition: gmThreadLocalStorage.h:150
A class that works together with GmThreadManager to provide thread local storage.
Definition: gmThreadLocalStorage.h:131
void setLocalData(const T &data)
Updates the current thread local data.
Definition: gmThreadLocalStorage.h:186
bool GmIsCacheAligned(void *ptr)
Checks if a pointer is cache aligned or not.
Definition: gmMemory.h:81
Declaration of the GmThreadManager class.
GmTLS(const T &defVal)
Creates a new thread local storage with values initialized to the given default value.
Definition: gmThreadLocalStorage.h:147
T & localData(int tid)
Returns the given thread local data as a modifiable reference.
Definition: gmThreadLocalStorage.h:163
GmTLS()
Creates a new thread local storage, with default constructed values.
Definition: gmThreadLocalStorage.h:144
static int currentId()
Returns the id of the current thread, which MUST be either the main thread or a thread created by the...
Definition: gmThreadManager.h:166
void init(const T &val)
Initializes the value for ALL threads with the given value.
Definition: gmThreadLocalStorage.h:153
static void free(DataT *ptr)
Releases the memory allocated by alloc.
Definition: gmThreadLocalStorage.h:62
const T & localData(int tid) const
Returns the given thread local data as a const reference.
Definition: gmThreadLocalStorage.h:170
static DataT * alloc()
Alloc a DataT vector of size equal to the number of threads + 1.
Definition: gmThreadLocalStorage.h:71
void setLocalData(int tid, const T &data)
Updates the given thread local data.
Definition: gmThreadLocalStorage.h:183
T & localData()
Returns the current thread local data as a modifiable reference.
Definition: gmThreadLocalStorage.h:177
static DataT * alloc()
Alloc a DataT vector of size equal to the number of threads + 1.
Definition: gmThreadLocalStorage.h:55
static void free(DataT *ptr)
Releases the memory allocated by alloc.
Definition: gmThreadLocalStorage.h:85
Aux structure to define the data type, cache aligned or not, for the GmTLS class.
Definition: gmThreadLocalStorage.h:32
Implementation of the custom allocator used by Armadillo when memory is needed for matrices and vecto...
int size() const
Returns the number of values stored in the TLS object. Equal to the max number of threads + 1 (for th...
Definition: gmThreadLocalStorage.h:160
const T & localData() const
Returns the current thread local data as a const reference.
Definition: gmThreadLocalStorage.h:180
static int maxWorkerThreads()
Returns the maximum number of allowed working threads.
Definition: gmThreadManager.h:153
Aux structure to define the allocation strategy for GmTLS.
Definition: gmThreadLocalStorage.h:47