1 #include "memory_preallocated.h" 2 3 #include <stdlib.h> 4 5 /* Initialise the memory pool with a mandatory 'limit' in pages. */ 6 7 MemoryPreallocated::MemoryPreallocated(unsigned int limit, offset_t region_size) 8 : Memory(region_size), _limit(limit) 9 { 10 /* Allocate all memory at once, rounding each unit to the nearest page 11 size. */ 12 13 offset_t rounded_size = round_multiple(region_size, PAGE_SIZE); 14 offset_t total_size = limit * rounded_size; 15 offset_t current; 16 17 if (posix_memalign((void **) ¤t, total_size, total_size)) 18 return; 19 20 /* Split the memory up into separate regions. */ 21 22 while (limit) 23 { 24 _free.push_back(new Region(current, current + rounded_size)); 25 current += rounded_size; 26 limit--; 27 } 28 } 29 30 /* Free all allocated regions. */ 31 32 MemoryPreallocated::~MemoryPreallocated() 33 { 34 for (std::list<Region *>::iterator it = _free.begin(); it != _free.end(); it++) 35 delete *it; 36 37 for (std::set<Region *>::iterator it = _used.begin(); it != _used.end(); it++) 38 delete *it; 39 } 40 41 /* Allocate a new region of the configured size rounded to the nearest page. */ 42 43 Region *MemoryPreallocated::region() 44 { 45 std::lock_guard<std::mutex> guard(_lock); 46 47 std::list<Region *>::iterator it = _free.begin(); 48 49 if (it == _free.end()) 50 return NULL; 51 52 Region *r = *it; 53 54 _free.erase(it); 55 _used.insert(r); 56 57 return r; 58 } 59 60 /* Release the allocated 'region'. */ 61 62 void MemoryPreallocated::release(Region *region) 63 { 64 std::lock_guard<std::mutex> guard(_lock); 65 66 std::set<Region *>::iterator it = _used.find(region); 67 68 if (it != _used.end()) 69 { 70 _used.erase(it); 71 _free.push_back(region); 72 } 73 } 74 75 // vim: tabstop=4 expandtab shiftwidth=4