1 #include "memory.h" 2 3 #include <stdlib.h> 4 5 6 /* Initialise the memory pool with an optional 'limit' in pages. */ 7 8 Memory::Memory(unsigned int limit, offset_t region_size) 9 : _limit(limit), _region_size(region_size) 10 { 11 _limited = true; 12 } 13 14 Memory::Memory() 15 : _region_size(PAGE_SIZE) 16 { 17 _limited = false; 18 } 19 20 /* Allocate a block of the given 'size'. */ 21 22 Region *Memory::allocate(offset_t size) 23 { 24 /* Attempt to allocate aligned memory. */ 25 26 void *current; 27 28 /* Make the size appropriate for the invocation. */ 29 30 size = round_multiple(size, PAGE_SIZE); 31 32 if (posix_memalign(¤t, size, size)) 33 return NULL; 34 35 return new Region((offset_t) current, (offset_t) current + size); 36 } 37 38 /* Allocate a new region of the given 'size' rounded to the nearest page. */ 39 40 Region *Memory::region(offset_t size) 41 { 42 std::lock_guard<std::mutex> guard(_lock); 43 44 offset_t rounded = round(size, PAGE_SIZE); 45 offset_t pages = rounded / PAGE_SIZE; 46 47 /* Check for sufficient pages. */ 48 49 if (!_limited || (_limit >= pages)) 50 { 51 /* Attempt to allocate aligned memory. */ 52 53 Region *region = allocate(rounded); 54 55 if (region == NULL) 56 return NULL; 57 58 if (_limited) 59 _limit -= pages; 60 61 return region; 62 } 63 64 /* Return no region without sufficient pages. */ 65 66 else 67 return NULL; 68 } 69 70 Region *Memory::region() 71 { 72 return region(_region_size); 73 } 74 75 /* Release the allocated 'region'. */ 76 77 void Memory::release(Region *region) 78 { 79 std::lock_guard<std::mutex> guard(_lock); 80 81 offset_t rounded = round(region->size(), PAGE_SIZE); 82 offset_t pages = rounded / PAGE_SIZE; 83 84 if (_limited) 85 _limit += pages; 86 87 delete region; 88 } 89 90 // vim: tabstop=4 expandtab shiftwidth=4