ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ObjectPool.h
Go to the documentation of this file.
1
52#ifndef ETISS_OBJECTPOOL_H_
53#define ETISS_OBJECTPOOL_H_
54
55#include "etiss/Misc.h"
57
58#include <cstring>
59
60#define ETISS_OBJECTPOOL_LOGSIZE 1
61#define ETISS_OBJECTPOOL_DBG_OBJLIMIT 0 // set to 0 to disable
62
63namespace etiss
64{
65
66template <typename T, size_t prealloc_inc = 100>
67class ObjectPool;
68
69namespace internal
70{
71// functions to set a pointer from object to memory pool if object inherited
72// RefCounted Object
73template <typename T>
75typename std::enable_if<!std::is_base_of<etiss::RefCountedObject<ObjectPool<T>>, T>::value, void>::type
79template <typename T>
80typename std::enable_if<std::is_base_of<etiss::RefCountedObject<ObjectPool<T>>, T>::value, void>::type
82{
83 etiss::helper_allocator_ptr_ref<T, ObjectPool<T>>(obj) = this_;
84}
85} // namespace internal
86
87// patch missing alignof support for msvc
88#ifdef _MSC_VER
89#define alignof(x) __alignof(x)
90#endif
92template <typename T, size_t prealloc_inc>
98{
99 public:
100 const size_t blocksize_;
101
102 private:
103 std::set<void *> areas_;
104 std::vector<void *> empty_;
105
106 public:
107 typedef T value_type;
108 typedef T *pointer;
109 typedef const T *const_pointer;
110 typedef T &reference;
111 typedef const T &const_reference;
112
113 typedef typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;
114
115 private:
116 storage stackstore[prealloc_inc]; // small (fast) possibly stack allocation of the first elements
118
119 public:
120 template <class Type>
121 struct rebind
122 {
124 };
125
126 ObjectPool(size_t blockElementCount = 5000) : blocksize_(blockElementCount), stackstore_used(false) {}
128 template <class U>
133 {
134 // no other cleanup must be preformed since all allocated objects are required to be destroyed prior to this
135 // destruction
136 for (auto iter = areas_.begin(); iter != areas_.end(); ++iter)
137 if (*iter != stackstore)
138 delete[](storage *)(*iter);
139 }
140
141 T *address(T &x) const { return &x; }
142 const T *address(const T &x) const { return &x; }
143 T *allocate(size_t n = 1, const T * = 0)
144 {
145 if (unlikely(n <= 0))
146 throw std::bad_alloc();
147 if (unlikely(n > 1)) // fall back to simple malloc call
148 {
149 return (T *)new storage[n];
150 }
151 else
152 {
153 if (unlikely(empty_.empty()))
154 {
155 if (!stackstore_used)
156 {
157 stackstore_used = true;
158 for (size_t i = 0; i < prealloc_inc; ++i)
159 {
160 empty_.push_back((void *)(&(stackstore[i])));
161 }
162 }
163 else
164 {
165 storage *area = new storage[blocksize_];
166 if (area == 0)
167 throw std::bad_alloc();
168 areas_.insert(area);
169#if ETISS_OBJECTPOOL_DBG_OBJLIMIT
171 throw new std::bad_alloc();
172#endif
173 for (size_t i = 0; i < blocksize_; ++i)
174 {
175 empty_.push_back((void *)(&(area[i])));
176 }
177#if ETISS_OBJECTPOOL_LOGSIZE
178 // etiss::log(etiss::VERBOSE,"ObjectPool increased size",areas_.size()*blocksize_+100);
179#endif
180 }
181 }
182 void *area = empty_.back();
183 empty_.pop_back();
184 return (T *)area;
185 }
186 }
187 void deallocate(T *p, size_t n = 1)
188 {
189 if (unlikely(p == 0))
190 return;
191 if (unlikely(n <= 0))
192 throw std::bad_alloc();
193 if (unlikely(n > 1))
194 {
195 delete[](storage *) p;
196 }
197 else
198 {
199 empty_.push_back(p);
200 }
201 }
202 size_t max_size() const { return (size_t)-1; }
203 template <class U, class... Args>
204 void construct(U *p, Args &&... args)
205 {
206 ::new ((void *)p) U(std::forward<Args>(args)...);
207 etiss::internal::ObjectPool_setAllocatorPointer<T>((T *)p, this);
208 }
209 template <class U>
210 void destroy(U *p)
211 {
212 p->~U();
213 }
214};
215
216template <typename T>
217typename std::enable_if<std::is_base_of<etiss::RefCountedObject<ObjectPool<T>>, T>::value, bool>::type decRef(T *ptr)
218{
219 bool ret = helper_decRef<T, typename T::refcount_allocatorT>(ptr);
220 if (ret)
221 {
222 ObjectPool<T> *&pool = etiss::helper_allocator_ptr_ref<T, typename T::refcount_allocatorT>(ptr);
223#if DEBUG
224 if (pool == 0)
225 throw std::bad_alloc();
226#endif
227 pool->destroy(ptr);
228 pool->deallocate(ptr);
229 ptr = 0;
230 }
231 return ret;
232}
233
240template <typename T, size_t stackallocatedsize = 1>
242{
243 static_assert(std::is_pod<T>::value, "ExpandingNativeStack can only handle types without constructor/destructor. "
244 "This cannot be fullfilled by non POD objects");
245
246 private:
247 T stackbuf_[stackallocatedsize > 0 ? stackallocatedsize : 1]; // must be >0 to conform to c++ standard
249 size_t size_;
250 ssize_t pos_;
251
252 public:
253 ExpandingNativeStack() : stack_(stackbuf_), size_(stackallocatedsize > 0 ? stackallocatedsize : 1), pos_(-1) {}
255 {
256 if (stack_ != stackbuf_)
257 delete stack_;
258 }
259 inline T operator[](ssize_t pos)
260 {
261#if DEBUG
262 if (unlikely((pos >= size_) || pos < 0))
263 etiss::log(etiss::FATALERROR, "Array index out of bounds", pos, ETISS_SRCLOC);
264#endif
265 return stack_[pos];
266 }
267 inline const T operator[](size_t pos) const
268 {
269#if DEBUG
270 if (unlikely((pos >= size_) || pos < 0))
271 etiss::log(etiss::FATALERROR, "Array index out of bounds", pos, ETISS_SRCLOC);
272#endif
273 return stack_[pos];
274 }
275 inline ssize_t pos() const { return pos_; }
276 inline ssize_t size() const { return pos_ + 1; }
277 inline ssize_t capacity() const { return size_; }
278 inline T &back() { return stack_[pos_]; }
279 inline const T &back() const { return stack_[pos_]; }
280 inline T &front() { return stack_[0]; }
281 inline const T &front() const { return stack_[0]; }
282 inline void pop()
283 {
284#if DEBUG
285 if (unlikely(pos_ < 0))
286 etiss::log(etiss::FATALERROR, "Array index out of bounds (negative)", ETISS_SRCLOC);
287#endif
288 --pos_;
289 }
290 inline void push(T t)
291 {
292 if (unlikely((++pos_) == (ssize_t)size_)) // reached end of old stack
293 {
294 size_t new_size = size_ + 10 + (size_ / 20); // increase stack size
295 T *tmp = new T[new_size]; // allocate new stack
296 memcpy(tmp, stack_, size_ * sizeof(T)); // copy old elements
297 if (stack_ != stackbuf_)
298 delete[] stack_;
299 stack_ = tmp;
300 size_ = new_size;
301 }
302 stack_[pos_] = t;
303 }
304 inline bool empty() const { return pos_ < 0; }
305};
306
307} // namespace etiss
308
309#endif
general configuration and logging
#define ETISS_SRCLOC
Definition Misc.h:239
#define ETISS_OBJECTPOOL_DBG_OBJLIMIT
Definition ObjectPool.h:61
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
#define unlikely(x)
Definition types.h:74
implements a stack that may only grow (if needed) and can only contain native types since no destruct...
Definition ObjectPool.h:242
const T operator[](size_t pos) const
Definition ObjectPool.h:267
T stackbuf_[stackallocatedsize > 0 ? stackallocatedsize :1]
Definition ObjectPool.h:247
const T & front() const
Definition ObjectPool.h:281
const T & back() const
Definition ObjectPool.h:279
prealloc_inc defines the number of objects that is availabe within ObjectPools memory; default: 100
Definition ObjectPool.h:98
const T & const_reference
Definition ObjectPool.h:111
T * address(T &x) const
Definition ObjectPool.h:141
std::set< void * > areas_
Definition ObjectPool.h:103
ObjectPool(size_t blockElementCount=5000)
Definition ObjectPool.h:126
ObjectPool(const ObjectPool &alloc)
Definition ObjectPool.h:127
const T * const_pointer
Definition ObjectPool.h:109
std::aligned_storage< sizeof(T), alignof(T)>::type storage
Definition ObjectPool.h:113
storage stackstore[prealloc_inc]
Definition ObjectPool.h:116
ObjectPool(const ObjectPool< U > &alloc)
Definition ObjectPool.h:129
size_t max_size() const
Definition ObjectPool.h:202
void construct(U *p, Args &&... args)
Definition ObjectPool.h:204
void destroy(U *p)
Definition ObjectPool.h:210
T * allocate(size_t n=1, const T *=0)
Definition ObjectPool.h:143
const T * address(const T &x) const
Definition ObjectPool.h:142
void deallocate(T *p, size_t n=1)
Definition ObjectPool.h:187
std::vector< void * > empty_
Definition ObjectPool.h:104
const size_t blocksize_
Definition ObjectPool.h:100
std::enable_if<!std::is_base_of< etiss::RefCountedObject< ObjectPool< T > >, T >::value, void >::type ObjectPool_setAllocatorPointer(T *obj, ObjectPool< T > *this_)
empty fallback function
Definition ObjectPool.h:76
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
std::enable_if< std::is_base_of< etiss::RefCountedObject< ObjectPool< T > >, T >::value, bool >::type decRef(T *ptr)
Definition ObjectPool.h:217
@ FATALERROR
Definition Misc.h:126
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:125
#define false
Definition stdbool.h:17
ObjectPool< Type > other
Definition ObjectPool.h:123