32# define CPPBEGININCLUDE <
33# define CPPENDINCLUDE >
34# include CPPBEGININCLUDE./ALLOCATORHEADER CPPENDINCLUDE
35# undef CPPBEGININCLUDE
40# define ALLOCATORCLASS fmatvec::PoolAllocator
54#if defined FMATVEC_THREADSAFE_GCCBUILTIN
55 #define FMATVEC_LOCKVAR(l) short int l;
56 #define FMATVEC_LOCKINIT(l) l=0;
57 #define FMATVEC_LOCK(l) while(__sync_bool_compare_and_swap(&l, 0, 0xffff)==false);
58 #define FMATVEC_UNLOCK(l) __sync_bool_compare_and_swap(&l, 0xffff, 0);
60 #define FMATVEC_SYNCVAR(l)
61 #define FMATVEC_SYNCINIT(l)
62 #define FMATVEC_SYNCINC(var, l) __sync_add_and_fetch(&(var), 1);
63 #define FMATVEC_SYNCPREDEC(ret, var, l) ret=__sync_sub_and_fetch(&(var), 1);
64#elif defined FMATVEC_THREADSAFE_PTHREAD
67 #define FMATVEC_LOCKVAR(l) pthread_mutex_t l;
68 #define FMATVEC_LOCKINIT(l) pthread_mutex_init(&l, NULL);
69 #define FMATVEC_LOCK(l) pthread_mutex_lock(&l);
70 #define FMATVEC_UNLOCK(l) pthread_mutex_unlock(&l);
72 #define FMATVEC_SYNCVAR(l) pthread_mutex_t l;
73 #define FMATVEC_SYNCINIT(l) pthread_mutex_init(&l, NULL);
74 #define FMATVEC_SYNCINC(var, l) pthread_mutex_lock(&l); (var)++; pthread_mutex_unlock(&l);
75 #define FMATVEC_SYNCPREDEC(ret, var, l) pthread_mutex_lock(&l); ret=--(var); pthread_mutex_unlock(&l);
76#elif defined FMATVEC_THREADSAFE_OPENMP
77 #define FMATVEC_PRAGMA(x) _Pragma(#x)
79 #define FMATVEC_LOCKVAR(l)
80 #define FMATVEC_LOCKINIT(l)
81 #define FMATVEC_LOCK(l) FMATVEC_PRAGMA(omp critical (l)) {
82 #define FMATVEC_UNLOCK(l) }
84 #define FMATVEC_SYNCVAR(l)
85 #define FMATVEC_SYNCINIT(l)
86 #define FMATVEC_SYNCINC(var, l) FMATVEC_PRAGMA(omp critical (l)) { (var)++; }
87 #define FMATVEC_SYNCPREDEC(ret, var, l) FMATVEC_PRAGMA(omp critical (l)) { ret=--(var); }
89 #define FMATVEC_PRAGMA(l)
90 #define FMATVEC_LOCKVAR(l)
91 #define FMATVEC_LOCKINIT(l)
92 #define FMATVEC_LOCK(l)
93 #define FMATVEC_UNLOCK(l)
95 #define FMATVEC_SYNCVAR(l)
96 #define FMATVEC_SYNCINIT(l)
97 #define FMATVEC_SYNCINC(var, l) (var)++;
98 #define FMATVEC_SYNCPREDEC(ret, var, l) ret=--(var);
113 class PoolAllocator {
116 static const size_t MINEXP=4;
120 std::vector<std::vector<AT*>> memoryPool;
123 FMATVEC_LOCKVAR(fmatvec_memoryPoolLock)
126 PoolAllocator() : memoryPool(1) {
127 FMATVEC_LOCKINIT(fmatvec_memoryPoolLock)
132 for(
typename std::vector<std::vector<AT*>>::iterator i=memoryPool.begin(); i!=memoryPool.end(); ++i)
133 for(
typename std::vector<AT*>::iterator j=i->begin(); j!=i->end(); ++j)
137 AT *allocate(
size_t size) {
139 if(size==0)
return &sizeZero;
143 while(size>>=1) ++index;
145 FMATVEC_LOCK(fmatvec_memoryPoolLock)
147 if(index>=memoryPool.size()) memoryPool.resize(index<<1);
149 std::vector<AT*> &memoryPoolIndex=memoryPool[index];
150 if(memoryPoolIndex.size()>0) {
151 ret=memoryPoolIndex.back();
152 memoryPoolIndex.pop_back();
154 FMATVEC_UNLOCK(fmatvec_memoryPoolLock)
157 return new AT[1<<(index+MINEXP)];
160 void deallocate(AT *p,
size_t size) {
166 while(size>>=1) ++index;
167 FMATVEC_LOCK(fmatvec_memoryPoolLock)
169 memoryPool[index].push_back(p);
170 FMATVEC_UNLOCK(fmatvec_memoryPoolLock)
174#ifdef MEMORYCLASS_FMATVEC
177 template <
class AT>
class Memory {
179 typedef ALLOCATORCLASS<AT> allocator_type;
182 static allocator_type ms;
184 FMATVEC_SYNCVAR(fmatvec_refLock)
186 FMATVEC_SYNCINC(*ref, fmatvec_refLock)
190 FMATVEC_SYNCPREDEC(refLocal, *ref, fmatvec_refLock)
192 ms.deallocate(ele0, sz);
198 Memory() : sz(0), ele0(0), ref(new size_t(1)) {
199 FMATVEC_SYNCINIT(fmatvec_refLock);
202 Memory(
size_t n) : sz(n), ele0(ms.allocate(sz)), ref(new size_t(1)){
203 FMATVEC_SYNCINIT(fmatvec_refLock);
206 Memory(
const Memory &memory) : sz(memory.sz), ele0(memory.ele0), ref(memory.ref) {
207 FMATVEC_SYNCINIT(fmatvec_refLock);
215 Memory& operator=(
const Memory &memory) {
218 unlock(); sz=memory.sz; ref=memory.ref; ele0=memory.ele0; lock();
222 void resize(
size_t n) {
226 ele0 = ms.allocate(sz);
229 AT* get()
const {
return ele0;}
232#elif defined MEMORYCLASS_STDSHAREDPTR
236 template <
class AT>
class Memory {
243 Memory(
size_t n) : ele0(new AT[n]) {}
245 Memory(
const Memory &memory) : ele0(memory.ele0) {}
249 Memory& operator=(
const Memory &memory) {
256 void resize(
size_t n) {
257 ele0.reset(
new AT[n]);
260 AT* get()
const {
return ele0.get();}
269 template <
class AT>
class Memory {
271 static const size_t ele0Start=(
sizeof(size_t)-1)/
sizeof(AT)+1;
274 FMATVEC_SYNCVAR(fmatvec_refLock)
277 FMATVEC_SYNCINC(*ref, fmatvec_refLock)
283 #pragma GCC diagnostic push
284 #pragma GCC diagnostic ignored "-Wuse-after-free"
287 FMATVEC_SYNCPREDEC(refLocal, *ref, fmatvec_refLock)
289 delete[]
reinterpret_cast<AT*
>(ref);
292 #pragma GCC diagnostic pop
297 Memory() : ref(reinterpret_cast<size_t*>(new AT[ele0Start])), ele0(nullptr) {
299 FMATVEC_SYNCINIT(fmatvec_refLock);
302 Memory(
size_t n) : ref(reinterpret_cast<size_t*>(new AT[ele0Start+n])), ele0(reinterpret_cast<AT*>(ref)+ele0Start) {
304 FMATVEC_SYNCINIT(fmatvec_refLock);
307 Memory(
const Memory &memory) : ref(memory.ref), ele0(memory.ele0) {
308 FMATVEC_SYNCINIT(fmatvec_refLock);
316 Memory& operator=(
const Memory &memory) {
319 unlock(); ref=memory.ref; ele0=memory.ele0; lock();
323 void resize(
size_t n) {
325 ref=
reinterpret_cast<size_t*
>(
new AT[ele0Start+n]);
326 ele0=
reinterpret_cast<AT*
>(ref)+ele0Start;
330 AT* get()
const {
return ele0;}
Namespace fmatvec.
Definition: _memory.cc:28