Line data Source code
1 : #include "RegionResource.h" 2 : 3 : #include "BitUtil.h" 4 : #include "Util.h" 5 : 6 : namespace elsa::mr 7 : { 8 : RegionResource::RegionResource(const MemoryResource& upstream, 9 : const RegionResourceConfig& config) 10 : : _upstream{upstream}, _config{config} 11 6 : { 12 6 : _basePtr = _upstream->allocate(_config.regionSize, region_resource::BLOCK_GRANULARITY); 13 6 : _bumpPtr = _basePtr; 14 6 : _allocatedSize = 0; 15 6 : _endPtr = detail::voidPtrOffset(_basePtr, _config.regionSize); 16 6 : } 17 : 18 : RegionResource::~RegionResource() 19 6 : { 20 6 : _upstream->deallocate(_basePtr, _config.regionSize, region_resource::BLOCK_GRANULARITY); 21 6 : } 22 : 23 : MemoryResource RegionResource::make(const MemoryResource& upstream, 24 : const RegionResourceConfig& config) 25 6 : { 26 6 : return std::shared_ptr<MemResInterface>(new RegionResource(upstream, config), 27 6 : [](RegionResource* p) { delete p; }); 28 6 : } 29 : 30 : void* RegionResource::allocate(size_t size, size_t alignment) 31 10117 : { 32 10117 : auto [_, sizeWithAlignment] = 33 10117 : util::computeSizeWithAlignment(size, alignment, region_resource::BLOCK_GRANULARITY); 34 : 35 10117 : size_t remainingSize = 36 10117 : reinterpret_cast<uintptr_t>(_endPtr) - reinterpret_cast<uintptr_t>(_bumpPtr); 37 : 38 10117 : if (sizeWithAlignment > remainingSize) { 39 0 : return _upstream->allocate(sizeWithAlignment, alignment); 40 0 : } 41 : 42 10117 : _allocatedSize += sizeWithAlignment; 43 10117 : void* ret = detail::alignUp(_bumpPtr, alignment); 44 10117 : _bumpPtr = detail::voidPtrOffset(_bumpPtr, sizeWithAlignment); 45 10117 : return ret; 46 10117 : } 47 : 48 : void RegionResource::deallocate(void* ptr, size_t size, size_t alignment) noexcept 49 10114 : { 50 10114 : if (reinterpret_cast<uintptr_t>(_basePtr) <= reinterpret_cast<uintptr_t>(ptr) 51 10114 : && reinterpret_cast<uintptr_t>(ptr) < reinterpret_cast<uintptr_t>(_endPtr)) { 52 10114 : auto [_, sizeWithAlignment] = 53 10114 : util::computeSizeWithAlignment(size, alignment, region_resource::BLOCK_GRANULARITY); 54 10114 : _allocatedSize -= sizeWithAlignment; 55 : 56 10114 : if (_allocatedSize == 0) { 57 : // arena can be reused 58 49 : _bumpPtr = _basePtr; 59 : // TODO: if config is set to adaptive, potentially allocate new arena based on 60 : // observed allocation behavior 61 49 : } 62 10114 : } else { 63 0 : _upstream->deallocate(ptr, size, alignment); 64 0 : return; 65 0 : } 66 10114 : } 67 : 68 : bool RegionResource::tryResize(void* ptr, size_t size, size_t alignment, 69 : size_t newSize) noexcept 70 0 : { 71 0 : if (reinterpret_cast<uintptr_t>(_basePtr) <= reinterpret_cast<uintptr_t>(ptr) 72 0 : && reinterpret_cast<uintptr_t>(ptr) < reinterpret_cast<uintptr_t>(_endPtr)) { 73 0 : return false; 74 0 : } else { 75 0 : return _upstream->tryResize(ptr, size, alignment, newSize); 76 0 : } 77 0 : } 78 : } // namespace elsa::mr