// // Created on 1/25/18 // #include #include #include #include #include using namespace std; template struct Node { typedef T Data_t; T _data; Node* _next; }; // Memory pool based on memory from stack template class MemPool { public: typedef Node Node_t; MemPool() { _freeList = nullptr; // Initialize the memory memset(_buff, C, sizeof(T)); // Create a link list of free nodes typename Node_t::Data_t count(0); for (size_t ii = 0; ii < C; ii++) { _buff[ii]._data = count++; put(&_buff[ii]); } } // get a node from the pool Node_t* get() { if (_freeList) { Node_t *node = _freeList; _freeList = _freeList->_next; return node; } return nullptr; } // free the node back to pool void put(Node_t* node) { if (!_freeList) { _freeList = node; _freeList->_next = nullptr; } else { node->_next = _freeList; _freeList = node; } return; } private: Node_t* _freeList; Node_t _buff[C]; }; // Memory pool based on memory from file via mmap template class MemMapPool { public: typedef Node Node_t; MemMapPool(size_t count) { _mmappedData = nullptr; _freeList = nullptr; int psz = getpagesize(); _mmappedDataSz = count * sizeof(T); if (_mmappedDataSz > psz) { _mmappedDataSz = ((_mmappedDataSz/psz) + 1) * psz; } else { _mmappedDataSz = psz; } Node_t* buff = getMappedMemory(); assert(buff); // Create a link list of free nodes typename Node_t::Data_t index(0); for (size_t ii = 0; ii < count; ii++) { buff[ii]._data = index++; put(&buff[ii]); } } ~MemMapPool() { _freeList = nullptr; if (_mmappedData) { munmap(_mmappedData, _mmappedDataSz); } } Node_t* getMappedMemory() { int fd = open("mem", O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); assert(fd>0); int err = ftruncate(fd, _mmappedDataSz); assert(err == 0); _mmappedData = mmap(NULL, _mmappedDataSz, PROT_WRITE, MAP_PRIVATE, fd, 0); assert(_mmappedData != MAP_FAILED); memset(_mmappedData, 1, _mmappedDataSz); return (Node_t*)_mmappedData; } // get a node from the pool Node_t* get() { if (_freeList) { Node_t *node = _freeList; _freeList = _freeList->_next; return node; } return nullptr; } // free the node back to pool void put(Node_t* node) { if (!_freeList) { _freeList = node; _freeList->_next = nullptr; } else { node->_next = _freeList; _freeList = node; } return; } private: Node_t* _freeList; void* _mmappedData; size_t _mmappedDataSz; }; static void cling_main() { // MemPool pool; // MemPool::Node_t *node; MemMapPool pool(10); MemMapPool::Node_t *node; while ((node = pool.get())) { cout << node->_data << endl; } } #ifdef CLING cling_main(); #else int main(int argc, const char* argv[]) { cling_main(); return 0; } #endif