blob: 8b4e2be9bc3a92fa90f75846bf74ffc5adde78f0 [file] [log] [blame]
@system nothrow unittest
{
import std.experimental.allocator.building_blocks.region;
import std.algorithm.comparison : max;
import std.experimental.allocator.building_blocks.allocator_list
: AllocatorList;
import std.experimental.allocator.mallocator : Mallocator;
import std.typecons : Ternary;
// Create a scalable list of regions. Each gets at least 1MB at a time by
// using malloc.
auto batchAllocator = AllocatorList!(
(size_t n) => Region!Mallocator(max(n, 1024 * 1024))
)();
assert(batchAllocator.empty == Ternary.yes);
auto b = batchAllocator.allocate(101);
assert(b.length == 101);
assert(batchAllocator.empty == Ternary.no);
// This will cause a second allocation
b = batchAllocator.allocate(2 * 1024 * 1024);
assert(b.length == 2 * 1024 * 1024);
// Destructor will free the memory
}
@system nothrow @nogc unittest
{
import std.experimental.allocator.building_blocks.region;
import std.typecons : Ternary;
ubyte[1024] store;
auto myRegion = BorrowedRegion!(1)(store[]);
assert(myRegion.empty == Ternary.yes);
assert(myRegion.available == store.length);
void[] b = myRegion.allocate(101);
assert(b.length == 101);
assert(myRegion.empty == Ternary.no);
assert(myRegion.owns(b) == Ternary.yes);
assert(myRegion.available == store.length - b.length);
void[] b2 = myRegion.allocate(256);
// Can only free the most recent allocation
assert(myRegion.deallocate(b) == false);
assert(myRegion.deallocate(b2) == true);
myRegion.deallocateAll();
assert(myRegion.empty == Ternary.yes);
}
@system unittest
{
import std.experimental.allocator.building_blocks.region;
// 128KB region, allocated to x86's cache line
InSituRegion!(128 * 1024, 16) r1;
auto a1 = r1.allocate(101);
assert(a1.length == 101);
// 128KB region, with fallback to the garbage collector.
import std.experimental.allocator.building_blocks.fallback_allocator
: FallbackAllocator;
import std.experimental.allocator.building_blocks.free_list
: FreeList;
import std.experimental.allocator.building_blocks.bitmapped_block
: BitmappedBlock;
import std.experimental.allocator.gc_allocator : GCAllocator;
FallbackAllocator!(InSituRegion!(128 * 1024), GCAllocator) r2;
const a2 = r2.allocate(102);
assert(a2.length == 102);
// Reap with GC fallback.
InSituRegion!(128 * 1024, 8) tmp3;
FallbackAllocator!(BitmappedBlock!(64, 8), GCAllocator) r3;
r3.primary = BitmappedBlock!(64, 8)(cast(ubyte[]) (tmp3.allocateAll()));
const a3 = r3.allocate(103);
assert(a3.length == 103);
// Reap/GC with a freelist for small objects up to 16 bytes.
InSituRegion!(128 * 1024, 64) tmp4;
FreeList!(FallbackAllocator!(BitmappedBlock!(64, 64), GCAllocator), 0, 16) r4;
r4.parent.primary = BitmappedBlock!(64, 64)(cast(ubyte[]) (tmp4.allocateAll()));
const a4 = r4.allocate(104);
assert(a4.length == 104);
}