From e2bed0cfcb1ceb2373f200d53fd73a246fe6eaff Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 12 May 2017 21:02:24 +0200 Subject: [PATCH] Replace tabs with spaces in mmappool and buffer --- source/tanya/container/buffer.d | 10 +- source/tanya/memory/mmappool.d | 1050 +++++++++++++++---------------- 2 files changed, 530 insertions(+), 530 deletions(-) diff --git a/source/tanya/container/buffer.d b/source/tanya/container/buffer.d index 9dde930..fb11853 100644 --- a/source/tanya/container/buffer.d +++ b/source/tanya/container/buffer.d @@ -333,9 +333,9 @@ struct WriteBuffer(T = ubyte) /** * Params: - * size = Initial buffer size and the size by which the buffer will - * grow. - * allocator = Allocator. + * size = Initial buffer size and the size by which the buffer will + * grow. + * allocator = Allocator. * * Precondition: $(D_INLINECODE size > 0 && allocator !is null) */ @@ -428,7 +428,7 @@ struct WriteBuffer(T = ubyte) * Appends data to the buffer. * * Params: - * buffer = Buffer chunk got with $(D_PSYMBOL opIndex). + * buffer = Buffer chunk got with $(D_PSYMBOL opIndex). */ ref WriteBuffer opOpAssign(string op)(in T[] buffer) if (op == "~") @@ -535,7 +535,7 @@ struct WriteBuffer(T = ubyte) * appropriately. Always call it after $(D_PSYMBOL opIndex). * * Params: - * length = Length of the written data. + * length = Length of the written data. * * Returns: $(D_KEYWORD this). */ diff --git a/source/tanya/memory/mmappool.d b/source/tanya/memory/mmappool.d index d7a2e5e..5adbf10 100644 --- a/source/tanya/memory/mmappool.d +++ b/source/tanya/memory/mmappool.d @@ -16,14 +16,14 @@ import tanya.memory.allocator; version (Posix) { - import core.stdc.errno; - import core.sys.posix.sys.mman; - import core.sys.posix.unistd; + import core.stdc.errno; + import core.sys.posix.sys.mman; + import core.sys.posix.unistd; } else version (Windows) { - import core.sys.windows.winbase; - import core.sys.windows.windows; + import core.sys.windows.winbase; + import core.sys.windows.windows; } /** @@ -50,596 +50,596 @@ else version (Windows) */ final class MmapPool : Allocator { - invariant - { - for (auto r = &head; *r !is null; r = &((*r).next)) - { - auto block = cast(Block) (cast(void*) *r + RegionEntry.sizeof); - do - { - assert(block.prev is null || block.prev.next is block); - assert(block.next is null || block.next.prev is block); - assert(block.region is *r); - } - while ((block = block.next) !is null); - } - } + invariant + { + for (auto r = &head; *r !is null; r = &((*r).next)) + { + auto block = cast(Block) (cast(void*) *r + RegionEntry.sizeof); + do + { + assert(block.prev is null || block.prev.next is block); + assert(block.next is null || block.next.prev is block); + assert(block.region is *r); + } + while ((block = block.next) !is null); + } + } - /** - * Allocates $(D_PARAM size) bytes of memory. - * - * Params: - * size = Amount of memory to allocate. - * - * Returns: Pointer to the new allocated memory. - */ - void[] allocate(in size_t size) shared nothrow @nogc - { - if (!size) - { - return null; - } - immutable dataSize = addAlignment(size); + /** + * Allocates $(D_PARAM size) bytes of memory. + * + * Params: + * size = Amount of memory to allocate. + * + * Returns: Pointer to the new allocated memory. + */ + void[] allocate(in size_t size) shared nothrow @nogc + { + if (!size) + { + return null; + } + immutable dataSize = addAlignment(size); - void* data = findBlock(dataSize); - if (data is null) - { - data = initializeRegion(dataSize); - } + void* data = findBlock(dataSize); + if (data is null) + { + data = initializeRegion(dataSize); + } - return data is null ? null : data[0 .. size]; - } + return data is null ? null : data[0 .. size]; + } - /// - nothrow unittest - { - auto p = MmapPool.instance.allocate(20); + /// + nothrow unittest + { + auto p = MmapPool.instance.allocate(20); - assert(p); + assert(p); - MmapPool.instance.deallocate(p); - } + MmapPool.instance.deallocate(p); + } - /** - * Search for a block large enough to keep $(D_PARAM size) and split it - * into two blocks if the block is too large. - * - * Params: - * size = Minimum size the block should have (aligned). - * - * Returns: Data the block points to or $(D_KEYWORD null). - */ - private void* findBlock(in ref size_t size) shared nothrow @nogc - { - Block block1; - RegionLoop: for (auto r = head; r !is null; r = r.next) - { - block1 = cast(Block) (cast(void*) r + RegionEntry.sizeof); - do - { - if (block1.free && block1.size >= size) - { - break RegionLoop; - } - } - while ((block1 = block1.next) !is null); - } - if (block1 is null) - { - return null; - } - else if (block1.size >= size + alignment_ + BlockEntry.sizeof) - { // Split the block if needed - Block block2 = cast(Block) (cast(void*) block1 + BlockEntry.sizeof + size); - block2.prev = block1; - block2.next = block1.next; - block2.free = true; - block2.size = block1.size - BlockEntry.sizeof - size; - block2.region = block1.region; + /** + * Search for a block large enough to keep $(D_PARAM size) and split it + * into two blocks if the block is too large. + * + * Params: + * size = Minimum size the block should have (aligned). + * + * Returns: Data the block points to or $(D_KEYWORD null). + */ + private void* findBlock(in ref size_t size) shared nothrow @nogc + { + Block block1; + RegionLoop: for (auto r = head; r !is null; r = r.next) + { + block1 = cast(Block) (cast(void*) r + RegionEntry.sizeof); + do + { + if (block1.free && block1.size >= size) + { + break RegionLoop; + } + } + while ((block1 = block1.next) !is null); + } + if (block1 is null) + { + return null; + } + else if (block1.size >= size + alignment_ + BlockEntry.sizeof) + { // Split the block if needed + Block block2 = cast(Block) (cast(void*) block1 + BlockEntry.sizeof + size); + block2.prev = block1; + block2.next = block1.next; + block2.free = true; + block2.size = block1.size - BlockEntry.sizeof - size; + block2.region = block1.region; - if (block1.next !is null) - { - block1.next.prev = block2; - } - block1.next = block2; - block1.size = size; - } - block1.free = false; - block1.region.blocks = block1.region.blocks + 1; + if (block1.next !is null) + { + block1.next.prev = block2; + } + block1.next = block2; + block1.size = size; + } + block1.free = false; + block1.region.blocks = block1.region.blocks + 1; - return cast(void*) block1 + BlockEntry.sizeof; - } + return cast(void*) block1 + BlockEntry.sizeof; + } - // Merge block with the next one. - private void mergeNext(Block block) shared const pure nothrow @safe @nogc - { - block.size = block.size + BlockEntry.sizeof + block.next.size; - if (block.next.next !is null) - { - block.next.next.prev = block; - } - block.next = block.next.next; - } + // Merge block with the next one. + private void mergeNext(Block block) shared const pure nothrow @safe @nogc + { + block.size = block.size + BlockEntry.sizeof + block.next.size; + if (block.next.next !is null) + { + block.next.next.prev = block; + } + block.next = block.next.next; + } - /** - * Deallocates a memory block. - * - * Params: - * p = A pointer to the memory block to be freed. - * - * Returns: Whether the deallocation was successful. - */ - bool deallocate(void[] p) shared nothrow @nogc - { - if (p.ptr is null) - { - return true; - } + /** + * Deallocates a memory block. + * + * Params: + * p = A pointer to the memory block to be freed. + * + * Returns: Whether the deallocation was successful. + */ + bool deallocate(void[] p) shared nothrow @nogc + { + if (p.ptr is null) + { + return true; + } - Block block = cast(Block) (p.ptr - BlockEntry.sizeof); - if (block.region.blocks <= 1) - { - if (block.region.prev !is null) - { - block.region.prev.next = block.region.next; - } - else // Replace the list head. It is being deallocated - { - head = block.region.next; - } - if (block.region.next !is null) - { - block.region.next.prev = block.region.prev; - } - version (Posix) - { - return munmap(cast(void*) block.region, block.region.size) == 0; - } - version (Windows) - { - return VirtualFree(cast(void*) block.region, 0, MEM_RELEASE) == 0; - } - } - // Merge blocks if neigbours are free. - if (block.next !is null && block.next.free) - { - mergeNext(block); - } - if (block.prev !is null && block.prev.free) - { - block.prev.size = block.prev.size + BlockEntry.sizeof + block.size; - if (block.next !is null) - { - block.next.prev = block.prev; - } - block.prev.next = block.next; - } - else - { - block.free = true; - } - block.region.blocks = block.region.blocks - 1; - return true; - } + Block block = cast(Block) (p.ptr - BlockEntry.sizeof); + if (block.region.blocks <= 1) + { + if (block.region.prev !is null) + { + block.region.prev.next = block.region.next; + } + else // Replace the list head. It is being deallocated + { + head = block.region.next; + } + if (block.region.next !is null) + { + block.region.next.prev = block.region.prev; + } + version (Posix) + { + return munmap(cast(void*) block.region, block.region.size) == 0; + } + version (Windows) + { + return VirtualFree(cast(void*) block.region, 0, MEM_RELEASE) == 0; + } + } + // Merge blocks if neigbours are free. + if (block.next !is null && block.next.free) + { + mergeNext(block); + } + if (block.prev !is null && block.prev.free) + { + block.prev.size = block.prev.size + BlockEntry.sizeof + block.size; + if (block.next !is null) + { + block.next.prev = block.prev; + } + block.prev.next = block.next; + } + else + { + block.free = true; + } + block.region.blocks = block.region.blocks - 1; + return true; + } - /// - nothrow unittest - { - auto p = MmapPool.instance.allocate(20); + /// + nothrow unittest + { + auto p = MmapPool.instance.allocate(20); - assert(MmapPool.instance.deallocate(p)); - } + assert(MmapPool.instance.deallocate(p)); + } - /** - * Reallocates a memory block in place if possible or returns - * $(D_KEYWORD false). This function cannot be used to allocate or - * deallocate memory, so if $(D_PARAM p) is $(D_KEYWORD null) or - * $(D_PARAM size) is `0`, it should return $(D_KEYWORD false). - * - * Params: - * p = A pointer to the memory block. - * size = Size of the reallocated block. - * - * Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise. - */ - bool reallocateInPlace(ref void[] p, in size_t size) shared nothrow @nogc - { - if (p is null || size == 0) - { - return false; - } - if (size <= p.length) - { - // Leave the block as is. - p = p.ptr[0 .. size]; - return true; - } - Block block1 = cast(Block) (p.ptr - BlockEntry.sizeof); + /** + * Reallocates a memory block in place if possible or returns + * $(D_KEYWORD false). This function cannot be used to allocate or + * deallocate memory, so if $(D_PARAM p) is $(D_KEYWORD null) or + * $(D_PARAM size) is `0`, it should return $(D_KEYWORD false). + * + * Params: + * p = A pointer to the memory block. + * size = Size of the reallocated block. + * + * Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise. + */ + bool reallocateInPlace(ref void[] p, in size_t size) shared nothrow @nogc + { + if (p is null || size == 0) + { + return false; + } + if (size <= p.length) + { + // Leave the block as is. + p = p.ptr[0 .. size]; + return true; + } + Block block1 = cast(Block) (p.ptr - BlockEntry.sizeof); - if (block1.size >= size) - { - // Enough space in the current block. Can happen because of the alignment. - p = p.ptr[0 .. size]; - return true; - } - immutable dataSize = addAlignment(size); - immutable delta = dataSize - addAlignment(p.length); + if (block1.size >= size) + { + // Enough space in the current block. Can happen because of the alignment. + p = p.ptr[0 .. size]; + return true; + } + immutable dataSize = addAlignment(size); + immutable delta = dataSize - addAlignment(p.length); - 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 or not - // free. - return false; - } - if (block1.next.size >= delta + alignment_) - { - // Move size from block2 to block1. - block1.next.size = block1.next.size - delta; - block1.size = block1.size + 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 or not + // free. + return false; + } + if (block1.next.size >= delta + alignment_) + { + // Move size from block2 to block1. + block1.next.size = block1.next.size - delta; + block1.size = block1.size + delta; - auto block2 = cast(Block) (p.ptr + dataSize); - if (block1.next.next !is null) - { - block1.next.next.prev = block2; - } - // block1.next and block2 can overlap. - memmove(cast(void*) block2, cast(void*) block1.next, BlockEntry.sizeof); - block1.next = block2; - } - else - { - // The next block has enough space, but is too small for further - // allocations. Merge it with the current block. - mergeNext(block1); - } + auto block2 = cast(Block) (p.ptr + dataSize); + if (block1.next.next !is null) + { + block1.next.next.prev = block2; + } + // block1.next and block2 can overlap. + memmove(cast(void*) block2, cast(void*) block1.next, BlockEntry.sizeof); + block1.next = block2; + } + else + { + // The next block has enough space, but is too small for further + // allocations. Merge it with the current block. + mergeNext(block1); + } - p = p.ptr[0 .. size]; - return true; - } + p = p.ptr[0 .. size]; + return true; + } - /// - nothrow unittest - { - void[] p; - assert(!MmapPool.instance.reallocateInPlace(p, 5)); - assert(p is null); + /// + nothrow unittest + { + void[] p; + assert(!MmapPool.instance.reallocateInPlace(p, 5)); + assert(p is null); - p = MmapPool.instance.allocate(1); - auto orig = p.ptr; + p = MmapPool.instance.allocate(1); + auto orig = p.ptr; - assert(MmapPool.instance.reallocateInPlace(p, 2)); - assert(p.length == 2); - assert(p.ptr == orig); + assert(MmapPool.instance.reallocateInPlace(p, 2)); + assert(p.length == 2); + assert(p.ptr == orig); - assert(MmapPool.instance.reallocateInPlace(p, 4)); - assert(p.length == 4); - assert(p.ptr == orig); + assert(MmapPool.instance.reallocateInPlace(p, 4)); + assert(p.length == 4); + assert(p.ptr == orig); - assert(MmapPool.instance.reallocateInPlace(p, 2)); - assert(p.length == 2); - assert(p.ptr == orig); + assert(MmapPool.instance.reallocateInPlace(p, 2)); + assert(p.length == 2); + assert(p.ptr == orig); - MmapPool.instance.deallocate(p); - } + MmapPool.instance.deallocate(p); + } - /** - * Increases or decreases the size of a memory block. - * - * Params: - * p = A pointer to the memory block. - * size = Size of the reallocated block. - * - * Returns: Whether the reallocation was successful. - */ - bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc - { - if (size == 0) - { - if (deallocate(p)) - { - p = null; - return true; - } - return false; - } - else if (reallocateInPlace(p, size)) - { - return true; - } - // Can't reallocate in place, allocate a new block, - // copy and delete the previous one. - void[] reallocP = allocate(size); - if (reallocP is null) - { - return false; - } - if (p !is null) - { - memcpy(reallocP.ptr, p.ptr, min(p.length, size)); - deallocate(p); - } - p = reallocP; + /** + * Increases or decreases the size of a memory block. + * + * Params: + * p = A pointer to the memory block. + * size = Size of the reallocated block. + * + * Returns: Whether the reallocation was successful. + */ + bool reallocate(ref void[] p, in size_t size) shared nothrow @nogc + { + if (size == 0) + { + if (deallocate(p)) + { + p = null; + return true; + } + return false; + } + else if (reallocateInPlace(p, size)) + { + return true; + } + // Can't reallocate in place, allocate a new block, + // copy and delete the previous one. + void[] reallocP = allocate(size); + if (reallocP is null) + { + return false; + } + if (p !is null) + { + memcpy(reallocP.ptr, p.ptr, min(p.length, size)); + deallocate(p); + } + p = reallocP; - return true; - } + return true; + } - /// - nothrow unittest - { - void[] p; - MmapPool.instance.reallocate(p, 10 * int.sizeof); - (cast(int[]) p)[7] = 123; + /// + nothrow unittest + { + void[] p; + MmapPool.instance.reallocate(p, 10 * int.sizeof); + (cast(int[]) p)[7] = 123; - assert(p.length == 40); + assert(p.length == 40); - MmapPool.instance.reallocate(p, 8 * int.sizeof); + MmapPool.instance.reallocate(p, 8 * int.sizeof); - assert(p.length == 32); - assert((cast(int[]) p)[7] == 123); + assert(p.length == 32); + assert((cast(int[]) p)[7] == 123); - MmapPool.instance.reallocate(p, 20 * int.sizeof); - (cast(int[]) p)[15] = 8; + MmapPool.instance.reallocate(p, 20 * int.sizeof); + (cast(int[]) p)[15] = 8; - assert(p.length == 80); - assert((cast(int[]) p)[15] == 8); - assert((cast(int[]) p)[7] == 123); + assert(p.length == 80); + assert((cast(int[]) p)[15] == 8); + assert((cast(int[]) p)[7] == 123); - MmapPool.instance.reallocate(p, 8 * int.sizeof); + MmapPool.instance.reallocate(p, 8 * int.sizeof); - assert(p.length == 32); - assert((cast(int[]) p)[7] == 123); + assert(p.length == 32); + assert((cast(int[]) p)[7] == 123); - MmapPool.instance.deallocate(p); - } + MmapPool.instance.deallocate(p); + } - /** - * Static allocator instance and initializer. - * - * Returns: Global $(D_PSYMBOL MmapPool) instance. - */ - static @property ref shared(MmapPool) instance() nothrow @nogc - { - if (instance_ is null) - { - // Get system dependend page size. - version (Posix) - { - pageSize = sysconf(_SC_PAGE_SIZE); - if (pageSize < 65536) - { - pageSize = pageSize * 65536 / pageSize; - } - } - else version (Windows) - { - SYSTEM_INFO si; - GetSystemInfo(&si); - pageSize = si.dwPageSize; - } + /** + * Static allocator instance and initializer. + * + * Returns: Global $(D_PSYMBOL MmapPool) instance. + */ + static @property ref shared(MmapPool) instance() nothrow @nogc + { + if (instance_ is null) + { + // Get system dependend page size. + version (Posix) + { + pageSize = sysconf(_SC_PAGE_SIZE); + if (pageSize < 65536) + { + pageSize = pageSize * 65536 / pageSize; + } + } + else version (Windows) + { + SYSTEM_INFO si; + GetSystemInfo(&si); + pageSize = si.dwPageSize; + } - immutable instanceSize = addAlignment(__traits(classInstanceSize, MmapPool)); + immutable instanceSize = addAlignment(__traits(classInstanceSize, MmapPool)); - Region head; // Will become soon our region list head - void* data = initializeRegion(instanceSize, head); - if (data !is null) - { - memcpy(data, typeid(MmapPool).initializer.ptr, instanceSize); - instance_ = cast(shared MmapPool) data; - instance_.head = head; - } - } - return instance_; - } + Region head; // Will become soon our region list head + void* data = initializeRegion(instanceSize, head); + if (data !is null) + { + memcpy(data, typeid(MmapPool).initializer.ptr, instanceSize); + instance_ = cast(shared MmapPool) data; + instance_.head = head; + } + } + return instance_; + } - /// - nothrow unittest - { - assert(instance is instance); - } + /// + nothrow unittest + { + assert(instance is instance); + } - /* - * Initializes a region for one element. - * - * Params: - * size = Aligned size of the first data block in the region. - * head = Region list head. - * - * Returns: A pointer to the data. - */ - private static void* initializeRegion(size_t size, ref Region head) - nothrow @nogc - { - immutable regionSize = calculateRegionSize(size); - - version (Posix) - { - void* p = mmap(null, - regionSize, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, - -1, - 0); - if (p is MAP_FAILED) - { - return null; - } - } - else version (Windows) - { - void* p = VirtualAlloc(null, - regionSize, - MEM_COMMIT, - PAGE_READWRITE); - if (p is null) - { - return null; - } - } + /* + * Initializes a region for one element. + * + * Params: + * size = Aligned size of the first data block in the region. + * head = Region list head. + * + * Returns: A pointer to the data. + */ + private static void* initializeRegion(size_t size, ref Region head) + nothrow @nogc + { + immutable regionSize = calculateRegionSize(size); - Region region = cast(Region) p; - region.blocks = 1; - region.size = regionSize; + version (Posix) + { + void* p = mmap(null, + regionSize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, + -1, + 0); + if (p is MAP_FAILED) + { + return null; + } + } + else version (Windows) + { + void* p = VirtualAlloc(null, + regionSize, + MEM_COMMIT, + PAGE_READWRITE); + if (p is null) + { + return null; + } + } - // Set the pointer to the head of the region list - if (head !is null) - { - head.prev = region; - } - region.next = head; - region.prev = null; - head = region; + Region region = cast(Region) p; + region.blocks = 1; + region.size = regionSize; - // Initialize the data block - void* memoryPointer = p + RegionEntry.sizeof; - Block block1 = cast(Block) memoryPointer; - block1.size = size; - block1.free = false; + // Set the pointer to the head of the region list + if (head !is null) + { + head.prev = region; + } + region.next = head; + region.prev = null; + head = region; - // It is what we want to return - void* data = memoryPointer + BlockEntry.sizeof; + // Initialize the data block + void* memoryPointer = p + RegionEntry.sizeof; + Block block1 = cast(Block) memoryPointer; + block1.size = size; + block1.free = false; - // Free block after data - memoryPointer = data + size; - Block block2 = cast(Block) memoryPointer; - block1.prev = block2.next = null; - block1.next = block2; - block2.prev = block1; - block2.size = regionSize - size - RegionEntry.sizeof - BlockEntry.sizeof * 2; - block2.free = true; - block1.region = block2.region = region; + // It is what we want to return + void* data = memoryPointer + BlockEntry.sizeof; - return data; - } + // Free block after data + memoryPointer = data + size; + Block block2 = cast(Block) memoryPointer; + block1.prev = block2.next = null; + block1.next = block2; + block2.prev = block1; + block2.size = regionSize - size - RegionEntry.sizeof - BlockEntry.sizeof * 2; + block2.free = true; + block1.region = block2.region = region; - private void* initializeRegion(size_t size) shared nothrow @nogc - { - return initializeRegion(size, head); - } + return data; + } - /* - * Params: - * x = Space to be aligned. - * - * Returns: Aligned size of $(D_PARAM x). - */ - private static immutable(size_t) addAlignment(size_t x) - pure nothrow @safe @nogc - out (result) - { - assert(result > 0); - } - body - { - return (x - 1) / alignment_ * alignment_ + alignment_; - } + private void* initializeRegion(size_t size) shared nothrow @nogc + { + return initializeRegion(size, head); + } - /* - * Params: - * x = Required space. - * - * Returns: Minimum region size (a multiple of $(D_PSYMBOL pageSize)). - */ - private static immutable(size_t) calculateRegionSize(size_t x) - nothrow @safe @nogc - out (result) - { - assert(result > 0); - } - body - { - x += RegionEntry.sizeof + BlockEntry.sizeof * 2; - return x / pageSize * pageSize + pageSize; - } + /* + * Params: + * x = Space to be aligned. + * + * Returns: Aligned size of $(D_PARAM x). + */ + private static immutable(size_t) addAlignment(size_t x) + pure nothrow @safe @nogc + out (result) + { + assert(result > 0); + } + body + { + return (x - 1) / alignment_ * alignment_ + alignment_; + } - /** - * Returns: Alignment offered. - */ - @property uint alignment() shared const pure nothrow @safe @nogc - { - return alignment_; - } - private enum alignment_ = 8; + /* + * Params: + * x = Required space. + * + * Returns: Minimum region size (a multiple of $(D_PSYMBOL pageSize)). + */ + private static immutable(size_t) calculateRegionSize(size_t x) + nothrow @safe @nogc + out (result) + { + assert(result > 0); + } + body + { + x += RegionEntry.sizeof + BlockEntry.sizeof * 2; + return x / pageSize * pageSize + pageSize; + } - private shared static MmapPool instance_; - private shared static size_t pageSize; + /** + * Returns: Alignment offered. + */ + @property uint alignment() shared const pure nothrow @safe @nogc + { + return alignment_; + } + private enum alignment_ = 8; - private shared struct RegionEntry - { - Region prev; - Region next; - uint blocks; - size_t size; - } - private alias Region = shared RegionEntry*; - private shared Region head; + private shared static MmapPool instance_; + private shared static size_t pageSize; - private shared struct BlockEntry - { - Block prev; - Block next; - Region region; - size_t size; - bool free; - } - private alias Block = shared BlockEntry*; + private shared struct RegionEntry + { + Region prev; + Region next; + uint blocks; + size_t size; + } + private alias Region = shared RegionEntry*; + private shared Region head; + + private shared struct BlockEntry + { + Block prev; + Block next; + Region region; + size_t size; + bool free; + } + private alias Block = shared BlockEntry*; } // A lot of allocations/deallocations, but it is the minimum caused a // segmentation fault because MmapPool reallocateInPlace moves a block wrong. unittest { - auto a = MmapPool.instance.allocate(16); - auto d = MmapPool.instance.allocate(16); - auto b = MmapPool.instance.allocate(16); - auto e = MmapPool.instance.allocate(16); - auto c = MmapPool.instance.allocate(16); - auto f = MmapPool.instance.allocate(16); + auto a = MmapPool.instance.allocate(16); + auto d = MmapPool.instance.allocate(16); + auto b = MmapPool.instance.allocate(16); + auto e = MmapPool.instance.allocate(16); + auto c = MmapPool.instance.allocate(16); + auto f = MmapPool.instance.allocate(16); - MmapPool.instance.deallocate(a); - MmapPool.instance.deallocate(b); - MmapPool.instance.deallocate(c); + MmapPool.instance.deallocate(a); + MmapPool.instance.deallocate(b); + MmapPool.instance.deallocate(c); - a = MmapPool.instance.allocate(50); - MmapPool.instance.reallocateInPlace(a, 64); - MmapPool.instance.deallocate(a); + a = MmapPool.instance.allocate(50); + MmapPool.instance.reallocateInPlace(a, 64); + MmapPool.instance.deallocate(a); - a = MmapPool.instance.allocate(1); - auto tmp1 = MmapPool.instance.allocate(1); - auto h1 = MmapPool.instance.allocate(1); - auto tmp2 = cast(ubyte[]) MmapPool.instance.allocate(1); + a = MmapPool.instance.allocate(1); + auto tmp1 = MmapPool.instance.allocate(1); + auto h1 = MmapPool.instance.allocate(1); + auto tmp2 = cast(ubyte[]) MmapPool.instance.allocate(1); - auto h2 = MmapPool.instance.allocate(2); - tmp1 = MmapPool.instance.allocate(1); - MmapPool.instance.deallocate(h2); - MmapPool.instance.deallocate(h1); + auto h2 = MmapPool.instance.allocate(2); + tmp1 = MmapPool.instance.allocate(1); + MmapPool.instance.deallocate(h2); + MmapPool.instance.deallocate(h1); - h2 = MmapPool.instance.allocate(2); - h1 = MmapPool.instance.allocate(1); - MmapPool.instance.deallocate(h2); + h2 = MmapPool.instance.allocate(2); + h1 = MmapPool.instance.allocate(1); + MmapPool.instance.deallocate(h2); - auto rep = cast(void[]) tmp2; - MmapPool.instance.reallocate(rep, tmp1.length); - tmp2 = cast(ubyte[]) rep; + auto rep = cast(void[]) tmp2; + MmapPool.instance.reallocate(rep, tmp1.length); + tmp2 = cast(ubyte[]) rep; - MmapPool.instance.reallocate(tmp1, 9); + MmapPool.instance.reallocate(tmp1, 9); - rep = cast(void[]) tmp2; - MmapPool.instance.reallocate(rep, tmp1.length); - tmp2 = cast(ubyte[]) rep; - MmapPool.instance.reallocate(tmp1, 17); + rep = cast(void[]) tmp2; + MmapPool.instance.reallocate(rep, tmp1.length); + tmp2 = cast(ubyte[]) rep; + MmapPool.instance.reallocate(tmp1, 17); - tmp2[$ - 1] = 0; + tmp2[$ - 1] = 0; - MmapPool.instance.deallocate(tmp1); + MmapPool.instance.deallocate(tmp1); - b = MmapPool.instance.allocate(16); + b = MmapPool.instance.allocate(16); - MmapPool.instance.deallocate(h1); - MmapPool.instance.deallocate(a); - MmapPool.instance.deallocate(b); - MmapPool.instance.deallocate(d); - MmapPool.instance.deallocate(e); - MmapPool.instance.deallocate(f); + MmapPool.instance.deallocate(h1); + MmapPool.instance.deallocate(a); + MmapPool.instance.deallocate(b); + MmapPool.instance.deallocate(d); + MmapPool.instance.deallocate(e); + MmapPool.instance.deallocate(f); }