From 721bb110e5ad2f07b436d5064f5662fdec72fa77 Mon Sep 17 00:00:00 2001 From: Eugene Wissner Date: Wed, 5 Oct 2016 13:12:50 +0200 Subject: [PATCH] Use dispose from std.experimental --- source/tanya/container/buffer.d | 22 +-- source/tanya/container/list.d | 22 +-- source/tanya/container/queue.d | 14 +- source/tanya/container/vector.d | 24 +-- source/tanya/crypto/cipher.d | 18 +-- source/tanya/event/internal/epoll.d | 6 +- source/tanya/event/internal/selector.d | 6 +- source/tanya/event/loop.d | 6 +- source/tanya/event/watcher.d | 6 +- source/tanya/memory/allocator.d | 25 +++- source/tanya/memory/package.d | 200 ++----------------------- 11 files changed, 98 insertions(+), 251 deletions(-) diff --git a/source/tanya/container/buffer.d b/source/tanya/container/buffer.d index 999cff5..efe2e41 100644 --- a/source/tanya/container/buffer.d +++ b/source/tanya/container/buffer.d @@ -116,7 +116,7 @@ class ReadBuffer : Buffer */ ~this() { - finalize(allocator, _buffer); + dispose(allocator, _buffer); } /// @@ -126,7 +126,7 @@ class ReadBuffer : Buffer assert(b.capacity == 8192); assert(b.length == 0); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } /** @@ -169,7 +169,7 @@ class ReadBuffer : Buffer b[]; assert(b.free == b.blockSize); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } /** @@ -240,7 +240,7 @@ class ReadBuffer : Buffer assert(result[10] == 20); assert(result[14] == 24); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } /** @@ -275,7 +275,7 @@ class ReadBuffer : Buffer assert(result[9] == 9); assert(b.length == 0); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } } @@ -333,7 +333,7 @@ class WriteBuffer : Buffer */ ~this() { - finalize(allocator, _buffer); + dispose(allocator, _buffer); } /** @@ -385,7 +385,7 @@ class WriteBuffer : Buffer b.written = b.length; assert(b.length == 0); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } /** @@ -485,7 +485,7 @@ class WriteBuffer : Buffer assert(b._buffer[0] == 23 && b._buffer[1] == 255 && b._buffer[2] == 48 && b._buffer[3] == 23 && b._buffer[4] == 255); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); b = make!WriteBuffer(defaultAllocator, 2); @@ -495,7 +495,7 @@ class WriteBuffer : Buffer assert(b.ring == 3); assert(b.position == 3); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } /** @@ -578,7 +578,7 @@ class WriteBuffer : Buffer b.written = 4; assert(b.length == 0); - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } /** @@ -631,6 +631,6 @@ class WriteBuffer : Buffer assert(returnedBuf[0..b.length] == buf[0..6]); b.written = b.length; - finalize(defaultAllocator, b); + dispose(defaultAllocator, b); } } diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d index e3bf25c..d9b40f2 100644 --- a/source/tanya/container/list.d +++ b/source/tanya/container/list.d @@ -42,7 +42,7 @@ class SList(T) { static if (isFinalizable!T) { - finalize(allocator, front); + dispose(allocator, front); } popFront(); } @@ -87,7 +87,7 @@ class SList(T) l.front = values[1]; assert(l.front == values[1]); - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /** @@ -118,7 +118,7 @@ class SList(T) assert(l.front == value); assert(!l.empty); - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /** @@ -144,7 +144,7 @@ class SList(T) auto n = first.next.next; auto content = first.next.content; - finalize(allocator, first.next); + dispose(allocator, first.next); first.next = n; return content; @@ -162,7 +162,7 @@ class SList(T) l.popFront(); assert(l.front == values[0]); - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /** @@ -183,7 +183,7 @@ class SList(T) auto temp = position.next.next; auto content = position.next.content; - finalize(allocator, position.next); + dispose(allocator, position.next); position.next = temp; return content; @@ -203,7 +203,7 @@ class SList(T) assert(l.remove() == 8); assert(l.empty); - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /** @@ -231,7 +231,7 @@ class SList(T) l.reset(); assert(l.current == 5); - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /** @@ -275,7 +275,7 @@ class SList(T) assert(i != 2 || e == values[0]); } - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /// Ditto. @@ -315,7 +315,7 @@ class SList(T) ++i; } - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } /** @@ -400,5 +400,5 @@ unittest { auto l = make!(SList!Stuff)(defaultAllocator); - finalize(defaultAllocator, l); + dispose(defaultAllocator, l); } diff --git a/source/tanya/container/queue.d b/source/tanya/container/queue.d index de28de2..6c9b794 100644 --- a/source/tanya/container/queue.d +++ b/source/tanya/container/queue.d @@ -41,7 +41,7 @@ class Queue(T) { static if (isFinalizable!T) { - finalize(allocator, e); + dispose(allocator, e); } } } @@ -99,7 +99,7 @@ class Queue(T) q.insertBack(values[1]); assert(q.front is values[0]); - finalize(defaultAllocator, q); + dispose(defaultAllocator, q); } /** @@ -129,7 +129,7 @@ class Queue(T) assert(q.front == value); assert(!q.empty); - finalize(defaultAllocator, q); + dispose(defaultAllocator, q); } /** @@ -150,7 +150,7 @@ class Queue(T) q.insertBack(value); assert(!q.empty); - finalize(defaultAllocator, q); + dispose(defaultAllocator, q); } /** @@ -167,7 +167,7 @@ class Queue(T) { auto n = first.next.next; - finalize(allocator, first.next); + dispose(allocator, first.next); first.next = n; return this; @@ -185,7 +185,7 @@ class Queue(T) q.popFront(); assert(q.front is values[1]); - finalize(defaultAllocator, q); + dispose(defaultAllocator, q); } /** @@ -214,5 +214,5 @@ unittest { auto q = make!(Queue!int)(defaultAllocator); - finalize(defaultAllocator, q); + dispose(defaultAllocator, q); } diff --git a/source/tanya/container/vector.d b/source/tanya/container/vector.d index fb8353b..f6bde1f 100644 --- a/source/tanya/container/vector.d +++ b/source/tanya/container/vector.d @@ -22,7 +22,7 @@ import tanya.memory; * * v[1000] = value; * - * finalize(defaultAllocator, v); + * dispose(defaultAllocator, v); * --- * it will allocate not only for one, but for 1000 elements. So this * implementation is more suitable for sequential data with random access. @@ -57,7 +57,7 @@ class Vector(T) */ ~this() { - finalize(allocator, vector); + dispose(allocator, vector); } /** @@ -94,7 +94,7 @@ class Vector(T) v.length = 0; assert(v.length == 0); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -116,7 +116,7 @@ class Vector(T) void remove(size_t pos) { auto el = vector[pos]; - finalize(allocator, el); + dispose(allocator, el); } } @@ -151,7 +151,7 @@ class Vector(T) v[4] = values[1]; assert(v.length == 5); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -182,7 +182,7 @@ class Vector(T) v[0] = values[1]; assert(v[0] is values[1]); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -250,7 +250,7 @@ class Vector(T) assert(j != 2 || e is values[2]); } - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -289,7 +289,7 @@ class Vector(T) v.front = values[1]; assert(v.front == 15); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -325,7 +325,7 @@ class Vector(T) v.popFront(); assert(v.empty); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -364,7 +364,7 @@ class Vector(T) v.back = values[1]; assert(v.back == 15); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /** @@ -399,7 +399,7 @@ class Vector(T) v.popBack(); assert(v.empty); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } /// Container. @@ -413,5 +413,5 @@ unittest { auto v = make!(Vector!int)(defaultAllocator); - finalize(defaultAllocator, v); + dispose(defaultAllocator, v); } diff --git a/source/tanya/crypto/cipher.d b/source/tanya/crypto/cipher.d index d436feb..c74013b 100644 --- a/source/tanya/crypto/cipher.d +++ b/source/tanya/crypto/cipher.d @@ -94,7 +94,7 @@ unittest assert(input.length == 64); assert(input[63] == 0); - defaultAllocator.finalize(input); + defaultAllocator.dispose(input); } { // PKCS#7 auto input = defaultAllocator.makeArray!ubyte(50); @@ -139,7 +139,7 @@ unittest } } - defaultAllocator.finalize(input); + defaultAllocator.dispose(input); } { // ANSI X.923 auto input = defaultAllocator.makeArray!ubyte(50); @@ -184,7 +184,7 @@ unittest } } - defaultAllocator.finalize(input); + defaultAllocator.dispose(input); } } @@ -240,8 +240,8 @@ unittest removePadding(input, Mode.zero, 64); assert(input == inputDup); - defaultAllocator.finalize(input); - defaultAllocator.finalize(inputDup); + defaultAllocator.dispose(input); + defaultAllocator.dispose(inputDup); } { // PKCS#7 @@ -257,8 +257,8 @@ unittest removePadding(input, Mode.pkcs7, 64); assert(input == inputDup); - defaultAllocator.finalize(input); - defaultAllocator.finalize(inputDup); + defaultAllocator.dispose(input); + defaultAllocator.dispose(inputDup); } { // ANSI X.923 auto input = defaultAllocator.makeArray!ubyte(50); @@ -273,7 +273,7 @@ unittest removePadding(input, Mode.pkcs7, 64); assert(input == inputDup); - defaultAllocator.finalize(input); - defaultAllocator.finalize(inputDup); + defaultAllocator.dispose(input); + defaultAllocator.dispose(inputDup); } } diff --git a/source/tanya/event/internal/epoll.d b/source/tanya/event/internal/epoll.d index 0e76c3a..a129661 100644 --- a/source/tanya/event/internal/epoll.d +++ b/source/tanya/event/internal/epoll.d @@ -59,7 +59,7 @@ class EpollLoop : Loop */ ~this() { - finalize(defaultAllocator, epollEvents); + dispose(defaultAllocator, epollEvents); } /** @@ -125,7 +125,7 @@ class EpollLoop : Loop // If it is a ConnectionWatcher if (connection is null && connections[client] !is null) { - finalize(defaultAllocator, connections[client]); + dispose(defaultAllocator, connections[client]); connections[client] = null; } } @@ -198,7 +198,7 @@ class EpollLoop : Loop catch (TransportException e) { swapPendings.insertBack(connection); - finalize(defaultAllocator, e); + dispose(defaultAllocator, e); } } else if (ev.events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) diff --git a/source/tanya/event/internal/selector.d b/source/tanya/event/internal/selector.d index 36dca76..95bf5d8 100644 --- a/source/tanya/event/internal/selector.d +++ b/source/tanya/event/internal/selector.d @@ -61,9 +61,9 @@ class SocketTransport : DuplexTransport ~this() { close(socket); - finalize(defaultAllocator, input_); - finalize(defaultAllocator, output_); - finalize(defaultAllocator, protocol_); + dispose(defaultAllocator, input_); + dispose(defaultAllocator, output_); + dispose(defaultAllocator, protocol_); } /** diff --git a/source/tanya/event/loop.d b/source/tanya/event/loop.d index 73b0557..035c0b6 100644 --- a/source/tanya/event/loop.d +++ b/source/tanya/event/loop.d @@ -70,9 +70,9 @@ abstract class Loop */ ~this() { - finalize(defaultAllocator, connections); - finalize(defaultAllocator, pendings); - finalize(defaultAllocator, swapPendings); + dispose(defaultAllocator, connections); + dispose(defaultAllocator, pendings); + dispose(defaultAllocator, swapPendings); } /** diff --git a/source/tanya/event/watcher.d b/source/tanya/event/watcher.d index e19a21b..b9880eb 100644 --- a/source/tanya/event/watcher.d +++ b/source/tanya/event/watcher.d @@ -128,7 +128,7 @@ class IOWatcher : ConnectionWatcher ~this() { - finalize(defaultAllocator, transport_); + dispose(defaultAllocator, transport_); } /** @@ -185,7 +185,7 @@ class IOWatcher : ConnectionWatcher else if (transport.disconnected) { transport.protocol.disconnected(); - finalize(defaultAllocator, transport_); + dispose(defaultAllocator, transport_); protocolFactory = null; } else if (transport.output.length) @@ -200,7 +200,7 @@ class IOWatcher : ConnectionWatcher } catch (TransportException e) { - finalize(defaultAllocator, e); + dispose(defaultAllocator, e); } } } diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d index 07a19b9..711b1fd 100644 --- a/source/tanya/memory/allocator.d +++ b/source/tanya/memory/allocator.d @@ -7,12 +7,17 @@ * 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) - */ + */ module tanya.memory.allocator; import std.experimental.allocator; import std.traits; +version (unittest) +{ + import tanya.memory : defaultAllocator; +} + /** * Allocator interface. */ @@ -80,5 +85,23 @@ bool resizeArray(T)(shared Allocator allocator, return true; } +/// +unittest +{ + int[] p; + + defaultAllocator.resizeArray(p, 20); + assert(p.length == 20); + + defaultAllocator.resizeArray(p, 30); + assert(p.length == 30); + + defaultAllocator.resizeArray(p, 10); + assert(p.length == 10); + + defaultAllocator.resizeArray(p, 0); + assert(p is null); +} + enum bool isFinalizable(T) = is(T == class) || is(T == interface) || hasElaborateDestructor!T || isDynamicArray!T; diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d index 9c5ca42..1585a87 100644 --- a/source/tanya/memory/package.d +++ b/source/tanya/memory/package.d @@ -7,199 +7,23 @@ * 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) - */ + */ module tanya.memory; -public import tanya.memory.allocator; -public import std.experimental.allocator : make, makeArray, expandArray, shrinkArray, IAllocator; -import core.atomic; -import core.stdc.stdlib; -import std.traits; - -version (Windows) +public { - import core.sys.windows.windows; -} -else version (Posix) -{ - public import tanya.memory.mmappool; - import core.sys.posix.pthread; + import tanya.memory.allocator; + import std.experimental.allocator : make, dispose, shrinkArray, expandArray, makeArray, dispose; } -version (Windows) +shared Allocator allocator; + +@property ref shared(Allocator) defaultAllocator() { - package alias Mutex = CRITICAL_SECTION; - package alias destroyMutex = DeleteCriticalSection; -} -else version (Posix) -{ - package alias Mutex = pthread_mutex_t; - package void destroyMutex(pthread_mutex_t* mtx) + import tanya.memory.mallocator; + if (allocator is null) { - pthread_mutex_destroy(mtx) && assert(0); - } + allocator = Mallocator.instance; + } + return allocator; } - -@property void defaultAllocator(shared Allocator allocator) @safe nothrow -{ - _defaultAllocator = allocator; -} - -@property shared(Allocator) defaultAllocator() @safe nothrow -{ - return _defaultAllocator; -} - -static this() @safe nothrow -{ - defaultAllocator = MmapPool.instance; -} - -package struct Monitor -{ - Object.Monitor impl; // for user-level monitors - void delegate(Object) @nogc[] devt; // for internal monitors - size_t refs; // reference count - version (Posix) - { - Mutex mtx; - } -} - -package @property ref shared(Monitor*) monitor(Object h) pure nothrow -{ - return *cast(shared Monitor**)&h.__monitor; -} - -/** - * Destroys and then deallocates (using $(D_PARAM allocator)) the class - * object referred to by a $(D_KEYWORD class) or $(D_KEYWORD interface) - * reference. It is assumed the respective entities had been allocated with - * the same allocator. - * - * Params: - * A = The type of the allocator used for the ojbect allocation. - * T = The type of the object that should be destroyed. - * allocator = The allocator used for the object allocation. - * p = The object should be destroyed. - */ -void finalize(A, T)(auto ref A allocator, ref T p) - if (is(T == class) || is(T == interface)) -{ - static if (is(T == interface)) - { - auto ob = cast(Object) p; - } - else - { - alias ob = p; - } - auto pp = cast(void*) ob; - auto ppv = cast(void**) pp; - if (!pp || !*ppv) - { - return; - } - auto support = (cast(void*) ob)[0 .. typeid(ob).initializer.length]; - auto pc = cast(ClassInfo*) *ppv; - auto c = *pc; - do - { - if (c.destructor) - { - (cast(void function(Object)) c.destructor)(ob); - } - } while ((c = c.base) !is null); - - // Take care of monitors for synchronized blocks - if (ppv[1]) - { - shared(Monitor)* m = atomicLoad!(MemoryOrder.acq)(ob.monitor); - if (m !is null) - { - auto mc = cast(Monitor*) m; - if (!atomicOp!("-=")(m.refs, cast(size_t) 1)) - { - foreach (v; mc.devt) - { - if (v) - { - v(ob); - } - } - if (mc.devt.ptr) - { - free(mc.devt.ptr); - } - destroyMutex(&mc.mtx); - free(mc); - atomicStore!(MemoryOrder.rel)(ob.monitor, null); - } - } - } - *ppv = null; - - allocator.deallocate(support); - p = null; -} - -/// Ditto. -void finalize(A, T)(auto ref A allocator, ref T *p) - if (is(T == struct)) -{ - if (p is null) - { - return; - } - static if (hasElaborateDestructor!T) - { - *p.__xdtor(); - } - allocator.deallocate((cast(void*)p)[0 .. T.sizeof]); - p = null; -} - -/// Ditto. -void finalize(A, T)(auto ref A allocator, ref T[] p) -{ - static if (hasElaborateDestructor!T) - { - foreach (ref e; p) - { - finalize(allocator, e); - } - } - allocator.deallocate(p); - p = null; -} - -bool resizeArray(T, A)(auto ref A allocator, ref T[] array, in size_t length) -@trusted -{ - if (length == array.length) - { - return true; - } - if (array is null && length > 0) - { - array = makeArray!T(allocator, length); - return array !is null; - } - if (length == 0) - { - finalize(allocator, array); - return true; - } - void[] buf = array; - if (!allocator.reallocate(buf, length * T.sizeof)) - { - return false; - } - array = cast(T[]) buf; - return true; -} - -enum bool isFinalizable(T) = is(T == class) || is(T == interface) - || hasElaborateDestructor!T || isDynamicArray!T; - -private shared Allocator _defaultAllocator;