1 /** 2 3 Collection of typical and useful prebuilt allocators using the given 4 components. User code would typically import this module and use its 5 facilities, or import individual heap building blocks and assemble them. 6 7 */ 8 module stdx.allocator.showcase; 9 10 version (D_BetterC) {} else version = HasDRuntime; 11 12 version (HasDRuntime): 13 14 import stdx.allocator.building_blocks.fallback_allocator, 15 stdx.allocator.gc_allocator, 16 stdx.allocator.building_blocks.region; 17 18 /** 19 20 Allocator that uses stack allocation for up to $(D stackSize) bytes and 21 then falls back to $(D Allocator). Defined as: 22 23 ---- 24 alias StackFront(size_t stackSize, Allocator) = 25 FallbackAllocator!( 26 InSituRegion!(stackSize, Allocator.alignment, 27 __traits(hasMember, Allocator, "deallocate") 28 ? Yes.defineDeallocate 29 : No.defineDeallocate), 30 Allocator); 31 ---- 32 33 Choosing `stackSize` is as always a compromise. Too small a size exhausts the 34 stack storage after a few allocations, after which there are no gains over the 35 backup allocator. Too large a size increases the stack consumed by the thread 36 and may end up worse off because it explores cold portions of the stack. 37 38 */ 39 alias StackFront(size_t stackSize, Allocator = GCAllocator) = 40 FallbackAllocator!( 41 InSituRegion!(stackSize, Allocator.alignment), 42 Allocator); 43 44 /// 45 @system unittest 46 { 47 StackFront!4096 a; 48 auto b = a.allocate(4000); 49 assert(b.length == 4000); 50 auto c = a.allocate(4000); 51 assert(c.length == 4000); 52 a.deallocate(b); 53 a.deallocate(c); 54 } 55 56 /** 57 Creates a scalable `AllocatorList` of `Regions`, each having at least 58 `bytesPerRegion` bytes. Allocation is very fast. This allocator does not offer 59 `deallocate` but does free all regions in its destructor. It is recommended for 60 short-lived batch applications that count on never running out of memory. 61 */ 62 auto mmapRegionList(size_t bytesPerRegion) 63 { 64 static struct Factory 65 { 66 size_t bytesPerRegion; 67 import mir.utility : max; 68 import stdx.allocator.building_blocks.region 69 : Region; 70 import stdx.allocator.mmap_allocator 71 : MmapAllocator; 72 this(size_t n) 73 { 74 bytesPerRegion = n; 75 } 76 auto opCall(size_t n) 77 { 78 return Region!MmapAllocator(max(n, bytesPerRegion)); 79 } 80 } 81 import stdx.allocator.building_blocks.allocator_list 82 : AllocatorList; 83 import stdx.allocator.building_blocks.null_allocator 84 : NullAllocator; 85 auto shop = Factory(bytesPerRegion); 86 return AllocatorList!(Factory, NullAllocator)(shop); 87 } 88 89 /// 90 @system unittest 91 { 92 auto alloc = mmapRegionList(1024 * 1024); 93 const b = alloc.allocate(100); 94 assert(b.length == 100); 95 }