1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/memory.cc Wed Jan 20 01:37:12 2021 +0100
1.3 @@ -0,0 +1,80 @@
1.4 +#include "memory.h"
1.5 +#include "memory_map.h"
1.6 +
1.7 +
1.8 +
1.9 +/* Global memory allocator. */
1.10 +
1.11 +extern Allocator allocator;
1.12 +
1.13 +
1.14 +
1.15 +/* Initialise the memory pool with an optional 'limit' in pages. */
1.16 +
1.17 +Memory::Memory(unsigned int limit, offset_t region_size)
1.18 +: _limit(limit), _region_size(region_size)
1.19 +{
1.20 + _limited = true;
1.21 +}
1.22 +
1.23 +Memory::Memory()
1.24 +: _region_size(PAGE_SIZE)
1.25 +{
1.26 + _limited = false;
1.27 +}
1.28 +
1.29 +/* Allocate a new region of the given 'size' rounded to the nearest page. */
1.30 +
1.31 +Region *Memory::region(offset_t size)
1.32 +{
1.33 + std::lock_guard<std::mutex> guard(_lock);
1.34 +
1.35 + offset_t rounded = round(size, PAGE_SIZE);
1.36 + offset_t pages = rounded / PAGE_SIZE;
1.37 +
1.38 + /* Check for sufficient pages. */
1.39 +
1.40 + if (!_limited || (_limit >= pages))
1.41 + {
1.42 + /* Attempt to allocate aligned memory. */
1.43 +
1.44 + Region *region = allocator.region(rounded);
1.45 +
1.46 + if (region == NULL)
1.47 + return NULL;
1.48 +
1.49 + if (_limited)
1.50 + _limit -= pages;
1.51 +
1.52 + return region;
1.53 + }
1.54 +
1.55 + /* Return no region without sufficient pages. */
1.56 +
1.57 + else
1.58 + return NULL;
1.59 +}
1.60 +
1.61 +Region *Memory::region()
1.62 +{
1.63 + return region(_region_size);
1.64 +}
1.65 +
1.66 +/* Release the allocated 'region'. */
1.67 +
1.68 +void Memory::release(Region *region)
1.69 +{
1.70 + std::lock_guard<std::mutex> guard(_lock);
1.71 +
1.72 + offset_t rounded = round(region->size(), PAGE_SIZE);
1.73 + offset_t pages = rounded / PAGE_SIZE;
1.74 +
1.75 + if (_limited)
1.76 + _limit += pages;
1.77 +
1.78 + allocator.remove(region);
1.79 +
1.80 + delete region;
1.81 +}
1.82 +
1.83 +// vim: tabstop=4 expandtab shiftwidth=4