Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //=============================================================================
- //= MemoryPool.h?
- #pragma once
- #include <inttypes.h>
- #include <memory.h>
- #include <vector>
- template<typename UnitT,
- uint16_t page_size = 100,
- uint32_t max_elements = 0x00FFFFFF>
- class MemPool {
- public:
- typedef struct {
- UnitT m_tData;
- uint32_t m_index;
- } block_t;
- typedef typename std::vector<block_t*> block_v;
- public:
- ~MemPool() {}
- static MemPool* I() {
- if (pool == NULL) {
- pool = new MemPool();
- }
- return pool;
- }
- static UnitT *Allocate() {
- return I()->allocate();
- }
- static void Dellocate(const uint32_t& index) {
- return I()->dellocate(index);
- }
- static uint32_t Index() {
- return I()->index();
- }
- static UnitT *Get(const uint32_t& index) {
- return I()->get(index);
- }
- static void Rewind() {
- return I()->rewind();
- }
- static UnitT *Next() {
- return I()->next();
- }
- protected:
- // 'allocates' space for an entry of type 'UnitT'
- UnitT *allocate() {
- block_t *block = NULL;
- UnitT *pointer = NULL;
- size_t size = 0;
- // performs pre-allocation (if needed)
- this->preallocate();
- // returns free slot (if any) or null
- if ((size = m_free.size()) > 0) {
- block = m_free.back();
- pointer = &block->m_tData;
- this->m_index = block->m_index;
- m_free.pop_back();
- } return pointer;
- }
- // 'delocates' a pointer at given @index
- void dellocate(const uint32_t& index) {
- uint16_t row = index / page_size;
- uint16_t col = index % page_size;
- block_t *entry = NULL;
- if (index > max_elements) {
- return;
- }
- entry = &m_list[row][col];
- m_free.push_back(entry);
- }
- uint32_t index() {
- return this->m_index;
- }
- // 'retrieves' an entry at given @index
- UnitT *get(const uint32_t& index) {
- uint16_t row = index / page_size;
- uint16_t col = index % page_size;
- if (index > max_elements) {
- return 0;
- }
- if (m_list.size() <= row) {
- return 0;
- }
- return &pool->m_list[row][col].m_tData;
- }
- // returns m_list index
- void preallocate() {
- uint32_t index = 0;
- block_t *blocks = NULL;
- size_t col = 0, rows = 0;
- rows = m_list.size();
- if (m_free.empty() == false) {
- // not required,
- // there are some free objects to pick up
- return;
- }
- if (rows * page_size >= max_elements) {
- return;// limit reached
- }
- try {
- blocks = new block_t[page_size];
- if (blocks == NULL) {
- return;// out of memory?
- }
- m_list.push_back(blocks);
- for (col = 0; col < page_size; ++col) {
- index = uint32_t(rows * page_size + col);
- m_free.push_back(&blocks[col]);
- blocks[col].m_index = index;
- }
- }
- catch (const std::bad_alloc& e) {
- (void)e;//-- out of memory?
- }
- }
- // set the iterator position at the list beginning
- void rewind() {
- this->m_iterator = 0;
- }
- // 'retrieves' the item in where the iterator is at,
- // and increases its position by 1, for its next iteration.
- UnitT *next() {
- uint16_t row = this->m_iterator / page_size;
- uint16_t col = this->m_iterator % page_size;
- this->m_iterator += 1;
- if (this->m_iterator > max_elements) {
- return 0;
- }
- if (m_list.size() <= row) {
- return 0;
- }
- return &pool->m_list[row][col].m_tData;
- }
- private:
- MemPool() : m_list(), m_free(), m_iterator(0), m_index(0) {}
- private:
- block_v m_list;
- block_v m_free;
- uint32_t m_iterator;
- uint32_t m_index;
- static MemPool *pool;
- };
- //-- indeed to be a singleton, might be changed to work as an instance (if required)
- template<typename UnitT, uint16_t page_size, uint32_t max_elements>
- MemPool<UnitT, page_size, max_elements>*
- MemPool<UnitT, page_size, max_elements>::pool = NULL;
- //=============================================================================
- //= main.cpp
- //=============================================================================
- #include "MemoryPool.h"
- #include <Windows.h>
- struct sData {// 40kb
- private:
- unsigned char _its_size_[1024*40 - sizeof(uint32_t)];
- uint32_t _mem_index;
- public:
- uint32_t GetIndex() {
- return this->_mem_index;
- }
- void SetIndex(uint32_t i) {
- this->_mem_index = i;
- }
- void Initially() {
- //-- ? triggered when it is being 'allocated'
- }
- void Finally() {
- //-- ? triggered when it is 'deallocated'
- }
- };
- // defines a memory pool type | a shortcut
- typedef MemPool<
- sData, //-- object type
- 100, //-- objects within each allocated page
- 64000 //-- maximum amount of objects
- > DataAllocator;
- // 'allocation' | null
- static sData* NewData()
- {
- sData *data = DataAllocator::Allocate();
- if (data) {
- data->SetIndex(DataAllocator::Index());
- data->Initially();
- } return data;
- return NULL;
- }
- // 'deallocation'
- static void DelData(sData* data)
- {
- data->Finally();
- // 0xFFFFFFFF unused flag/index
- data->SetIndex(0xFFFFFFFF);
- DataAllocator::Dellocate(data->GetIndex());
- }
- // access by an index | null
- static sData* GetData(uint32_t i)
- {
- return DataAllocator::Get(i);
- }
- // Iterator: begin
- static void BeginGetData()
- {
- return DataAllocator::Rewind();
- }
- // Iterator: next | null
- static sData* GetNextData()
- {
- sData *data = DataAllocator::Next();
- do {
- data = DataAllocator::Next();
- if (data == NULL)
- break;
- // 0xFFFFFFFF unused flag/index
- if (data->GetIndex() < 0xFFFFFFFF)
- break;
- } while (true);
- return data;
- }
- int main(int argc, const char *argv[])
- {
- size_t allocations = 0;
- BOOL more = TRUE;
- while (more) {// runs until nulled out
- allocations += (more = (NewData() != NULL))? 1 : 0;
- }
- // prints out the amount of allocations until reached its max. items,
- // or memory allocation issues (there is not enough memory).
- printf("Allocations: %lu\n", allocations);
- return system("pause");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement