Advertisement
mechanicker

Memory pool based on stack/file based memory

Jan 25th, 2018
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.61 KB | None | 0 0
  1. //
  2. // Created on 1/25/18
  3. //
  4.  
  5. #include <iostream>
  6.  
  7. #include <sys/mman.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <assert.h>
  11.  
  12. using namespace std;
  13.  
  14. template <typename T>
  15. struct Node {
  16.     typedef T Data_t;
  17.  
  18.     T _data;
  19.     Node<T>* _next;
  20. };
  21.  
  22. // Memory pool based on memory from stack
  23. template <typename T, size_t C>
  24. class MemPool {
  25. public:
  26.     typedef Node<T> Node_t;
  27.  
  28.     MemPool() {
  29.         _freeList = nullptr;
  30.  
  31.         // Initialize the memory
  32.         memset(_buff, C, sizeof(T));
  33.  
  34.         // Create a link list of free nodes
  35.         typename Node_t::Data_t count(0);
  36.         for (size_t ii = 0; ii < C; ii++) {
  37.             _buff[ii]._data = count++;
  38.             put(&_buff[ii]);
  39.         }
  40.     }
  41.  
  42.     // get a node from the pool
  43.     Node_t* get() {
  44.         if (_freeList) {
  45.             Node_t *node = _freeList;
  46.             _freeList = _freeList->_next;
  47.             return node;
  48.         }
  49.  
  50.         return nullptr;
  51.     }
  52.  
  53.     // free the node back to pool
  54.     void put(Node_t* node) {
  55.         if (!_freeList) {
  56.             _freeList = node;
  57.             _freeList->_next = nullptr;
  58.         } else {
  59.             node->_next = _freeList;
  60.             _freeList = node;
  61.         }
  62.  
  63.         return;
  64.     }
  65.  
  66. private:
  67.     Node_t* _freeList;
  68.     Node_t _buff[C];
  69. };
  70.  
  71.  
  72. // Memory pool based on memory from file via mmap
  73. template <typename T>
  74. class MemMapPool {
  75. public:
  76.     typedef Node<T> Node_t;
  77.  
  78.     MemMapPool(size_t count) {
  79.         _mmappedData = nullptr;
  80.         _freeList = nullptr;
  81.  
  82.         int psz = getpagesize();
  83.         _mmappedDataSz = count * sizeof(T);
  84.  
  85.         if (_mmappedDataSz > psz) {
  86.             _mmappedDataSz = ((_mmappedDataSz/psz) + 1) * psz;
  87.         } else {
  88.             _mmappedDataSz = psz;
  89.         }
  90.  
  91.         Node_t* buff = getMappedMemory();
  92.         assert(buff);
  93.  
  94.         // Create a link list of free nodes
  95.         typename Node_t::Data_t index(0);
  96.         for (size_t ii = 0; ii < count; ii++) {
  97.             buff[ii]._data = index++;
  98.             put(&buff[ii]);
  99.         }
  100.     }
  101.  
  102.     ~MemMapPool() {
  103.         _freeList = nullptr;
  104.         if (_mmappedData) {
  105.             munmap(_mmappedData, _mmappedDataSz);
  106.         }
  107.     }
  108.  
  109.     Node_t* getMappedMemory() {
  110.         int fd = open("mem", O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);
  111.         assert(fd>0);
  112.  
  113.         int err = ftruncate(fd, _mmappedDataSz);
  114.         assert(err == 0);
  115.  
  116.         _mmappedData = mmap(NULL, _mmappedDataSz, PROT_WRITE, MAP_PRIVATE, fd, 0);
  117.         assert(_mmappedData != MAP_FAILED);
  118.  
  119.         memset(_mmappedData, 1, _mmappedDataSz);
  120.         return (Node_t*)_mmappedData;
  121.     }
  122.  
  123.     // get a node from the pool
  124.     Node_t* get() {
  125.         if (_freeList) {
  126.             Node_t *node = _freeList;
  127.             _freeList = _freeList->_next;
  128.             return node;
  129.         }
  130.  
  131.         return nullptr;
  132.     }
  133.  
  134.     // free the node back to pool
  135.     void put(Node_t* node) {
  136.         if (!_freeList) {
  137.             _freeList = node;
  138.             _freeList->_next = nullptr;
  139.         } else {
  140.             node->_next = _freeList;
  141.             _freeList = node;
  142.         }
  143.  
  144.         return;
  145.     }
  146.  
  147. private:
  148.     Node_t* _freeList;
  149.     void* _mmappedData;
  150.     size_t _mmappedDataSz;
  151. };
  152.  
  153. static void cling_main() {
  154.     // MemPool<int, 10> pool;
  155.     // MemPool<int, 10>::Node_t *node;
  156.  
  157.     MemMapPool<int> pool(10);
  158.     MemMapPool<int>::Node_t *node;
  159.  
  160.     while ((node = pool.get())) {
  161.         cout << node->_data << endl;
  162.     }
  163. }
  164.  
  165. #ifdef CLING
  166. cling_main();
  167. #else
  168. int main(int argc, const char* argv[]) {
  169.     cling_main();
  170.     return 0;
  171. }
  172. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement