Advertisement
ne_ziggy

memory.h

Nov 20th, 2011
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.38 KB | None | 0 0
  1. #include <iostream>
  2. #include <map>
  3. #include <set>
  4. #include <queue>
  5. #include <cstdlib>
  6. #include <cstring>
  7.  
  8. #define POOLSIZE 512
  9.  
  10. class Memory {
  11. public:
  12.     static Memory* Instance(); //singleton called with Memory::Instance()
  13.     void* Allocate(size_t); //returns a void pointer and creates a respective pool if none available
  14.     void  Free(void*, size_t); //marks the void pointer as available
  15.  
  16. private:
  17.     Memory() {}
  18.     ~Memory();
  19.     static Memory* pInstance;
  20.     //add a copy constructor
  21.     //add an assignment operator
  22.  
  23.     struct Pool {
  24.         void* pool;
  25.         Pool* next;
  26.     };
  27.  
  28.     std::map<size_t, Pool> poolList; //contains list of memory pool heads
  29.     std::map<size_t, Pool>::iterator poolListIter;
  30.     std::map<size_t,   std::set<void*> > chunkUsed; //used pointers
  31.     std::map<size_t, std::queue<void*> > chunkFree; //available pointers
  32.     std::map<size_t,   std::set<void*> >::iterator chunkUsedIter;
  33.     std::map<size_t, std::queue<void*> >::iterator chunkFreeIter;
  34.  
  35.     void* ExpandPool(size_t, size_t);
  36.     void SegmentPool(void*, size_t, size_t);
  37.     void Cleanup();
  38.     void Cleanup(size_t); //support to clear specific pools...
  39. };
  40.  
  41. Memory* Memory::pInstance = NULL;
  42.  
  43. Memory::~Memory() {
  44.     Cleanup();
  45. }
  46.  
  47. Memory* Memory::Instance() {
  48.     if(!pInstance) pInstance = new Memory();
  49.     return pInstance;
  50. }
  51.  
  52. void* Memory::Allocate(size_t size) {
  53.     void* ptr = NULL;
  54.     chunkFreeIter = chunkFree.find(size);
  55.  
  56.     if(chunkFreeIter == chunkFree.end()) { //if free chunk queue does not exist for size...
  57.         //if there is no free chunk queue, that means there is no respective pool list
  58.         poolListIter  = poolList.find(size);
  59.         Pool chunk;
  60.         chunk.pool = NULL; chunk.next = NULL;
  61.         poolList.insert(std::pair<size_t, Pool>(size, chunk));
  62.         ptr = ExpandPool(size, POOLSIZE); //returns void* to pool head
  63.  
  64.         std::queue<void*> freequeue;
  65.         chunkFree.insert(std::pair<size_t, std::queue<void*> >(size, freequeue));
  66.  
  67.         SegmentPool(ptr, size, POOLSIZE); //Adds void pointers to free queue from pool
  68.  
  69.         std::set<void*> usedset;
  70.         chunkUsed.insert(std::pair<size_t, std::set<void*> >(size, usedset));
  71.     }
  72.     else if (chunkFreeIter->second.empty()) { //if free chunk queue is empty...
  73.         ptr = ExpandPool(size, POOLSIZE);
  74.         SegmentPool(ptr, size, POOLSIZE);
  75.     }
  76.  
  77.     chunkUsedIter = chunkUsed.find(size);
  78.     ptr = (chunkFreeIter->second).front();
  79.  
  80.     (chunkFreeIter->second).pop(); //pop pointer from free queue
  81.     chunkUsedIter->second.insert(ptr); //place into used set
  82.  
  83.     return ptr;
  84. }
  85.  
  86. void Memory::Free(void* ptr, size_t sizetype) {
  87.     chunkFreeIter = chunkFree.find(sizetype); // <size_t, queue<> >
  88.     chunkUsedIter = chunkUsed.find(sizetype); // <size_t, set<> >
  89.     chunkFreeIter->second.push(ptr); //add pointer to free queue
  90.     chunkUsedIter->second.erase(ptr);
  91. }
  92.  
  93.  
  94. void* Memory::ExpandPool(size_t sizetype, size_t sizepool = POOLSIZE) {
  95.     poolListIter = poolList.find(sizetype); //assumption that pool exists
  96.     Pool* pChunk = &(poolListIter->second);
  97.  
  98.     while(pChunk->next != NULL) pChunk = pChunk->next; //iterate to last
  99.     pChunk->next = new Pool;
  100.     pChunk = pChunk->next;
  101.  
  102.     pChunk->pool = malloc(sizetype*sizepool);
  103.     pChunk->next = NULL;
  104.  
  105.     return pChunk->pool;
  106. }
  107.  
  108. void Memory::SegmentPool(void* pool, size_t sizetype, size_t sizepool) {
  109.     void* ptr;
  110.     chunkFreeIter = chunkFree.find(sizetype); //chunkFreeIter->second == (queue<>)
  111.  
  112.     for(size_t ii = 0; ii < sizepool; ii++) {
  113.         ptr = (char*) pool + sizetype * ii;
  114.         chunkFreeIter->second.push(ptr);
  115.     }
  116. }
  117.  
  118. void Memory::Cleanup() {
  119.     /*
  120.     Pool.pool == void*
  121.     Pool.next == Pool*
  122.     */
  123.  
  124.     chunkFree.clear();
  125.     chunkUsed.clear();
  126.  
  127.     for(poolListIter = poolList.begin(); poolListIter != poolList.end(); poolListIter++) {
  128.         Pool* pHead  = &(poolListIter->second);
  129.         free(pHead->pool);
  130.  
  131.         if(pHead->next != NULL) {
  132.             Pool* pChunk = pHead->next;
  133.             while(pChunk->next != NULL) {
  134.                 Pool* pNext = pChunk->next;
  135.                 free(pChunk->pool);
  136.                 delete pChunk;
  137.                 pChunk = pNext;
  138.             }
  139.             free(pChunk->pool);
  140.             delete pChunk;
  141.         }
  142.     }
  143. }
  144.  
  145. void Memory::Cleanup(size_t sizetype) {
  146.     chunkUsed.erase(sizetype);
  147.     chunkFree.erase(sizetype);
  148.  
  149.     poolListIter = poolList.find(sizetype);
  150.     Pool* pHead  = &(poolListIter->second);
  151.     free(pHead->pool);
  152.  
  153.     if(pHead->next != NULL) {
  154.         Pool* pChunk = pHead->next;
  155.         while(pChunk->next != NULL) {
  156.             Pool* pNext = pChunk->next;
  157.             free(pChunk->pool); //void*
  158.             delete pChunk;
  159.             pChunk = pNext;
  160.         }
  161.         free(pChunk->pool);
  162.         delete pChunk;
  163.     }
  164.  
  165.     poolList.erase(poolListIter);
  166. }
  167.  
  168.  
  169. class foo {
  170. public:
  171.     foo(double a, double b) : x(a), y(b) {}
  172.     void* operator new(size_t size)  { return Memory::Instance()->Allocate(size); }
  173.     void  operator delete(void* ptr) { Memory::Instance()->Free(ptr, sizeof(foo)); }
  174.  
  175. private:
  176.     double x, y;
  177. };
  178.  
  179.  
  180. int main() {
  181.     foo* array[1000];
  182.     for(int i = 0; i < 5000; i++) {
  183.         for(int j = 0; j < 1000; j++) {
  184.             array[j] = new foo(i, j);
  185.         }
  186.         for(int j = 0; j < 1000; j++) {
  187.             delete array[j];
  188.         }
  189.     }
  190.  
  191.     return 0;
  192. }
  193.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement