summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x64/linux/syscall.S41
-rw-r--r--source/tanya/memory/allocator.d6
-rw-r--r--source/tanya/memory/mallocator.d37
-rw-r--r--source/tanya/memory/mmappool.d131
-rw-r--r--source/tanya/sys/linux/syscall.d47
-rw-r--r--source/tanya/sys/posix/mman.d31
6 files changed, 169 insertions, 124 deletions
diff --git a/arch/x64/linux/syscall.S b/arch/x64/linux/syscall.S
index 9261d87..7c00036 100644
--- a/arch/x64/linux/syscall.S
+++ b/arch/x64/linux/syscall.S
@@ -22,44 +22,31 @@ syscall1:
ret
- .globl syscall2
- .type syscall2, @function
+// 2 parameters.
+ .globl _D5tanya3sys5linux7syscall7syscallFNbNilllZl
+ .type _D5tanya3sys5linux7syscall7syscallFNbNilllZl, @function
-syscall2:
- // Store registers.
- movq %rdi, %r8
-
- movq %rdx, %rax // Syscall number.
-
- // Syscall arguments.
- movq %rsi, %rdi
- movq %r8, %rsi
+_D5tanya3sys5linux7syscall7syscallFNbNilllZl:
+ movq %rdx, %rax
syscall
- // Restore registers.
- movq %rdi, %rsi
- movq %r8, %rdi
-
ret
- .globl syscall3
- .type syscall3, @function
+// 6 parameters.
+ .globl _D5tanya3sys5linux7syscall7syscallFNbNilllllllZl
+ .type _D5tanya3sys5linux7syscall7syscallFNbNilllllllZl, @function
-syscall3:
- // Store registers.
- movq %rdi, %r8
+_D5tanya3sys5linux7syscall7syscallFNbNilllllllZl:
+ pushq %rbp
+ movq %rsp, %rbp
- movq %rcx, %rax // Syscall number.
+ movq 16(%rbp), %rax
- // Syscall arguments.
- movq %rdx, %rdi
- movq %r8, %rdx
+ mov %rcx, %r10
syscall
- // Restore registers.
- movq %r8, %rdi
-
+ leave
ret
diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d
index 0eaff65..1d8139d 100644
--- a/source/tanya/memory/allocator.d
+++ b/source/tanya/memory/allocator.d
@@ -35,7 +35,7 @@ interface Allocator
*
* Returns: Pointer to the new allocated memory.
*/
- void[] allocate(const size_t size) shared pure nothrow @nogc;
+ void[] allocate(size_t size) shared pure nothrow @nogc;
/**
* Deallocates a memory block.
@@ -56,7 +56,7 @@ interface Allocator
*
* Returns: Pointer to the allocated memory.
*/
- bool reallocate(ref void[] p, const size_t size) shared pure nothrow @nogc;
+ bool reallocate(ref void[] p, size_t size) shared pure nothrow @nogc;
/**
* Reallocates a memory block in place if possible or returns
@@ -70,7 +70,7 @@ interface Allocator
*
* Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
*/
- bool reallocateInPlace(ref void[] p, const size_t size)
+ bool reallocateInPlace(ref void[] p, size_t size)
shared pure nothrow @nogc;
}
diff --git a/source/tanya/memory/mallocator.d b/source/tanya/memory/mallocator.d
index ce868b8..f9e65cd 100644
--- a/source/tanya/memory/mallocator.d
+++ b/source/tanya/memory/mallocator.d
@@ -29,11 +29,11 @@ import tanya.memory.allocator;
final class Mallocator : Allocator
{
private alias MallocType = extern (C) void* function(size_t)
- pure nothrow @system @nogc;
+ @nogc nothrow pure @system;
private alias FreeType = extern (C) void function(void*)
- pure nothrow @system @nogc;
+ @nogc nothrow pure @system;
private alias ReallocType = extern (C) void* function(void*, size_t)
- pure nothrow @system @nogc;
+ @nogc nothrow pure @system;
/**
* Allocates $(D_PARAM size) bytes of memory.
@@ -43,7 +43,7 @@ final class Mallocator : Allocator
*
* Returns: The pointer to the new allocated memory.
*/
- void[] allocate(const size_t size) shared pure nothrow @nogc
+ void[] allocate(size_t size) @nogc nothrow pure shared @system
{
if (size == 0)
{
@@ -55,7 +55,7 @@ final class Mallocator : Allocator
}
///
- @nogc nothrow unittest
+ @nogc nothrow pure @system unittest
{
auto p = Mallocator.instance.allocate(20);
assert(p.length == 20);
@@ -73,7 +73,7 @@ final class Mallocator : Allocator
*
* Returns: Whether the deallocation was successful.
*/
- bool deallocate(void[] p) shared pure nothrow @nogc
+ bool deallocate(void[] p) @nogc nothrow pure shared @system
{
if (p !is null)
{
@@ -83,7 +83,7 @@ final class Mallocator : Allocator
}
///
- @nogc nothrow unittest
+ @nogc nothrow pure @system unittest
{
void[] p;
assert(Mallocator.instance.deallocate(p));
@@ -101,14 +101,14 @@ final class Mallocator : Allocator
*
* Returns: $(D_KEYWORD false).
*/
- bool reallocateInPlace(ref void[] p, const size_t size)
- shared pure nothrow @nogc
+ bool reallocateInPlace(ref void[] p, size_t size)
+ @nogc nothrow pure shared @system
{
return false;
}
///
- @nogc nothrow unittest
+ @nogc nothrow pure @system unittest
{
void[] p;
assert(!Mallocator.instance.reallocateInPlace(p, 8));
@@ -123,7 +123,8 @@ final class Mallocator : Allocator
*
* Returns: Whether the reallocation was successful.
*/
- bool reallocate(ref void[] p, const size_t size) shared pure nothrow @nogc
+ bool reallocate(ref void[] p, size_t size)
+ @nogc nothrow pure shared @system
{
if (size == 0)
{
@@ -152,7 +153,7 @@ final class Mallocator : Allocator
}
///
- @nogc nothrow unittest
+ @nogc nothrow pure @system unittest
{
void[] p;
@@ -169,8 +170,8 @@ final class Mallocator : Allocator
assert(p is null);
}
- // Fails with false.
- private @nogc nothrow unittest
+ // Fails with false
+ @nogc nothrow pure @system unittest
{
void[] p = Mallocator.instance.allocate(20);
void[] oldP = p;
@@ -182,7 +183,7 @@ final class Mallocator : Allocator
/**
* Returns: The alignment offered.
*/
- @property uint alignment() shared const pure nothrow @safe @nogc
+ @property uint alignment() const @nogc nothrow pure @safe shared
{
return (void*).alignof;
}
@@ -192,7 +193,7 @@ final class Mallocator : Allocator
assert(Mallocator.instance.alignment == (void*).alignof);
}
- static private shared(Mallocator) instantiate() nothrow @nogc
+ static private shared(Mallocator) instantiate() @nogc nothrow @system
{
if (instance_ is null)
{
@@ -213,13 +214,13 @@ final class Mallocator : Allocator
*
* Returns: The global $(D_PSYMBOL Allocator) instance.
*/
- static @property shared(Mallocator) instance() pure nothrow @nogc
+ static @property shared(Mallocator) instance() @nogc nothrow pure @system
{
return (cast(GetPureInstance!Mallocator) &instantiate)();
}
///
- @nogc nothrow unittest
+ @nogc nothrow pure @system unittest
{
assert(instance is instance);
}
diff --git a/source/tanya/memory/mmappool.d b/source/tanya/memory/mmappool.d
index b555580..fb3ef06 100644
--- a/source/tanya/memory/mmappool.d
+++ b/source/tanya/memory/mmappool.d
@@ -14,45 +14,32 @@
*/
module tanya.memory.mmappool;
-import std.algorithm.comparison;
+version (TanyaNative):
+
+import mir.linux._asm.unistd;
+import tanya.algorithm.comparison;
import tanya.memory.allocator;
import tanya.memory.op;
+import tanya.os.error;
+import tanya.sys.linux.syscall;
+import tanya.sys.posix.mman;
-version (TanyaNative):
-
-import core.sys.posix.sys.mman : MAP_ANON,
- MAP_FAILED,
- MAP_PRIVATE,
- PROT_READ,
- PROT_WRITE;
-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
+private void* mapMemory(const size_t length) @nogc nothrow pure @system
{
- void* p = mmap(null,
- len,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON,
- -1,
- 0);
- return p is MAP_FAILED ? null : p;
+ auto p = syscall_(0,
+ length,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1,
+ 0,
+ NR_mmap);
+ return p == -ErrorCode.noMemory ? null : cast(void*) p;
}
-private bool unmapMemory(shared void* addr, const size_t len)
-pure nothrow @system @nogc
+private bool unmapMemory(shared void* addr, const size_t length)
+@nogc nothrow pure @system
{
- return munmap(cast(void*) addr, len) == 0;
+ return syscall_(cast(ptrdiff_t) addr, length, NR_munmap) == 0;
}
/*
@@ -83,7 +70,7 @@ final class MmapPool : Allocator
{
version (none)
{
- pure nothrow @nogc invariant
+ @nogc nothrow pure @system invariant
{
for (auto r = &head; *r !is null; r = &((*r).next))
{
@@ -107,7 +94,7 @@ final class MmapPool : Allocator
*
* Returns: Pointer to the new allocated memory.
*/
- void[] allocate(const size_t size) shared pure nothrow @nogc
+ void[] allocate(size_t size) @nogc nothrow pure shared @system
{
if (size == 0)
{
@@ -128,7 +115,7 @@ final class MmapPool : Allocator
return data is null ? null : data[0 .. size];
}
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
auto p = MmapPool.instance.allocate(20);
assert(p);
@@ -138,15 +125,14 @@ final class MmapPool : Allocator
assert(p.length == 0);
}
- // Issue 245: https://issues.caraus.io/issues/245.
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
// allocate() check.
size_t tooMuchMemory = size_t.max
- MmapPool.alignment_
- BlockEntry.sizeof * 2
- RegionEntry.sizeof
- - MmapPool.instance.pageSize;
+ - pageSize;
assert(MmapPool.instance.allocate(tooMuchMemory) is null);
assert(MmapPool.instance.allocate(size_t.max) is null);
@@ -165,7 +151,8 @@ final class MmapPool : Allocator
*
* Returns: Data the block points to or $(D_KEYWORD null).
*/
- private void* findBlock(const ref size_t size) shared pure nothrow @nogc
+ private void* findBlock(const ref size_t size)
+ @nogc nothrow pure shared @system
{
Block block1;
RegionLoop: for (auto r = head; r !is null; r = r.next)
@@ -207,7 +194,7 @@ final class MmapPool : Allocator
}
// Merge block with the next one.
- private void mergeNext(Block block) shared const pure nothrow @safe @nogc
+ private void mergeNext(Block block) const @nogc nothrow pure @safe shared
{
block.size = block.size + BlockEntry.sizeof + block.next.size;
if (block.next.next !is null)
@@ -225,7 +212,7 @@ final class MmapPool : Allocator
*
* Returns: Whether the deallocation was successful.
*/
- bool deallocate(void[] p) shared pure nothrow @nogc
+ bool deallocate(void[] p) @nogc nothrow pure shared @system
{
if (p.ptr is null)
{
@@ -271,7 +258,7 @@ final class MmapPool : Allocator
return true;
}
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
auto p = MmapPool.instance.allocate(20);
@@ -290,8 +277,8 @@ final class MmapPool : Allocator
*
* Returns: $(D_KEYWORD true) if successful, $(D_KEYWORD false) otherwise.
*/
- bool reallocateInPlace(ref void[] p, const size_t size)
- shared pure nothrow @nogc
+ bool reallocateInPlace(ref void[] p, size_t size)
+ @nogc nothrow pure shared @system
{
if (p is null || size == 0)
{
@@ -354,7 +341,7 @@ final class MmapPool : Allocator
return true;
}
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
void[] p;
assert(!MmapPool.instance.reallocateInPlace(p, 5));
@@ -387,7 +374,8 @@ final class MmapPool : Allocator
*
* Returns: Whether the reallocation was successful.
*/
- bool reallocate(ref void[] p, const size_t size) shared pure nothrow @nogc
+ bool reallocate(ref void[] p, size_t size)
+ @nogc nothrow pure shared @system
{
if (size == 0)
{
@@ -419,7 +407,7 @@ final class MmapPool : Allocator
return true;
}
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
void[] p;
MmapPool.instance.reallocate(p, 10 * int.sizeof);
@@ -447,28 +435,20 @@ final class MmapPool : Allocator
MmapPool.instance.deallocate(p);
}
- static private shared(MmapPool) instantiate() nothrow @nogc
+ static private shared(MmapPool) instantiate() @nogc nothrow @system
{
if (instance_ is null)
{
- // Get system dependend page size.
- size_t pageSize = sysconf(_SC_PAGE_SIZE);
- if (pageSize < 65536)
- {
- pageSize = pageSize * 65536 / pageSize;
- }
-
const instanceSize = addAlignment(__traits(classInstanceSize,
MmapPool));
Region head; // Will become soon our region list head
- void* data = initializeRegion(instanceSize, head, pageSize);
+ void* data = initializeRegion(instanceSize, head);
if (data !is null)
{
copy(typeid(MmapPool).initializer, data[0 .. instanceSize]);
instance_ = cast(shared MmapPool) data;
instance_.head = head;
- instance_.pageSize = pageSize;
}
}
return instance_;
@@ -479,12 +459,12 @@ final class MmapPool : Allocator
*
* Returns: Global $(D_PSYMBOL MmapPool) instance.
*/
- static @property shared(MmapPool) instance() pure nothrow @nogc
+ static @property shared(MmapPool) instance() @nogc nothrow pure @system
{
return (cast(GetPureInstance!MmapPool) &instantiate)();
}
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
assert(instance is instance);
}
@@ -498,12 +478,10 @@ final class MmapPool : Allocator
*
* Returns: A pointer to the data.
*/
- private static void* initializeRegion(const size_t size,
- ref Region head,
- const size_t pageSize)
- pure nothrow @nogc
+ private static void* initializeRegion(const size_t size, ref Region head)
+ @nogc nothrow pure @system
{
- const regionSize = calculateRegionSize(size, pageSize);
+ const regionSize = calculateRegionSize(size);
if (regionSize < size)
{
return null;
@@ -550,9 +528,10 @@ final class MmapPool : Allocator
return data;
}
- private void* initializeRegion(const size_t size) shared pure nothrow @nogc
+ private void* initializeRegion(const size_t size)
+ @nogc nothrow pure shared @system
{
- return initializeRegion(size, this.head, this.pageSize);
+ return initializeRegion(size, this.head);
}
/*
@@ -561,21 +540,19 @@ final class MmapPool : Allocator
*
* Returns: Aligned size of $(D_PARAM x).
*/
- private static size_t addAlignment(const size_t x) pure nothrow @safe @nogc
+ private static size_t addAlignment(const size_t x) @nogc nothrow pure @safe
{
return (x - 1) / alignment_ * alignment_ + alignment_;
}
/*
* Params:
- * x = Required space.
- * pageSize = Page size.
+ * x = Required space.
*
* Returns: Minimum region size (a multiple of $(D_PSYMBOL pageSize)).
*/
- private static size_t calculateRegionSize(ref const size_t x,
- ref const size_t pageSize)
- pure nothrow @safe @nogc
+ private static size_t calculateRegionSize(ref const size_t x)
+ @nogc nothrow pure @safe
{
return (x + RegionEntry.sizeof + BlockEntry.sizeof * 2)
/ pageSize * pageSize + pageSize;
@@ -584,12 +561,12 @@ final class MmapPool : Allocator
/*
* Returns: Alignment offered.
*/
- @property uint alignment() shared const pure nothrow @safe @nogc
+ @property uint alignment() const @nogc nothrow pure @safe shared
{
return alignment_;
}
- @nogc nothrow pure unittest
+ @nogc nothrow pure @system unittest
{
assert(MmapPool.instance.alignment == MmapPool.alignment_);
}
@@ -597,7 +574,9 @@ final class MmapPool : Allocator
private enum uint alignment_ = 8;
private shared static MmapPool instance_;
- private shared size_t pageSize;
+
+ // Page size.
+ enum size_t pageSize = 65536;
private shared struct RegionEntry
{
@@ -622,7 +601,7 @@ final class MmapPool : Allocator
// A lot of allocations/deallocations, but it is the minimum caused a
// segmentation fault because MmapPool reallocateInPlace moves a block wrong.
-@nogc nothrow pure unittest
+@nogc nothrow pure @system unittest
{
auto a = MmapPool.instance.allocate(16);
auto d = MmapPool.instance.allocate(16);
diff --git a/source/tanya/sys/linux/syscall.d b/source/tanya/sys/linux/syscall.d
new file mode 100644
index 0000000..64d2cd4
--- /dev/null
+++ b/source/tanya/sys/linux/syscall.d
@@ -0,0 +1,47 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Copyright: Eugene Wissner 2018.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/sys/linux/syscall.d,
+ * tanya/sys/linux/syscall.d)
+ */
+module tanya.sys.linux.syscall;
+
+version (TanyaNative):
+
+extern ptrdiff_t syscall(ptrdiff_t, ptrdiff_t, ptrdiff_t)
+@nogc nothrow @system;
+
+extern ptrdiff_t syscall(ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t) @nogc nothrow @system;
+
+// Same syscalls as above but pure.
+private template getOverloadMangling(size_t n)
+{
+ enum string getOverloadMangling = __traits(getOverloads,
+ tanya.sys.linux.syscall,
+ "syscall")[n].mangleof;
+}
+
+pragma(mangle, getOverloadMangling!0)
+extern ptrdiff_t syscall_(ptrdiff_t, ptrdiff_t, ptrdiff_t)
+@nogc nothrow pure @system;
+
+pragma(mangle, getOverloadMangling!1)
+extern ptrdiff_t syscall_(ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t,
+ ptrdiff_t) @nogc nothrow pure @system;
diff --git a/source/tanya/sys/posix/mman.d b/source/tanya/sys/posix/mman.d
new file mode 100644
index 0000000..dbf78a9
--- /dev/null
+++ b/source/tanya/sys/posix/mman.d
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Copyright: Eugene Wissner 2018.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/sys/posix/mman.d,
+ * tanya/sys/posix/mman.d)
+ */
+module tanya.sys.posix.mman;
+
+version (TanyaNative):
+
+enum
+{
+ PROT_EXEC = 0x4, // Page can be executed.
+ PROT_NONE = 0x0, // Page cannot be accessed.
+ PROT_READ = 0x1, // Page can be read.
+ PROT_WRITE = 0x2, // Page can be written.
+}
+
+enum
+{
+ MAP_FIXED = 0x10, // Interpret addr exactly.
+ MAP_PRIVATE = 0x02, // Changes are private.
+ MAP_SHARED = 0x01, // Share changes.
+ MAP_ANONYMOUS = 0x20, // Don't use a file.
+}