Skip to content

Commit

Permalink
Merge pull request #15 from dlang-community/betterc
Browse files Browse the repository at this point in the history
BetterC & Mir rework: @nogc SharedFreeList, BitmappedBlock and imports cleanup
  • Loading branch information
wilzbach authored Oct 24, 2018
2 parents 62ff955 + 6b1aa89 commit 6a16792
Show file tree
Hide file tree
Showing 19 changed files with 302 additions and 379 deletions.
1 change: 1 addition & 0 deletions dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ description "Extracted std.experimental.allocator"
authors "Team Phobos"
copyright "Copyright © 2017, Team Phobos"
license "Boost"
dependency "mir-core" version="~>0.0.0"
17 changes: 8 additions & 9 deletions source/stdx/allocator/building_blocks/affix_allocator.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ The following methods are defined if $(D Allocator) defines them, and forward to
*/
struct AffixAllocator(Allocator, Prefix, Suffix = void)
{
import std.algorithm.comparison : min;
import std.conv : emplace;
import mir.utility : min;
import stdx.allocator.internal : emplace;
import stdx.allocator : IAllocator, theAllocator;
import stdx.allocator.common : stateSize, forwardToMember,
roundUpToMultipleOf, alignedAt, alignDownTo, roundUpToMultipleOf,
hasStaticallyKnownAlignment;
import stdx.allocator.internal : isPowerOf2;
import std.traits : hasMember;
import stdx.allocator.internal : Ternary;

static if (hasStaticallyKnownAlignment!Allocator)
Expand Down Expand Up @@ -162,7 +161,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
return result[stateSize!Prefix .. stateSize!Prefix + bytes];
}

static if (hasMember!(Allocator, "allocateAll"))
static if (__traits(hasMember, Allocator, "allocateAll"))
void[] allocateAll()
{
auto result = parent.allocateAll();
Expand Down Expand Up @@ -191,14 +190,14 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
return result;
}

static if (hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "owns"))
Ternary owns(void[] b)
{
if (b is null) return Ternary.no;
return parent.owns(actualAllocation(b));
}

static if (hasMember!(Allocator, "resolveInternalPointer"))
static if (__traits(hasMember, Allocator, "resolveInternalPointer"))
Ternary resolveInternalPointer(const void* p, ref void[] result)
{
void[] p1;
Expand All @@ -212,7 +211,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
return Ternary.yes;
}

static if (!stateSize!Suffix && hasMember!(Allocator, "expand"))
static if (!stateSize!Suffix && __traits(hasMember, Allocator, "expand"))
bool expand(ref void[] b, size_t delta)
{
if (!b.ptr) return delta == 0;
Expand All @@ -223,7 +222,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
return true;
}

static if (hasMember!(Allocator, "reallocate"))
static if (__traits(hasMember, Allocator, "reallocate"))
bool reallocate(ref void[] b, size_t s)
{
if (b is null)
Expand All @@ -238,7 +237,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
return true;
}

static if (hasMember!(Allocator, "deallocate"))
static if (__traits(hasMember, Allocator, "deallocate"))
bool deallocate(void[] b)
{
if (!b.ptr) return true;
Expand Down
61 changes: 30 additions & 31 deletions source/stdx/allocator/building_blocks/allocator_list.d
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ called `factory`.
*/
struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
{
import std.conv : emplace;
import stdx.allocator.internal : emplace;
import stdx.allocator.building_blocks.stats_collector
: StatsCollector, Options;
import std.traits : hasMember;
import stdx.allocator.internal : Ternary;

private enum ouroboros = is(BookkeepingAllocator == NullAllocator);
Expand All @@ -76,7 +75,7 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
Alias for `typeof(Factory()(1))`, i.e. the type of the individual
allocators.
*/
alias Allocator = typeof(Factory.init(1));
alias Allocator = typeof(Factory.init(size_t(1)));
// Allocator used internally
private alias SAllocator = StatsCollector!(Allocator, Options.bytesUsed);

Expand Down Expand Up @@ -142,8 +141,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
factory = plant;
}

static if (hasMember!(Allocator, "deallocateAll")
&& hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "deallocateAll")
&& __traits(hasMember, Allocator, "owns"))
~this()
{
deallocateAll;
Expand Down Expand Up @@ -236,8 +235,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
// Free the olden buffer
static if (ouroboros)
{
static if (hasMember!(Allocator, "deallocate")
&& hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "deallocate")
&& __traits(hasMember, Allocator, "owns"))
deallocate(toFree);
}
else
Expand All @@ -250,8 +249,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
private Node* addAllocator(size_t atLeastBytes)
{
void[] t = allocators;
static if (hasMember!(Allocator, "expand")
&& hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "expand")
&& __traits(hasMember, Allocator, "owns"))
{
immutable bool expanded = t && this.expand(t, Node.sizeof);
}
Expand Down Expand Up @@ -303,7 +302,7 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
private Node* addAllocator(size_t atLeastBytes)
{
void[] t = allocators;
static if (hasMember!(BookkeepingAllocator, "expand"))
static if (__traits(hasMember, BookkeepingAllocator, "expand"))
immutable bool expanded = bkalloc.expand(t, Node.sizeof);
else
immutable bool expanded = false;
Expand Down Expand Up @@ -348,7 +347,7 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
`Ternary.unknown` if no allocator returned `Ternary.yes` and at least one
returned `Ternary.unknown`.
*/
static if (hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "owns"))
Ternary owns(void[] b)
{
auto result = Ternary.no;
Expand Down Expand Up @@ -377,8 +376,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
and calls $(D expand) for it. The owner is not brought to the head of the
list.
*/
static if (hasMember!(Allocator, "expand")
&& hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "expand")
&& __traits(hasMember, Allocator, "owns"))
bool expand(ref void[] b, size_t delta)
{
if (!b.ptr) return delta == 0;
Expand All @@ -394,7 +393,7 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
$(D b) and calls $(D reallocate) for it. If that fails, calls the global
$(D reallocate), which allocates a new block and moves memory.
*/
static if (hasMember!(Allocator, "reallocate"))
static if (__traits(hasMember, Allocator, "reallocate"))
bool reallocate(ref void[] b, size_t s)
{
// First attempt to reallocate within the existing node
Expand All @@ -414,8 +413,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
/**
Defined if $(D Allocator.deallocate) and $(D Allocator.owns) are defined.
*/
static if (hasMember!(Allocator, "deallocate")
&& hasMember!(Allocator, "owns"))
static if (__traits(hasMember, Allocator, "deallocate")
&& __traits(hasMember, Allocator, "owns"))
bool deallocate(void[] b)
{
if (!b.ptr) return true;
Expand Down Expand Up @@ -457,8 +456,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
Defined only if $(D Allocator.owns) and $(D Allocator.deallocateAll) are
defined.
*/
static if (ouroboros && hasMember!(Allocator, "deallocateAll")
&& hasMember!(Allocator, "owns"))
static if (ouroboros && __traits(hasMember, Allocator, "deallocateAll")
&& __traits(hasMember, Allocator, "owns"))
bool deallocateAll()
{
Node* special;
Expand All @@ -483,8 +482,8 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
return true;
}

static if (!ouroboros && hasMember!(Allocator, "deallocateAll")
&& hasMember!(Allocator, "owns"))
static if (!ouroboros && __traits(hasMember, Allocator, "deallocateAll")
&& __traits(hasMember, Allocator, "owns"))
bool deallocateAll()
{
foreach (ref n; allocators)
Expand Down Expand Up @@ -513,7 +512,7 @@ struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator)
template AllocatorList(alias factoryFunction,
BookkeepingAllocator = GCAllocator)
{
alias A = typeof(factoryFunction(1));
alias A = typeof(factoryFunction(size_t(1)));
static assert(
// is a template function (including literals)
is(typeof({A function(size_t) @system x = factoryFunction!size_t;}))
Expand All @@ -535,7 +534,7 @@ template AllocatorList(alias factoryFunction,
///
version(Posix) @system unittest
{
import std.algorithm.comparison : max;
import mir.utility : max;
import stdx.allocator.building_blocks.free_list : ContiguousFreeList;
import stdx.allocator.building_blocks.null_allocator : NullAllocator;
import stdx.allocator.building_blocks.region : Region;
Expand All @@ -545,17 +544,17 @@ version(Posix) @system unittest

// Ouroboros allocator list based upon 4MB regions, fetched directly from
// mmap. All memory is released upon destruction.
alias A1 = AllocatorList!((n) => Region!MmapAllocator(max(n, 1024 * 4096)),
alias A1 = AllocatorList!((n) => Region!MmapAllocator(max(n, 1024u * 4096u)),
NullAllocator);

// Allocator list based upon 4MB regions, fetched from the garbage
// collector. All memory is released upon destruction.
alias A2 = AllocatorList!((n) => Region!GCAllocator(max(n, 1024 * 4096)));
alias A2 = AllocatorList!((n) => Region!GCAllocator(max(n, 1024u * 4096u)));

// Ouroboros allocator list based upon 4MB regions, fetched from the garbage
// collector. Memory is left to the collector.
alias A3 = AllocatorList!(
(n) => Region!NullAllocator(new ubyte[max(n, 1024 * 4096)]),
(n) => Region!NullAllocator(new ubyte[max(n, 1024u * 4096u)]),
NullAllocator);

// Allocator list that creates one freelist for all objects
Expand All @@ -579,9 +578,9 @@ version(Posix) @system unittest
@system unittest
{
// Create an allocator based upon 4MB regions, fetched from the GC heap.
import std.algorithm.comparison : max;
import mir.utility : max;
import stdx.allocator.building_blocks.region : Region;
AllocatorList!((n) => Region!GCAllocator(new ubyte[max(n, 1024 * 4096)]),
AllocatorList!((n) => Region!GCAllocator(new ubyte[max(n, 1024u * 4096u)]),
NullAllocator) a;
const b1 = a.allocate(1024 * 8192);
assert(b1 !is null); // still works due to overdimensioning
Expand All @@ -593,9 +592,9 @@ version(Posix) @system unittest
@system unittest
{
// Create an allocator based upon 4MB regions, fetched from the GC heap.
import std.algorithm.comparison : max;
import mir.utility : max;
import stdx.allocator.building_blocks.region : Region;
AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)])) a;
AllocatorList!((n) => Region!()(new ubyte[max(n, 1024u * 4096u)])) a;
auto b1 = a.allocate(1024 * 8192);
assert(b1 !is null); // still works due to overdimensioning
b1 = a.allocate(1024 * 10);
Expand All @@ -605,10 +604,10 @@ version(Posix) @system unittest

@system unittest
{
import std.algorithm.comparison : max;
import mir.utility : max;
import stdx.allocator.building_blocks.region : Region;
import stdx.allocator.internal : Ternary;
AllocatorList!((n) => Region!()(new ubyte[max(n, 1024 * 4096)])) a;
AllocatorList!((n) => Region!()(new ubyte[max(n, 1024u * 4096u)])) a;
auto b1 = a.allocate(1024 * 8192);
assert(b1 !is null);
b1 = a.allocate(1024 * 10);
Expand Down
Loading

0 comments on commit 6a16792

Please sign in to comment.