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 /* Return whether memory has been allocated. */ 42 43 bool MemoryPreallocated::allocated() 44 { 45 std::lock_guard<std::mutex> guard(_lock); 46 47 return !(_free.empty() && _used.empty()); 48 } 49 50 /* Allocate a new region of the configured size rounded to the nearest page. */ 51 52 Region *MemoryPreallocated::region() 53 { 54 std::lock_guard<std::mutex> guard(_lock); 55 56 std::list<Region *>::iterator it = _free.begin(); 57 58 if (it == _free.end()) 59 return NULL; 60 61 Region *r = *it; 62 63 _free.erase(it); 64 _used.insert(r); 65 66 return r; 67 } 68 69 /* Release the allocated 'region'. */ 70 71 void MemoryPreallocated::release(Region *region) 72 { 73 std::lock_guard<std::mutex> guard(_lock); 74 75 std::set<Region *>::iterator it = _used.find(region); 76 77 if (it != _used.end()) 78 { 79 _used.erase(it); 80 _free.push_back(region); 81 } 82 } 83 84 // vim: tabstop=4 expandtab shiftwidth=4