12 #ifndef ROC_CORE_POOL_H_
13 #define ROC_CORE_POOL_H_
44 : allocator_(allocator)
46 , elem_size_(
max_align(std::max(sizeof(Elem), object_size)))
47 , chunk_hdr_size_(
max_align(sizeof(Chunk)))
51 (
unsigned long)elem_size_, (
int)poison);
63 Elem* elem = get_elem_();
73 memset(memory, PoisonAllocated, elem_size_);
75 memset(memory, 0, elem_size_);
84 roc_panic(
"pool: deallocating null pointer");
88 memset(memory, PoisonDeallocated, elem_size_);
91 Elem* elem =
new (memory) Elem;
102 enum { PoisonAllocated = 0x7a, PoisonDeallocated = 0x7d };
104 struct Chunk : ListNode {};
105 struct Elem : ListNode {};
110 if (free_elems_.size() == 0) {
114 Elem* elem = free_elems_.front();
116 free_elems_.remove(*elem);
123 void put_elem_(Elem* elem) {
126 if (used_elems_ == 0) {
127 roc_panic(
"pool: unpaired deallocation");
131 free_elems_.push_front(*elem);
134 void allocate_chunk_() {
135 void* memory = allocator_.
allocate(chunk_offset_(chunk_n_elems_));
136 if (memory == NULL) {
140 Chunk* chunk =
new (memory) Chunk;
141 chunks_.push_back(*chunk);
143 for (
size_t n = 0; n < chunk_n_elems_; n++) {
144 Elem* elem =
new ((
char*)chunk + chunk_offset_(n)) Elem;
145 free_elems_.push_back(*elem);
151 void deallocate_all_() {
152 if (used_elems_ != 0) {
153 roc_panic(
"pool: detected leak: used=%lu free=%lu",
154 (
unsigned long)used_elems_, (
unsigned long)free_elems_.size());
157 while (Elem* elem = free_elems_.front()) {
158 free_elems_.remove(*elem);
161 while (Chunk* chunk = chunks_.front()) {
162 chunks_.remove(*chunk);
167 size_t chunk_offset_(
size_t n)
const {
168 return chunk_hdr_size_ + n * elem_size_;
173 IAllocator& allocator_;
175 List<Chunk, NoOwnership> chunks_;
176 List<Elem, NoOwnership> free_elems_;
179 const size_t elem_size_;
180 const size_t chunk_hdr_size_;
181 size_t chunk_n_elems_;
195 return pool.allocate();
203 pool.deallocate(ptr);
#define ROC_ATTR_NOTHROW
Function never throws.
Memory allocator interface.
virtual void deallocate(void *)=0
Deallocate previously allocated memory.
virtual void * allocate(size_t size)=0
Allocate memory.
ScopedLock< Mutex > Lock
RAII lock.
Base class for non-copyable objects.
void destroy(T &object)
Destroy object and deallocate its memory.
Pool(IAllocator &allocator, size_t object_size, bool poison)
Initialization.
void * allocate()
Allocate new object.
void deallocate(void *memory)
Free previously allocated memory.
Memory allocator interface.
Intrusive doubly-linked list.
#define roc_log(...)
Print message to log.
size_t max_align(size_t sz)
Adjust the given size to be maximum aligned.
#define roc_panic_if(x)
Panic if condition is true.
#define roc_panic(...)
Print error message and terminate program gracefully.
Commonly used types and functions.