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