summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/tanya/memory/allocator.d14
-rw-r--r--source/tanya/memory/mallocator.d39
-rw-r--r--source/tanya/memory/mmappool.d54
-rw-r--r--source/tanya/memory/package.d38
4 files changed, 93 insertions, 52 deletions
diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d
index 369a189..d47d10a 100644
--- a/source/tanya/memory/allocator.d
+++ b/source/tanya/memory/allocator.d
@@ -33,7 +33,7 @@ interface 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;
/**
* Deallocates a memory block.
@@ -43,7 +43,7 @@ interface Allocator
*
* Returns: Whether the deallocation was successful.
*/
- bool deallocate(void[] p) shared nothrow @nogc;
+ bool deallocate(void[] p) shared pure nothrow @nogc;
/**
* Increases or decreases the size of a memory block.
@@ -54,7 +54,7 @@ interface Allocator
*
* Returns: Pointer to the allocated memory.
*/
- 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;
/**
* Reallocates a memory block in place if possible or returns
@@ -69,5 +69,11 @@ interface Allocator
* Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
*/
bool reallocateInPlace(ref void[] p, const size_t size)
- shared nothrow @nogc;
+ shared pure nothrow @nogc;
+}
+
+package template GetPureInstance(T : Allocator)
+{
+ alias GetPureInstance = shared(T) function()
+ pure nothrow @nogc;
}
diff --git a/source/tanya/memory/mallocator.d b/source/tanya/memory/mallocator.d
index 887ade9..ebb8ffc 100644
--- a/source/tanya/memory/mallocator.d
+++ b/source/tanya/memory/mallocator.d
@@ -21,6 +21,13 @@ import tanya.memory.allocator;
*/
final class Mallocator : Allocator
{
+ private alias MallocType = extern (C) void* function(size_t)
+ pure nothrow @system @nogc;
+ private alias FreeType = extern (C) void function(void*)
+ pure nothrow @system @nogc;
+ private alias ReallocType = extern (C) void* function(void*, size_t)
+ pure nothrow @system @nogc;
+
/**
* Allocates $(D_PARAM size) bytes of memory.
*
@@ -29,13 +36,13 @@ final class Mallocator : Allocator
*
* Returns: The 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)
{
return null;
}
- auto p = malloc(size + psize);
+ auto p = (cast(MallocType) &malloc)(size + psize);
return p is null ? null : p[psize .. psize + size];
}
@@ -59,11 +66,11 @@ final class Mallocator : Allocator
*
* Returns: Whether the deallocation was successful.
*/
- bool deallocate(void[] p) shared nothrow @nogc
+ bool deallocate(void[] p) shared pure nothrow @nogc
{
if (p !is null)
{
- free(p.ptr - psize);
+ (cast(FreeType) &free)(p.ptr - psize);
}
return true;
}
@@ -87,7 +94,8 @@ final class Mallocator : Allocator
*
* Returns: $(D_KEYWORD false).
*/
- bool reallocateInPlace(ref void[] p, const size_t size) shared nothrow @nogc
+ bool reallocateInPlace(ref void[] p, const size_t size)
+ shared pure nothrow @nogc
{
return false;
}
@@ -108,7 +116,7 @@ final class Mallocator : 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)
{
@@ -125,7 +133,7 @@ final class Mallocator : Allocator
}
else
{
- auto r = realloc(p.ptr - psize, size + psize);
+ auto r = (cast(ReallocType) &realloc)(p.ptr - psize, size + psize);
if (r !is null)
{
@@ -177,12 +185,7 @@ final class Mallocator : Allocator
assert(Mallocator.instance.alignment == (void*).alignof);
}
- /**
- * Static allocator instance and initializer.
- *
- * Returns: The global $(D_PSYMBOL Allocator) instance.
- */
- static @property ref shared(Mallocator) instance() @nogc nothrow
+ static private shared(Mallocator) instantiate() nothrow @nogc
{
if (instance_ is null)
{
@@ -198,6 +201,16 @@ final class Mallocator : Allocator
return instance_;
}
+ /**
+ * Static allocator instance and initializer.
+ *
+ * Returns: The global $(D_PSYMBOL Allocator) instance.
+ */
+ static @property shared(Mallocator) instance() pure nothrow @nogc
+ {
+ return (cast(GetPureInstance!Mallocator) &instantiate)();
+ }
+
///
@nogc nothrow unittest
{
diff --git a/source/tanya/memory/mmappool.d b/source/tanya/memory/mmappool.d
index 9f59afc..f802247 100644
--- a/source/tanya/memory/mmappool.d
+++ b/source/tanya/memory/mmappool.d
@@ -167,7 +167,7 @@ final class MmapPool : Allocator
- MmapPool.alignment_
- BlockEntry.sizeof * 2
- RegionEntry.sizeof
- - pageSize;
+ - MmapPool.instance.pageSize;
assert(MmapPool.instance.allocate(tooMuchMemory) is null);
assert(MmapPool.instance.allocate(size_t.max) is null);
@@ -471,46 +471,52 @@ final class MmapPool : Allocator
MmapPool.instance.deallocate(p);
}
- /**
- * Static allocator instance and initializer.
- *
- * Returns: Global $(D_PSYMBOL MmapPool) instance.
- */
- static @property ref shared(MmapPool) instance() nothrow @nogc
+ static private shared(MmapPool) instantiate() nothrow @nogc
{
if (instance_ is null)
{
// Get system dependend page size.
version (Posix)
{
- pageSize_ = sysconf(_SC_PAGE_SIZE);
- if (pageSize_ < 65536)
+ size_t 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;
+ size_t pageSize = si.dwPageSize;
}
const instanceSize = addAlignment(__traits(classInstanceSize,
MmapPool));
Region head; // Will become soon our region list head
- void* data = initializeRegion(instanceSize, head);
+ void* data = initializeRegion(instanceSize, head, pageSize);
if (data !is null)
{
memcpy(data, typeid(MmapPool).initializer.ptr, instanceSize);
instance_ = cast(shared MmapPool) data;
instance_.head = head;
+ instance_.pageSize = pageSize;
}
}
return instance_;
}
+ /**
+ * Static allocator instance and initializer.
+ *
+ * Returns: Global $(D_PSYMBOL MmapPool) instance.
+ */
+ static @property shared(MmapPool) instance() pure nothrow @nogc
+ {
+ return (cast(GetPureInstance!MmapPool) &instantiate)();
+ }
+
///
nothrow unittest
{
@@ -526,10 +532,12 @@ final class MmapPool : Allocator
*
* Returns: A pointer to the data.
*/
- private static void* initializeRegion(const size_t size, ref Region head)
+ private static void* initializeRegion(const size_t size,
+ ref Region head,
+ const size_t pageSize)
pure nothrow @nogc
{
- const regionSize = calculateRegionSize(size);
+ const regionSize = calculateRegionSize(size, pageSize);
if (regionSize < size)
{
return null;
@@ -578,7 +586,7 @@ final class MmapPool : Allocator
private void* initializeRegion(const size_t size) shared pure nothrow @nogc
{
- return initializeRegion(size, head);
+ return initializeRegion(size, this.head, this.pageSize);
}
/*
@@ -594,11 +602,13 @@ final class MmapPool : Allocator
/*
* Params:
- * x = Required space.
+ * x = Required space.
+ * pageSize = Page size.
*
* Returns: Minimum region size (a multiple of $(D_PSYMBOL pageSize)).
*/
- private static size_t calculateRegionSize(const size_t x)
+ private static size_t calculateRegionSize(ref const size_t x,
+ ref const size_t pageSize)
pure nothrow @safe @nogc
{
return (x + RegionEntry.sizeof + BlockEntry.sizeof * 2)
@@ -618,18 +628,10 @@ 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 size_t pageSize;
private shared struct RegionEntry
{
diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d
index 5293f24..eef28e4 100644
--- a/source/tanya/memory/package.d
+++ b/source/tanya/memory/package.d
@@ -36,7 +36,7 @@ mixin template DefaultAllocator()
*
* Precondition: $(D_INLINECODE allocator_ !is null)
*/
- this(shared Allocator allocator)
+ this(shared Allocator allocator) pure nothrow @safe @nogc
in
{
assert(allocator !is null);
@@ -54,7 +54,7 @@ mixin template DefaultAllocator()
*
* Postcondition: $(D_INLINECODE allocator !is null)
*/
- protected @property shared(Allocator) allocator() nothrow @safe @nogc
+ protected @property shared(Allocator) allocator() pure nothrow @safe @nogc
out (allocator)
{
assert(allocator !is null);
@@ -69,7 +69,7 @@ mixin template DefaultAllocator()
}
/// Ditto.
- @property shared(Allocator) allocator() const nothrow @trusted @nogc
+ @property shared(Allocator) allocator() const pure nothrow @trusted @nogc
out (allocator)
{
assert(allocator !is null);
@@ -85,25 +85,44 @@ mixin template DefaultAllocator()
}
// From druntime
-private extern (C) void _d_monitordelete(Object h, bool det) nothrow @nogc;
+extern (C)
+private void _d_monitordelete(Object h, bool det) pure nothrow @nogc;
shared Allocator allocator;
-shared static this() nothrow @trusted @nogc
+shared static this() nothrow @nogc
{
allocator = MmapPool.instance;
}
-@property ref shared(Allocator) defaultAllocator() nothrow @safe @nogc
+private shared(Allocator) getAllocatorInstance() nothrow @nogc
+{
+ return allocator;
+}
+
+/**
+ * Returns: Default allocator.
+ *
+ * Postcondition: $(D_INLINECODE allocator !is null).
+ */
+@property shared(Allocator) defaultAllocator() pure nothrow @trusted @nogc
out (allocator)
{
assert(allocator !is null);
}
body
{
- return allocator;
+ return (cast(GetPureInstance!Allocator) &getAllocatorInstance)();
}
+/**
+ * Sets the default allocator.
+ *
+ * Params:
+ * allocator = $(D_PSYMBOL Allocator) instance.
+ *
+ * Precondition: $(D_INLINECODE allocator !is null).
+ */
@property void defaultAllocator(shared(Allocator) allocator) nothrow @safe @nogc
in
{
@@ -271,7 +290,8 @@ package(tanya) void[] finalize(T)(ref T p)
// shouldn't throw and if it does, it is an error anyway.
if (c.destructor)
{
- (cast(void function (Object) nothrow @safe @nogc) c.destructor)(ob);
+ alias DtorType = void function(Object) pure nothrow @safe @nogc;
+ (cast(DtorType) c.destructor)(ob);
}
}
while ((c = c.base) !is null);
@@ -322,7 +342,7 @@ private unittest
}
// Works with interfaces.
-private unittest
+private pure unittest
{
interface I
{