30 #ifdef ALLOCATORHEADER
31 # define CPPBEGININCLUDE <
32 # define CPPENDINCLUDE >
33 # include CPPBEGININCLUDE./ALLOCATORHEADER CPPENDINCLUDE
34 # undef CPPBEGININCLUDE
38 #ifndef ALLOCATORCLASS
39 # define ALLOCATORCLASS fmatvec::PoolAllocator
53 #if defined FMATVEC_THREADSAFE_GCCBUILTIN
54 #define FMATVEC_LOCKVAR(l) short int l;
55 #define FMATVEC_LOCKINIT(l) l=0;
56 #define FMATVEC_LOCK(l) while(__sync_bool_compare_and_swap(&l, 0, 0xffff)==false);
57 #define FMATVEC_UNLOCK(l) __sync_bool_compare_and_swap(&l, 0xffff, 0);
59 #define FMATVEC_SYNCVAR(l)
60 #define FMATVEC_SYNCINIT(l)
61 #define FMATVEC_SYNCINC(var, l) __sync_add_and_fetch(&(var), 1);
62 #define FMATVEC_SYNCPREDEC(ret, var, l) ret=__sync_sub_and_fetch(&(var), 1);
63 #elif defined FMATVEC_THREADSAFE_PTHREAD
66 #define FMATVEC_LOCKVAR(l) pthread_mutex_t l;
67 #define FMATVEC_LOCKINIT(l) pthread_mutex_init(&l, NULL);
68 #define FMATVEC_LOCK(l) pthread_mutex_lock(&l);
69 #define FMATVEC_UNLOCK(l) pthread_mutex_unlock(&l);
71 #define FMATVEC_SYNCVAR(l) pthread_mutex_t l;
72 #define FMATVEC_SYNCINIT(l) pthread_mutex_init(&l, NULL);
73 #define FMATVEC_SYNCINC(var, l) pthread_mutex_lock(&l); (var)++; pthread_mutex_unlock(&l);
74 #define FMATVEC_SYNCPREDEC(ret, var, l) pthread_mutex_lock(&l); ret=--(var); pthread_mutex_unlock(&l);
75 #elif defined FMATVEC_THREADSAFE_OPENMP
76 #define FMATVEC_PRAGMA(x) _Pragma(#x) // openmp required the _Pragma operator (defined by C99)
78 #define FMATVEC_LOCKVAR(l)
79 #define FMATVEC_LOCKINIT(l)
80 #define FMATVEC_LOCK(l) FMATVEC_PRAGMA(omp critical (l)) {
81 #define FMATVEC_UNLOCK(l) }
83 #define FMATVEC_SYNCVAR(l)
84 #define FMATVEC_SYNCINIT(l)
85 #define FMATVEC_SYNCINC(var, l) FMATVEC_PRAGMA(omp critical (l)) { (var)++; }
86 #define FMATVEC_SYNCPREDEC(ret, var, l) FMATVEC_PRAGMA(omp critical (l)) { ret=--(var); }
88 #define FMATVEC_PRAGMA(l)
89 #define FMATVEC_LOCKVAR(l)
90 #define FMATVEC_LOCKINIT(l)
91 #define FMATVEC_LOCK(l)
92 #define FMATVEC_UNLOCK(l)
94 #define FMATVEC_SYNCVAR(l)
95 #define FMATVEC_SYNCINIT(l)
96 #define FMATVEC_SYNCINC(var, l) (var)++;
97 #define FMATVEC_SYNCPREDEC(ret, var, l) ret=--(var);
100 #if defined MEMORYCLASS_BOOST
101 # include <boost/shared_array.hpp>
116 class PoolAllocator {
119 static const size_t MINEXP=4;
123 std::vector<std::vector<AT*> > memoryPool;
126 FMATVEC_LOCKVAR(fmatvec_memoryPoolLock)
129 PoolAllocator() : memoryPool(1) {
130 FMATVEC_LOCKINIT(fmatvec_memoryPoolLock)
135 for(
typename std::vector<std::vector<AT*> >::iterator i=memoryPool.begin(); i!=memoryPool.end(); ++i)
136 for(
typename std::vector<AT*>::iterator j=i->begin(); j!=i->end(); ++j)
140 AT *allocate(
size_t size) {
142 if(size==0)
return &sizeZero;
146 while(size>>=1) ++index;
148 FMATVEC_LOCK(fmatvec_memoryPoolLock)
150 if(index>=memoryPool.size()) memoryPool.resize(index<<1);
152 std::vector<AT*> &memoryPoolIndex=memoryPool[index];
153 if(memoryPoolIndex.size()>0) {
154 ret=memoryPoolIndex.back();
155 memoryPoolIndex.pop_back();
157 FMATVEC_UNLOCK(fmatvec_memoryPoolLock)
160 return new AT[1<<(index+MINEXP)];
163 void deallocate(AT *p,
size_t size) {
169 while(size>>=1) ++index;
170 FMATVEC_LOCK(fmatvec_memoryPoolLock)
172 memoryPool[index].push_back(p);
173 FMATVEC_UNLOCK(fmatvec_memoryPoolLock)
181 #ifdef MEMORYCLASS_FMATVEC
184 template <
class AT>
class Memory {
186 typedef ALLOCATORCLASS<AT> allocator_type;
189 static allocator_type ms;
191 FMATVEC_SYNCVAR(fmatvec_refLock)
193 FMATVEC_SYNCINC(*ref, fmatvec_refLock)
197 FMATVEC_SYNCPREDEC(refLocal, *ref, fmatvec_refLock)
199 ms.deallocate(ele0, sz);
205 Memory() : sz(0), ele0(0), ref(new size_t(1)) {
206 FMATVEC_SYNCINIT(fmatvec_refLock);
209 Memory(
size_t n) : sz(n), ele0(ms.allocate(sz)), ref(new size_t(1)){
210 FMATVEC_SYNCINIT(fmatvec_refLock);
213 Memory(
const Memory &memory) : sz(memory.sz), ele0(memory.ele0), ref(memory.ref) {
214 FMATVEC_SYNCINIT(fmatvec_refLock);
222 Memory& operator=(
const Memory &memory) {
225 unlock(); sz=memory.sz; ref=memory.ref; ele0=memory.ele0; lock();
229 void resize(
size_t n) {
233 ele0 = ms.allocate(sz);
236 AT*
get()
const {
return ele0;};
239 #elif defined MEMORYCLASS_BOOST
243 template <
class AT>
class Memory {
245 boost::shared_array<AT> ele0;
248 Memory() : ele0() {};
250 Memory(
size_t n) : ele0(new AT[n]) {};
252 Memory(
const Memory &memory) : ele0(memory.ele0) {};
256 Memory& operator=(
const Memory &memory) {
263 void resize(
size_t n) {
264 ele0.reset(
new AT[n]);
267 AT*
get()
const {
return ele0.get();};
276 template <
class AT>
class Memory {
278 static const size_t ele0Start=(
sizeof(size_t)-1)/
sizeof(AT)+1;
281 FMATVEC_SYNCVAR(fmatvec_refLock)
284 FMATVEC_SYNCINC(*ref, fmatvec_refLock)
289 FMATVEC_SYNCPREDEC(refLocal, *ref, fmatvec_refLock)
291 delete[]
reinterpret_cast<AT*
>(ref);
296 Memory() : ref(reinterpret_cast<size_t*>(new AT[ele0Start])), ele0(NULL) {
298 FMATVEC_SYNCINIT(fmatvec_refLock);
301 Memory(
size_t n) : ref(reinterpret_cast<size_t*>(new AT[ele0Start+n])), ele0(reinterpret_cast<AT*>(ref)+ele0Start) {
303 FMATVEC_SYNCINIT(fmatvec_refLock);
306 Memory(
const Memory &memory) : ref(memory.ref), ele0(memory.ele0) {
307 FMATVEC_SYNCINIT(fmatvec_refLock);
315 Memory& operator=(
const Memory &memory) {
318 unlock(); ref=memory.ref; ele0=memory.ele0; lock();
322 void resize(
size_t n) {
324 ref=
reinterpret_cast<size_t*
>(
new AT[ele0Start+n]);
325 ele0=
reinterpret_cast<AT*
>(ref)+ele0Start;
329 AT*
get()
const {
return ele0;};