|
#ifndef UTIL_POOL_H |
|
#define UTIL_POOL_H |
|
|
|
#include <cassert> |
|
#include <cstring> |
|
#include <vector> |
|
|
|
#include <stdint.h> |
|
|
|
namespace util { |
|
|
|
|
|
|
|
|
|
class Pool { |
|
public: |
|
Pool(); |
|
|
|
~Pool(); |
|
|
|
void *Allocate(std::size_t size) { |
|
void *ret = current_; |
|
current_ += size; |
|
if (current_ > current_end_) { |
|
ret = More(size); |
|
} |
|
#ifdef DEBUG |
|
base_check_ = ret; |
|
#endif |
|
return ret; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Continue(void *&base, std::ptrdiff_t additional) { |
|
#ifdef DEBUG |
|
assert(base == base_check_); |
|
#endif |
|
current_ += additional; |
|
if (current_ > current_end_) { |
|
std::size_t new_total = current_ - static_cast<uint8_t*>(base); |
|
void *new_base = More(new_total); |
|
std::memcpy(new_base, base, new_total - additional); |
|
base = new_base; |
|
#ifdef DEBUG |
|
base_check_ = base; |
|
#endif |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
void FreeAll(); |
|
|
|
private: |
|
void *More(std::size_t size); |
|
|
|
std::vector<void *> free_list_; |
|
|
|
uint8_t *current_, *current_end_; |
|
|
|
#ifdef DEBUG |
|
|
|
void *base_check_; |
|
#endif |
|
|
|
|
|
Pool(const Pool &); |
|
Pool &operator=(const Pool &); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
class FreePool { |
|
public: |
|
explicit FreePool(std::size_t element_size) |
|
: free_list_(NULL), |
|
element_size_(element_size), |
|
padded_size_(std::max(element_size_, sizeof(void*))) {} |
|
|
|
void *Allocate() { |
|
if (free_list_) { |
|
void *ret = free_list_; |
|
free_list_ = *reinterpret_cast<void**>(free_list_); |
|
return ret; |
|
} else { |
|
return backing_.Allocate(padded_size_); |
|
} |
|
} |
|
|
|
void Free(void *ptr) { |
|
*reinterpret_cast<void**>(ptr) = free_list_; |
|
free_list_ = ptr; |
|
} |
|
|
|
std::size_t ElementSize() const { return element_size_; } |
|
|
|
private: |
|
void *free_list_; |
|
|
|
Pool backing_; |
|
|
|
const std::size_t element_size_; |
|
const std::size_t padded_size_; |
|
}; |
|
|
|
} |
|
|
|
#endif |
|
|