1 module libd.memory.allocator.regionallocator; 2 3 import libd.memory, libd.threading; 4 5 shared struct RegionAllocator 6 { 7 static immutable string Tag = "region"; 8 9 @disable this(this){} 10 11 @nogc nothrow: 12 13 private 14 { 15 PageAllocation _alloc; 16 size_t _ptr; 17 LockBusyCas _ptrLock; 18 } 19 20 this(size_t regionSize) 21 { 22 this._alloc = PageAllocator.allocInBytesToPages(regionSize, false); 23 } 24 25 ~this() 26 { 27 if(this._alloc.memory.ptr) 28 PageAllocator.free(this._alloc); 29 } 30 31 MaybeNullSlice!(T, Tag) alloc(T)(size_t amount) 32 { 33 this._ptrLock.lock(); 34 scope(exit) this._ptrLock.unlock(); 35 36 const end = (T.sizeof * amount) + this._ptr; 37 if(end > this._alloc.memory.length) 38 return typeof(return)(null); 39 40 auto slice = (cast(T*)this._alloc.memory[this._ptr..end].ptr)[0..amount]; 41 this._ptr = end; 42 return typeof(return)(slice); 43 } 44 45 void free(T)(ref NotNullSlice!(T, Tag) slice) 46 { 47 } 48 49 void free(T)(ref NotNullPtr!(T, Tag) ptr) 50 { 51 } 52 53 MaybeNullSlice!(T, Tag) realloc(T)(ref NotNullSlice!(T, Tag) slice, size_t toAmount) 54 { 55 auto end = slice.ptr + slice.length; 56 if(end != this._ptr) 57 return typeof(return)(); 58 end += T.sizeof * toAmount; 59 if(end > this._alloc.memory.length) 60 return typeof(return)(); 61 this._ptr = end; 62 return typeof(return)(slice.ptr[0..end]); 63 } 64 } 65 66 @("RegionAllocator - BasicAllocatorTests") 67 unittest 68 { 69 import libd.memory.allocator._test; 70 auto alloc = RegionAllocator(4096); 71 basicAllocatorTests!(RegionAllocator, () => &alloc)(); 72 }