This commit is contained in:
Eugen Wissner 2017-01-07 09:30:42 +01:00
parent f3d48234c0
commit fb843e3473
2 changed files with 29 additions and 47 deletions

View File

@ -10,8 +10,6 @@
*/ */
module tanya.memory.allocator; module tanya.memory.allocator;
import std.typecons;
/** /**
* Abstract class implementing a basic allocator. * Abstract class implementing a basic allocator.
*/ */
@ -63,15 +61,6 @@ interface Allocator
* Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise. * Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
*/ */
bool expand(ref void[] p, in size_t size) shared nothrow @nogc; bool expand(ref void[] p, in size_t size) shared nothrow @nogc;
/**
* Returns $(D Ternary.yes) if no memory is currently allocated from this
* allocator, $(D Ternary.no) if some allocations are currently active, or
* $(D Ternary.unknown) if not supported.
*
* Returns: Whether any memory is currently allocated.
*/
Ternary empty() shared nothrow @nogc;
} }
/** /**

View File

@ -11,7 +11,7 @@
module tanya.memory.mmappool; module tanya.memory.mmappool;
import core.stdc.string; import core.stdc.string;
import std.typecons; import std.algorithm.comparison;
import tanya.memory.allocator; import tanya.memory.allocator;
version (Posix) version (Posix)
@ -245,9 +245,12 @@ final class MmapPool : Allocator
immutable dataSize = addAlignment(size); immutable dataSize = addAlignment(size);
immutable delta = dataSize - p.length; immutable delta = dataSize - p.length;
if (block1.next is null || block1.next.size + BlockEntry.sizeof < delta) if (block1.next is null
|| !block1.next.free
|| block1.next.size + BlockEntry.sizeof < delta)
{ {
// It is the last block in the region or the next block is too small. // It is the last block in the region or the next block is too small or not
// free.
return false; return false;
} }
if (block1.next.size >= delta + alignment_) if (block1.next.size >= delta + alignment_)
@ -255,9 +258,9 @@ final class MmapPool : Allocator
// We should move the start position of the next block. The order may be // We should move the start position of the next block. The order may be
// important because the old block and the new one can overlap. // important because the old block and the new one can overlap.
auto block2 = cast(Block) (p.ptr + dataSize); auto block2 = cast(Block) (p.ptr + dataSize);
block2.free = true;
block2.size = block1.next.size - delta; block2.size = block1.next.size - delta;
block2.region = block1.next.region; block2.free = true;
block2.region = block1.region;
block2.next = block1.next.next; block2.next = block1.next.next;
block2.prev = block1; block2.prev = block1;
@ -316,31 +319,34 @@ final class MmapPool : Allocator
*/ */
bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc
{ {
void[] reallocP; if (size == 0)
{
if (size == p.length) if (deallocate(p))
{
p = null;
return true;
}
return false;
}
else if (size <= p.length)
{
// Leave the block as is.
p = p.ptr[0 .. size];
return true;
}
else if (expand(p, size))
{ {
return true; return true;
} }
else if (size > 0) // Can't extend, allocate a new block, copy and delete the previous.
{ void[] reallocP = allocate(size);
reallocP = allocate(size);
if (reallocP is null) if (reallocP is null)
{ {
return false; return false;
} }
}
if (p !is null) if (p !is null)
{ {
if (size > p.length) memcpy(reallocP.ptr, p.ptr, min(p.length, size));
{
reallocP[0..p.length] = p[0..$];
}
else if (size > 0)
{
reallocP[0..size] = p[0..size];
}
deallocate(p); deallocate(p);
} }
p = reallocP; p = reallocP;
@ -501,19 +507,6 @@ final class MmapPool : Allocator
return initializeRegion(size, head); return initializeRegion(size, head);
} }
/**
* Returns $(D Ternary.yes) if no memory is currently allocated from this
* allocator, $(D Ternary.no) if some allocations are currently active, or
* $(D Ternary.unknown) if not supported.
*
* Returns: Whether any memory is currently allocated.
*/
Ternary empty() shared pure nothrow @safe @nogc
{
// MmapPool always owns some memory because it allocates itself.
return Ternary.no;
}
/* /*
* Params: * Params:
* x = Space to be aligned. * x = Space to be aligned.