GemaCoreLib
The GeMA Core library
gmThreadLocalBuffer.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_BUFFER_H_
25 #define _GEMA_THREAD_LOCAL_BUFFER_H_
26 
27 #include "gmMemory.h"
28 #include "gmThreadLocalStorage.h"
29 
30 
32 template <class T, bool Align> struct GmTLBuffer_Alloc {};
33 
35 template <class T> struct GmTLBuffer_Alloc<T, false>
36 {
38  static void alloc(int n, GmTLS<T*>& tls)
39  {
40  assert(GmThreadManager::maxWorkerThreads() >= 0);
41 
42  int nt = GmThreadManager::maxWorkerThreads() + 1; // +1 for the main thread
43 
44  T* buffer = new T[n * nt];
45  for(int i = 0; i < nt; i++, buffer += n)
46  tls.setLocalData(i, buffer);
47  }
48 
50  static void free(int n, GmTLS<T*>& tls) { Q_UNUSED(n); delete[] tls.localData(0); }
51 };
52 
54 template <class T> struct GmTLBuffer_Alloc<T, true>
55 {
57  static void alloc(int n, GmTLS<T*>& tls)
58  {
59  assert(GmThreadManager::maxWorkerThreads() >= 0);
60 
61  int nt = GmThreadManager::maxWorkerThreads() + 1; // +1 for the main thread
62  int tsize = ceil((n*sizeof(T))/(double)GM_CACHE_LINE_SIZE) * GM_CACHE_LINE_SIZE;
63 
64  // Alloc space
65  char* rawbuffer = (char*)GmAlignedMallocThrow(nt * tsize, GM_CACHE_LINE_SIZE);
66 
67  // Store pointers
68  for(int i = 0; i < nt; i++)
69  {
70  T* ptr = (T*)(rawbuffer + i*tsize);
71  assert(GmIsCacheAligned(ptr));
72 
73  tls.setLocalData(i, ptr);
74  GmConstructObjectsInMemory<T>(ptr, n); // Calls, if needed, the default object constructor for each buffer entry
75  }
76  }
77 
79  static void free(int n, GmTLS<T*>& tls)
80  {
81  assert(GmThreadManager::maxWorkerThreads() >= 0);
82 
83  int nt = GmThreadManager::maxWorkerThreads() + 1; // +1 for the main thread
84  for(int i = 0; i<nt; i++)
85  GmDestroyObjectsInMemory<T>(tls.localData(i), n);
86 
87  GmAlignedFree(tls.localData(0));
88  }
89 };
90 
105 template <class T, bool Align = false> class GmTLBuffer
106 {
107 public:
108 
109  // The type used for allocating the stored data
110  typedef GmTLBuffer_Alloc<T, Align> Alloc;
111 
113  GmTLBuffer() : _data(NULL), _n(0) {}
114 
116  GmTLBuffer(int n) { assert(n > 0); Alloc::alloc(n, _data); _n = n; }
117 
119  GmTLBuffer(int n, const T& defVal) { assert(n > 0); Alloc::alloc(n, _data); _n = n; init(defVal); }
120 
122  ~GmTLBuffer() { if(_n) Alloc::free(_n, _data); }
123 
125  void clear() { if(_n) { Alloc::free(_n, _data); _n = 0; _data.init(NULL); } }
126 
128  int size() const { return _n; }
129 
131  void setSize(int n) { assert(_n == 0); Alloc::alloc(n, _data); _n = n; }
132 
134  void setSize(int n, const T& defVal) { setSize(n); init(defVal); }
135 
137  void resize(int n) { if(n != _n) { clear(); setSize(n); } }
138 
140  T* localBuffer(int tid) { return _data.localData(tid); }
141 
143  const T* localBuffer(int tid) const { return _data.localData(tid); }
144 
147 
149  const T* localBuffer() const { return _data.localData(GmThreadManager::currentId()); }
150 
152  void init(const T& defVal)
153  {
154  for(int i = 0; i < GmThreadManager::maxWorkerThreads() + 1; i++)
155  {
156  T* ptr = _data.localData(i);
157  for(int j = 0; j < _n; j++)
158  ptr[j] = defVal;
159  }
160  }
161 
162 private:
163  Q_DISABLE_COPY(GmTLBuffer)
164 
165 
169  GmTLS<T*> _data;
170 
171  int _n;
172 };
173 
174 
175 #endif
#define GM_CACHE_LINE_SIZE
Cache line size. TODO: Get this from a configuration parameter.
Definition: gmMemory.h:35
void setSize(int n, const T &defVal)
Set buffer size for a default constructed buffer and initializes the contents to defVal.
Definition: gmThreadLocalBuffer.h:134
void * GmAlignedMallocThrow(size_t size, size_t align)
A version of GmAlignedMalloc that throws a bad_alloc exception on failure.
Definition: gmMemory.h:65
Declaration of the GmTLS class.
A class similar to GmTLS that creates a buffer for each possible thread in the GmThreadManager,...
Definition: gmValueSetData.h:43
GmTLBuffer(int n)
Constructor. Each thread buffer will store n entries of type T.
Definition: gmThreadLocalBuffer.h:116
int _n
The size of each buffer.
Definition: gmThreadLocalBuffer.h:171
static void alloc(int n, GmTLS< T * > &tls)
Alloc one buffer with size n for each thread, storing pointers in tls.
Definition: gmThreadLocalBuffer.h:38
void clear()
Clears the allocated buffers returning the object to a default constructed state.
Definition: gmThreadLocalBuffer.h:125
T * localBuffer(int tid)
Returns a pointer to the given thread local buffer.
Definition: gmThreadLocalBuffer.h:140
bool GmIsCacheAligned(void *ptr)
Checks if a pointer is cache aligned or not.
Definition: gmMemory.h:81
T * localBuffer()
Returns a pointer to the current thread local buffer.
Definition: gmThreadLocalBuffer.h:146
const T * localBuffer() const
Returns a const pointer to the current thread local buffer.
Definition: gmThreadLocalBuffer.h:149
~GmTLBuffer()
Destructor.
Definition: gmThreadLocalBuffer.h:122
T & localData(int tid)
Returns the given thread local data as a modifiable reference.
Definition: gmThreadLocalStorage.h:163
const T * localBuffer(int tid) const
Returns a const pointer to the given thread local buffer.
Definition: gmThreadLocalBuffer.h:143
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 alloc(int n, GmTLS< T * > &tls)
Alloc one cache aligned buffer with size n for each thread, storing pointers in tls.
Definition: gmThreadLocalBuffer.h:57
GmTLBuffer()
Default constructor. Buffer sizes MUST be initialized by a call to setSize()
Definition: gmThreadLocalBuffer.h:113
void setLocalData(int tid, const T &data)
Updates the given thread local data.
Definition: gmThreadLocalStorage.h:183
Aux structure to define the allocation strategy for GmTLBuffer.
Definition: gmThreadLocalBuffer.h:32
int size() const
Returns the buffer size.
Definition: gmThreadLocalBuffer.h:128
GmTLBuffer(int n, const T &defVal)
Constructor. Each thread buffer will store n entries of type T, initialized to defVal.
Definition: gmThreadLocalBuffer.h:119
static void free(int n, GmTLS< T * > &tls)
Releases the memory allocated by alloc.
Definition: gmThreadLocalBuffer.h:79
Implementation of the custom allocator used by Armadillo when memory is needed for matrices and vecto...
GmTLS< T * > _data
The local storage with pointers to each thread buffer. No need to align _data since worker threads wi...
Definition: gmThreadLocalBuffer.h:169
static void free(int n, GmTLS< T * > &tls)
Releases the memory allocated by alloc.
Definition: gmThreadLocalBuffer.h:50
void init(const T &defVal)
Initializes each buffer entry to defVal.
Definition: gmThreadLocalBuffer.h:152
static int maxWorkerThreads()
Returns the maximum number of allowed working threads.
Definition: gmThreadManager.h:153
void resize(int n)
Change buffer size.
Definition: gmThreadLocalBuffer.h:137
void setSize(int n)
Set buffer size for a default constructed buffer.
Definition: gmThreadLocalBuffer.h:131