Skip to content

Commit

Permalink
Merge pull request #5857 from BBasile/issue-16398
Browse files Browse the repository at this point in the history
fix issue 16398 - experimental allocators, add aligned reallocation for Posix
  • Loading branch information
andralex committed Nov 13, 2017
2 parents 53e5cf6 + fbe4f4e commit 0308bd6
Showing 1 changed file with 60 additions and 22 deletions.
82 changes: 60 additions & 22 deletions std/experimental/allocator/mallocator.d
Expand Up @@ -68,16 +68,14 @@ struct Mallocator
}

///
@nogc nothrow
@system unittest
@nogc @system nothrow unittest
{
auto buffer = Mallocator.instance.allocate(1024 * 1024 * 4);
scope(exit) Mallocator.instance.deallocate(buffer);
//...
}

@nogc nothrow
@system unittest
@nogc @system nothrow unittest
{
@nogc nothrow
static void test(A)()
Expand All @@ -91,8 +89,7 @@ struct Mallocator
test!Mallocator();
}

@nogc nothrow
@system unittest
@nogc @system nothrow unittest
{
static void test(A)()
{
Expand Down Expand Up @@ -280,26 +277,21 @@ struct AlignedMallocator
else static assert(0);

/**
On Posix, forwards to $(D realloc). On Windows, forwards to
$(D alignedReallocate(b, newSize, platformAlignment)).
Forwards to $(D alignedReallocate(b, newSize, platformAlignment)).
Should be used with bocks obtained with `allocate` otherwise the custom
alignment passed with `alignedAllocate` can be lost.
*/
version (Posix)
@system @nogc nothrow
bool reallocate(ref void[] b, size_t newSize) shared
{
return Mallocator.instance.reallocate(b, newSize);
}
version (Windows)
@system @nogc nothrow
bool reallocate(ref void[] b, size_t newSize) shared
{
return alignedReallocate(b, newSize, alignment);
}

/**
On Posix, uses $(D alignedAllocate) and copies data around because there is
no realloc for aligned memory. On Windows, calls
$(HTTP msdn.microsoft.com/en-US/library/y69db7sx(v=vs.80).aspx,
On Posix there is no `realloc` for aligned memory, so `alignedReallocate` emulates
the needed behavior by using `alignedAllocate` to get a new block. The existing
block is copied to the new block and then freed.
On Windows, calls $(HTTPS msdn.microsoft.com/en-us/library/y69db7sx.aspx,
$(D __aligned_realloc(b.ptr, newSize, a))).
*/
version (Windows)
Expand All @@ -318,6 +310,30 @@ struct AlignedMallocator
return true;
}

/// ditto
version (Posix)
@system @nogc nothrow
bool alignedReallocate(ref void[] b, size_t s, uint a) shared
{
if (!s)
{
deallocate(b);
b = null;
return true;
}
auto p = alignedAllocate(s, a);
if (!p.ptr)
{
return false;
}
import std.algorithm.comparison : min;
const upTo = min(s, b.length);
p[0 .. upTo] = b[0 .. upTo];
deallocate(b);
b = p;
return true;
}

/**
Returns the global instance of this allocator type. The C heap allocator is
thread-safe, therefore all of its methods and `instance` itself are
Expand All @@ -327,8 +343,7 @@ struct AlignedMallocator
}

///
@nogc nothrow
@system unittest
@nogc @system nothrow unittest
{
auto buffer = AlignedMallocator.instance.alignedAllocate(1024 * 1024 * 4,
128);
Expand All @@ -340,9 +355,32 @@ version(unittest) version(CRuntime_DigitalMars)
@nogc nothrow
size_t addr(ref void* ptr) { return cast(size_t) ptr; }

version(Posix)
@nogc @system nothrow unittest
{
// 16398 : test the "pseudo" alignedReallocate for Posix
void[] s = AlignedMallocator.instance.alignedAllocate(16, 32);
(cast(ubyte[]) s)[] = ubyte(1);
AlignedMallocator.instance.alignedReallocate(s, 32, 32);
ubyte[16] o;
o[] = 1;
assert((cast(ubyte[]) s)[0 .. 16] == o);
AlignedMallocator.instance.alignedReallocate(s, 4, 32);
assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);
AlignedMallocator.instance.alignedReallocate(s, 128, 32);
assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);
AlignedMallocator.instance.deallocate(s);

void[] c;
AlignedMallocator.instance.alignedReallocate(c, 32, 32);
assert(c.ptr);

assert(!AlignedMallocator.instance.alignedReallocate(c, size_t.max, 4096));
AlignedMallocator.instance.deallocate(c);
}

version(CRuntime_DigitalMars)
@nogc nothrow
@system unittest
@nogc @system nothrow unittest
{
void* m;

Expand Down

0 comments on commit 0308bd6

Please sign in to comment.