Fix #3
This commit is contained in:
parent
f3d48234c0
commit
fb843e3473
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
|
if (reallocP is null)
|
||||||
{
|
{
|
||||||
reallocP = allocate(size);
|
return false;
|
||||||
if (reallocP is null)
|
|
||||||
{
|
|
||||||
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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user