summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-07-12 09:30:07 +0200
committerEugen Wissner <belka@caraus.de>2017-07-12 09:30:07 +0200
commit2bd612fd197232645e5617d8041949912e3e7918 (patch)
treef93254db42b202f705d2017f96589f4afb7384a7 /source
parentfc53779d3fc12c93c8cc933f29362b2f3fc08bf2 (diff)
downloadtanya-2bd612fd197232645e5617d8041949912e3e7918.tar.gz
Make MmapPool allocations pure
Diffstat (limited to 'source')
-rw-r--r--source/tanya/memory/mmappool.d124
1 files changed, 77 insertions, 47 deletions
diff --git a/source/tanya/memory/mmappool.d b/source/tanya/memory/mmappool.d
index 092b477..7e8dac9 100644
--- a/source/tanya/memory/mmappool.d
+++ b/source/tanya/memory/mmappool.d
@@ -18,14 +18,61 @@ import tanya.memory.allocator;
version (Posix)
{
- import core.stdc.errno;
- import core.sys.posix.sys.mman;
import core.sys.posix.unistd;
+
+ extern (C)
+ private void* mmap(void* addr,
+ size_t len,
+ int prot,
+ int flags,
+ int fd,
+ off_t offset) pure nothrow @system @nogc;
+
+ extern (C)
+ private int munmap(void* addr, size_t len) pure nothrow @system @nogc;
+
+ private void* mapMemory(const size_t len) pure nothrow @system @nogc
+ {
+ void* p = mmap(null,
+ len,
+ 0x01 | 0x02, // PROT_READ | PROT_WRITE
+ 0x0002 | 0x1000, // MAP_PRIVATE | MAP_ANON
+ -1,
+ 0);
+ return p is (cast(void*) -1) ? null : p;
+ }
+
+ private bool unmapMemory(shared void* addr, const size_t len)
+ pure nothrow @system @nogc
+ {
+ return munmap(cast(void*) addr, len) == 0;
+ }
}
else version (Windows)
{
- import core.sys.windows.winbase;
- import core.sys.windows.windows;
+ import core.sys.windows.winbase : GetSystemInfo, SYSTEM_INFO;
+
+ extern (Windows)
+ private void* VirtualAlloc(void*, size_t, uint, uint)
+ pure nothrow @system @nogc;
+
+ extern (Windows)
+ private int VirtualFree(void* addr, size_t len, uint)
+ pure nothrow @system @nogc;
+
+ private void* mapMemory(const size_t len) pure nothrow @system @nogc
+ {
+ return VirtualAlloc(null,
+ len,
+ 0x00001000, // MEM_COMMIT
+ 0x04); // PAGE_READWRITE
+ }
+
+ private bool unmapMemory(shared void* addr, const size_t len)
+ pure nothrow @system @nogc
+ {
+ return VirtualFree(cast(void*) addr, 0, 0x8000) == 0;
+ }
}
/**
@@ -78,7 +125,7 @@ final class MmapPool : Allocator
*
* Returns: Pointer to the new allocated memory.
*/
- void[] allocate(const size_t size) shared nothrow @nogc
+ void[] allocate(const size_t size) shared pure nothrow @nogc
{
if (size == 0)
{
@@ -137,7 +184,7 @@ final class MmapPool : Allocator
*
* Returns: Data the block points to or $(D_KEYWORD null).
*/
- private void* findBlock(const ref size_t size) shared nothrow @nogc
+ private void* findBlock(const ref size_t size) shared pure nothrow @nogc
{
Block block1;
RegionLoop: for (auto r = head; r !is null; r = r.next)
@@ -197,7 +244,7 @@ final class MmapPool : Allocator
*
* Returns: Whether the deallocation was successful.
*/
- bool deallocate(void[] p) shared nothrow @nogc
+ bool deallocate(void[] p) shared pure nothrow @nogc
{
if (p.ptr is null)
{
@@ -219,14 +266,7 @@ final class MmapPool : Allocator
{
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;
- }
+ return unmapMemory(block.region, block.region.size);
}
// Merge blocks if neigbours are free.
if (block.next !is null && block.next.free)
@@ -271,7 +311,7 @@ final class MmapPool : Allocator
* Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
*/
bool reallocateInPlace(ref void[] p, const size_t size)
- shared nothrow @nogc
+ pure shared nothrow @nogc
{
if (p is null || size == 0)
{
@@ -368,7 +408,7 @@ final class MmapPool : Allocator
*
* Returns: Whether the reallocation was successful.
*/
- bool reallocate(ref void[] p, const size_t size) shared nothrow @nogc
+ bool reallocate(ref void[] p, const size_t size) shared pure nothrow @nogc
{
if (size == 0)
{
@@ -441,17 +481,17 @@ final class MmapPool : Allocator
// Get system dependend page size.
version (Posix)
{
- pageSize = sysconf(_SC_PAGE_SIZE);
- if (pageSize < 65536)
+ pageSize_ = sysconf(_SC_PAGE_SIZE);
+ if (pageSize_ < 65536)
{
- pageSize = pageSize * 65536 / pageSize;
+ pageSize_ = pageSize_ * 65536 / pageSize_;
}
}
else version (Windows)
{
SYSTEM_INFO si;
GetSystemInfo(&si);
- pageSize = si.dwPageSize;
+ pageSize_ = si.dwPageSize;
}
const instanceSize = addAlignment(__traits(classInstanceSize,
@@ -485,36 +525,18 @@ final class MmapPool : Allocator
* Returns: A pointer to the data.
*/
private static void* initializeRegion(const size_t size, ref Region head)
- nothrow @nogc
+ pure nothrow @nogc
{
const regionSize = calculateRegionSize(size);
if (regionSize < size)
{
return null;
}
- 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 = mapMemory(regionSize);
+ if (p is null)
{
- void* p = VirtualAlloc(null,
- regionSize,
- MEM_COMMIT,
- PAGE_READWRITE);
- if (p is null)
- {
- return null;
- }
+ return null;
}
Region region = cast(Region) p;
@@ -552,7 +574,7 @@ final class MmapPool : Allocator
return data;
}
- private void* initializeRegion(const size_t size) shared nothrow @nogc
+ private void* initializeRegion(const size_t size) shared pure nothrow @nogc
{
return initializeRegion(size, head);
}
@@ -575,7 +597,7 @@ final class MmapPool : Allocator
* Returns: Minimum region size (a multiple of $(D_PSYMBOL pageSize)).
*/
private static size_t calculateRegionSize(const size_t x)
- nothrow @safe @nogc
+ pure nothrow @safe @nogc
{
return (x + RegionEntry.sizeof + BlockEntry.sizeof * 2)
/ pageSize * pageSize + pageSize;
@@ -594,10 +616,18 @@ final class MmapPool : Allocator
assert(MmapPool.instance.alignment == MmapPool.alignment_);
}
+ private static @property size_t pageSize() pure nothrow @trusted @nogc
+ {
+ const pageSize = function size_t() nothrow @safe @nogc {
+ return pageSize_;
+ };
+ return (cast(size_t function() pure nothrow @safe @nogc) pageSize)();
+ }
+
private enum uint alignment_ = 8;
private shared static MmapPool instance_;
- private shared static size_t pageSize;
+ private shared static size_t pageSize_;
private shared struct RegionEntry
{