Advertisement
Guest User

Untitled

a guest
Jul 17th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.56 KB | None | 0 0
  1. //=============================================================================
  2. //= MemoryPool.h?
  3.  
  4. #pragma once
  5.  
  6. #include <inttypes.h>
  7. #include <memory.h>
  8. #include <vector>
  9.  
  10.  
  11. template<typename UnitT,
  12. uint16_t page_size = 100,
  13. uint32_t max_elements = 0x00FFFFFF>
  14. class MemPool {
  15. public:
  16.  
  17. typedef struct {
  18. UnitT m_tData;
  19. uint32_t m_index;
  20. } block_t;
  21.  
  22. typedef typename std::vector<block_t*> block_v;
  23.  
  24. public:
  25.  
  26. ~MemPool() {}
  27.  
  28. static MemPool* I() {
  29. if (pool == NULL) {
  30. pool = new MemPool();
  31. }
  32. return pool;
  33. }
  34.  
  35. static UnitT *Allocate() {
  36. return I()->allocate();
  37. }
  38.  
  39. static void Dellocate(const uint32_t& index) {
  40. return I()->dellocate(index);
  41. }
  42.  
  43. static uint32_t Index() {
  44. return I()->index();
  45. }
  46.  
  47. static UnitT *Get(const uint32_t& index) {
  48. return I()->get(index);
  49. }
  50.  
  51. static void Rewind() {
  52. return I()->rewind();
  53. }
  54.  
  55. static UnitT *Next() {
  56. return I()->next();
  57. }
  58.  
  59. protected:
  60.  
  61. // 'allocates' space for an entry of type 'UnitT'
  62. UnitT *allocate() {
  63. block_t *block = NULL;
  64. UnitT *pointer = NULL;
  65. size_t size = 0;
  66. // performs pre-allocation (if needed)
  67. this->preallocate();
  68. // returns free slot (if any) or null
  69. if ((size = m_free.size()) > 0) {
  70. block = m_free.back();
  71. pointer = &block->m_tData;
  72. this->m_index = block->m_index;
  73. m_free.pop_back();
  74. } return pointer;
  75. }
  76.  
  77. // 'delocates' a pointer at given @index
  78. void dellocate(const uint32_t& index) {
  79. uint16_t row = index / page_size;
  80. uint16_t col = index % page_size;
  81. block_t *entry = NULL;
  82. if (index > max_elements) {
  83. return;
  84. }
  85. entry = &m_list[row][col];
  86. m_free.push_back(entry);
  87. }
  88.  
  89. uint32_t index() {
  90. return this->m_index;
  91. }
  92.  
  93. // 'retrieves' an entry at given @index
  94. UnitT *get(const uint32_t& index) {
  95. uint16_t row = index / page_size;
  96. uint16_t col = index % page_size;
  97. if (index > max_elements) {
  98. return 0;
  99. }
  100. if (m_list.size() <= row) {
  101. return 0;
  102. }
  103. return &pool->m_list[row][col].m_tData;
  104. }
  105.  
  106. // returns m_list index
  107. void preallocate() {
  108. uint32_t index = 0;
  109. block_t *blocks = NULL;
  110. size_t col = 0, rows = 0;
  111. rows = m_list.size();
  112. if (m_free.empty() == false) {
  113. // not required,
  114. // there are some free objects to pick up
  115. return;
  116. }
  117. if (rows * page_size >= max_elements) {
  118. return;// limit reached
  119. }
  120. try {
  121. blocks = new block_t[page_size];
  122. if (blocks == NULL) {
  123. return;// out of memory?
  124. }
  125.  
  126. m_list.push_back(blocks);
  127. for (col = 0; col < page_size; ++col) {
  128. index = uint32_t(rows * page_size + col);
  129. m_free.push_back(&blocks[col]);
  130. blocks[col].m_index = index;
  131. }
  132. }
  133. catch (const std::bad_alloc& e) {
  134. (void)e;//-- out of memory?
  135. }
  136. }
  137.  
  138. // set the iterator position at the list beginning
  139. void rewind() {
  140. this->m_iterator = 0;
  141. }
  142.  
  143. // 'retrieves' the item in where the iterator is at,
  144. // and increases its position by 1, for its next iteration.
  145. UnitT *next() {
  146. uint16_t row = this->m_iterator / page_size;
  147. uint16_t col = this->m_iterator % page_size;
  148. this->m_iterator += 1;
  149. if (this->m_iterator > max_elements) {
  150. return 0;
  151. }
  152. if (m_list.size() <= row) {
  153. return 0;
  154. }
  155. return &pool->m_list[row][col].m_tData;
  156. }
  157.  
  158. private:
  159. MemPool() : m_list(), m_free(), m_iterator(0), m_index(0) {}
  160.  
  161. private:
  162. block_v m_list;
  163. block_v m_free;
  164. uint32_t m_iterator;
  165. uint32_t m_index;
  166. static MemPool *pool;
  167. };
  168.  
  169. //-- indeed to be a singleton, might be changed to work as an instance (if required)
  170. template<typename UnitT, uint16_t page_size, uint32_t max_elements>
  171. MemPool<UnitT, page_size, max_elements>*
  172. MemPool<UnitT, page_size, max_elements>::pool = NULL;
  173.  
  174. //=============================================================================
  175. //= main.cpp
  176. //=============================================================================
  177.  
  178. #include "MemoryPool.h"
  179. #include <Windows.h>
  180.  
  181. struct sData {// 40kb
  182. private:
  183. unsigned char _its_size_[1024*40 - sizeof(uint32_t)];
  184. uint32_t _mem_index;
  185.  
  186. public:
  187. uint32_t GetIndex() {
  188. return this->_mem_index;
  189. }
  190.  
  191. void SetIndex(uint32_t i) {
  192. this->_mem_index = i;
  193. }
  194.  
  195. void Initially() {
  196. //-- ? triggered when it is being 'allocated'
  197. }
  198.  
  199. void Finally() {
  200. //-- ? triggered when it is 'deallocated'
  201. }
  202. };
  203.  
  204. // defines a memory pool type | a shortcut
  205. typedef MemPool<
  206. sData, //-- object type
  207. 100, //-- objects within each allocated page
  208. 64000 //-- maximum amount of objects
  209. > DataAllocator;
  210.  
  211.  
  212. // 'allocation' | null
  213. static sData* NewData()
  214. {
  215. sData *data = DataAllocator::Allocate();
  216. if (data) {
  217. data->SetIndex(DataAllocator::Index());
  218. data->Initially();
  219. } return data;
  220. return NULL;
  221. }
  222.  
  223.  
  224. // 'deallocation'
  225. static void DelData(sData* data)
  226. {
  227. data->Finally();
  228. // 0xFFFFFFFF unused flag/index
  229. data->SetIndex(0xFFFFFFFF);
  230. DataAllocator::Dellocate(data->GetIndex());
  231. }
  232.  
  233.  
  234. // access by an index | null
  235. static sData* GetData(uint32_t i)
  236. {
  237. return DataAllocator::Get(i);
  238. }
  239.  
  240.  
  241. // Iterator: begin
  242. static void BeginGetData()
  243. {
  244. return DataAllocator::Rewind();
  245. }
  246.  
  247.  
  248. // Iterator: next | null
  249. static sData* GetNextData()
  250. {
  251. sData *data = DataAllocator::Next();
  252. do {
  253. data = DataAllocator::Next();
  254. if (data == NULL)
  255. break;
  256. // 0xFFFFFFFF unused flag/index
  257. if (data->GetIndex() < 0xFFFFFFFF)
  258. break;
  259. } while (true);
  260. return data;
  261. }
  262.  
  263. int main(int argc, const char *argv[])
  264. {
  265. size_t allocations = 0;
  266. BOOL more = TRUE;
  267.  
  268. while (more) {// runs until nulled out
  269. allocations += (more = (NewData() != NULL))? 1 : 0;
  270. }
  271.  
  272. // prints out the amount of allocations until reached its max. items,
  273. // or memory allocation issues (there is not enough memory).
  274. printf("Allocations: %lu\n", allocations);
  275.  
  276. return system("pause");
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement