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 }