Fix block size calculation

This commit is contained in:
Eugen Wissner 2017-01-06 11:56:54 +01:00
parent 8e0b742748
commit 254b881da6
2 changed files with 33 additions and 32 deletions

View File

@ -28,7 +28,7 @@ interface Allocator
* *
* Returns: Pointer to the new allocated memory. * Returns: Pointer to the new allocated memory.
*/ */
void[] allocate(size_t size) shared nothrow @nogc; void[] allocate(in size_t size) shared nothrow @nogc;
/** /**
* Deallocates a memory block. * Deallocates a memory block.
@ -49,7 +49,7 @@ interface Allocator
* *
* Returns: Pointer to the allocated memory. * Returns: Pointer to the allocated memory.
*/ */
bool reallocate(ref void[] p, size_t size) shared nothrow @nogc; bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc;
} }
/** /**

View File

@ -58,7 +58,7 @@ final class MmapPool : Allocator
* *
* Returns: Pointer to the new allocated memory. * Returns: Pointer to the new allocated memory.
*/ */
void[] allocate(size_t size) shared nothrow @nogc void[] allocate(in size_t size) shared nothrow @nogc
{ {
if (!size) if (!size)
{ {
@ -90,11 +90,11 @@ final class MmapPool : Allocator
* into two blocks if the block is too large. * into two blocks if the block is too large.
* *
* Params: * Params:
* size = Minimum size the block should have. * size = Minimum size the block should have (aligned).
* *
* Returns: Data the block points to or $(D_KEYWORD null). * Returns: Data the block points to or $(D_KEYWORD null).
*/ */
private void* findBlock(size_t size) shared nothrow @nogc private void* findBlock(in ref size_t size) shared nothrow @nogc
{ {
Block block1; Block block1;
RegionLoop: for (auto r = head; r !is null; r = r.next) RegionLoop: for (auto r = head; r !is null; r = r.next)
@ -122,11 +122,15 @@ final class MmapPool : Allocator
block2.size = block1.size - blockEntrySize - size; block2.size = block1.size - blockEntrySize - size;
block2.region = block1.region; block2.region = block1.region;
if (block1.next !is null)
{
block1.next.prev = block2;
}
block1.next = block2; block1.next = block2;
block1.size = size; block1.size = size;
} }
block1.free = false; block1.free = false;
atomicOp!"+="(block1.region.blocks, 1); block1.region.blocks = block1.region.blocks + 1;
return cast(void*) block1 + blockEntrySize; return cast(void*) block1 + blockEntrySize;
} }
@ -170,12 +174,10 @@ final class MmapPool : Allocator
return VirtualFree(cast(void*) block.region, 0, MEM_RELEASE) == 0; return VirtualFree(cast(void*) block.region, 0, MEM_RELEASE) == 0;
} }
} }
else
{
// Merge blocks if neigbours are free. // Merge blocks if neigbours are free.
if (block.next !is null && block.next.free) if (block.next !is null && block.next.free)
{ {
block.size = blockEntrySize + block.next.size; block.size = block.size + blockEntrySize + block.next.size;
if (block.next.next !is null) if (block.next.next !is null)
{ {
block.next.next.prev = block; block.next.next.prev = block;
@ -184,7 +186,7 @@ final class MmapPool : Allocator
} }
if (block.prev !is null && block.prev.free) if (block.prev !is null && block.prev.free)
{ {
block.size = blockEntrySize + block.size; block.prev.size = block.prev.size + blockEntrySize + block.size;
if (block.next !is null) if (block.next !is null)
{ {
block.next.prev = block.prev; block.next.prev = block.prev;
@ -195,10 +197,9 @@ final class MmapPool : Allocator
{ {
block.free = true; block.free = true;
} }
atomicOp!"-="(block.region.blocks, 1); block.region.blocks = block.region.blocks - 1;
return true; return true;
} }
}
/// ///
nothrow unittest nothrow unittest
@ -217,7 +218,7 @@ final class MmapPool : Allocator
* *
* Returns: Whether the reallocation was successful. * Returns: Whether the reallocation was successful.
*/ */
bool reallocate(ref void[] p, size_t size) shared nothrow @nogc bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc
{ {
void[] reallocP; void[] reallocP;