Remove shared from the allocators
This commit is contained in:
@ -12,6 +12,7 @@ module tanya.memory.allocator;
|
||||
|
||||
import std.experimental.allocator;
|
||||
import std.traits;
|
||||
import std.typecons : Ternary;
|
||||
|
||||
version (unittest)
|
||||
{
|
||||
@ -21,43 +22,122 @@ version (unittest)
|
||||
/**
|
||||
* Allocator interface.
|
||||
*/
|
||||
interface Allocator
|
||||
abstract class Allocator : IAllocator
|
||||
{
|
||||
/**
|
||||
* Allocates $(D_PARAM size) bytes of memory.
|
||||
* Not supported.
|
||||
*
|
||||
* Returns: $(D_KEYWORD false).
|
||||
*/
|
||||
bool deallocateAll() const @nogc @safe pure nothrow
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*
|
||||
* Returns $(D_PSYMBOL Ternary.unknown).
|
||||
*/
|
||||
Ternary empty() const @nogc @safe pure nothrow
|
||||
{
|
||||
return Ternary.unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*
|
||||
* Params:
|
||||
* b = Memory block.
|
||||
*
|
||||
* Returns: $(D_PSYMBOL Ternary.unknown).
|
||||
*/
|
||||
Ternary owns(void[] b) const @nogc @safe pure nothrow
|
||||
{
|
||||
return Ternary.unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*
|
||||
* Params:
|
||||
* p = Pointer to a memory block.
|
||||
* result = Full block allocated.
|
||||
*
|
||||
* Returns: $(D_PSYMBOL Ternary.unknown).
|
||||
*/
|
||||
Ternary resolveInternalPointer(void* p, ref void[] result)
|
||||
const @nogc @safe pure nothrow
|
||||
{
|
||||
return Ternary.unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Params:
|
||||
* size = Amount of memory to allocate.
|
||||
*
|
||||
* Returns: The pointer to the new allocated memory.
|
||||
* Returns: The good allocation size that guarantees zero internal
|
||||
* fragmentation.
|
||||
*/
|
||||
void[] allocate(size_t size) shared;
|
||||
size_t goodAllocSize(size_t s)
|
||||
{
|
||||
auto rem = s % alignment;
|
||||
return rem ? s + alignment - rem : s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocates a memory block.
|
||||
* Not supported.
|
||||
*
|
||||
* Returns: $(D_KEYWORD null).
|
||||
*
|
||||
*/
|
||||
void[] allocateAll() const @nogc @safe pure nothrow
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*
|
||||
* Params:
|
||||
* b = Block to be expanded.
|
||||
* s = New size.
|
||||
*
|
||||
* Returns: $(D_KEYWORD false).
|
||||
*/
|
||||
bool expand(ref void[] b, size_t s) const @nogc @safe pure nothrow
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*
|
||||
* Params:
|
||||
* p = A pointer to the memory block to be freed.
|
||||
* n = Amount of memory to allocate.
|
||||
* a = Alignment.
|
||||
*
|
||||
* Returns: Whether the deallocation was successful.
|
||||
* Returns: $(D_KEYWORD null).
|
||||
*/
|
||||
bool deallocate(void[] p) shared;
|
||||
void[] alignedAllocate(size_t n, uint a) const @nogc @safe pure nothrow
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases or decreases the size of a memory block.
|
||||
* Not supported.
|
||||
*
|
||||
* Params:
|
||||
* p = A pointer to the memory block.
|
||||
* size = Size of the reallocated block.
|
||||
* n = Amount of memory to allocate.
|
||||
* a = Alignment.
|
||||
*
|
||||
* Returns: Whether the reallocation was successful.
|
||||
* Returns: $(D_KEYWORD false).
|
||||
*/
|
||||
bool reallocate(ref void[] p, size_t size) shared;
|
||||
|
||||
/**
|
||||
* Returns: The alignment offered.
|
||||
*/
|
||||
@property immutable(uint) alignment() shared const @safe pure nothrow;
|
||||
bool alignedReallocate(ref void[] b, size_t size, uint alignment)
|
||||
const @nogc @safe pure nothrow
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +150,7 @@ interface Allocator
|
||||
* Returns: $(D_KEYWORD true) upon success, $(D_KEYWORD false) if memory could
|
||||
* not be reallocated. In the latter
|
||||
*/
|
||||
bool resizeArray(T)(shared Allocator allocator,
|
||||
bool resizeArray(T)(IAllocator allocator,
|
||||
ref T[] array,
|
||||
in size_t length)
|
||||
{
|
||||
|
@ -1,173 +0,0 @@
|
||||
/* 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 2016.
|
||||
* 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.mallocator;
|
||||
|
||||
import tanya.memory.allocator;
|
||||
import core.exception;
|
||||
import core.stdc.stdlib;
|
||||
import std.algorithm.comparison;
|
||||
|
||||
/**
|
||||
* Wrapper for malloc/realloc/free from the C standard library.
|
||||
*/
|
||||
class Mallocator : Allocator
|
||||
{
|
||||
/**
|
||||
* Allocates $(D_PARAM size) bytes of memory.
|
||||
*
|
||||
* Params:
|
||||
* size = Amount of memory to allocate.
|
||||
*
|
||||
* Returns: The pointer to the new allocated memory.
|
||||
*/
|
||||
void[] allocate(size_t size) shared @nogc nothrow
|
||||
{
|
||||
if (!size)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
auto p = malloc(size + psize);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
onOutOfMemoryError();
|
||||
}
|
||||
return p[psize.. psize + size];
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow unittest
|
||||
{
|
||||
auto p = Mallocator.instance.allocate(20);
|
||||
|
||||
assert(p.length == 20);
|
||||
|
||||
Mallocator.instance.deallocate(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @nogc nothrow
|
||||
{
|
||||
if (p !is null)
|
||||
{
|
||||
free(p.ptr - psize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow unittest
|
||||
{
|
||||
void[] p;
|
||||
assert(Mallocator.instance.deallocate(p));
|
||||
|
||||
p = Mallocator.instance.allocate(10);
|
||||
assert(Mallocator.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, size_t size) shared @nogc nothrow
|
||||
{
|
||||
if (!size)
|
||||
{
|
||||
deallocate(p);
|
||||
p = null;
|
||||
return true;
|
||||
}
|
||||
else if (p is null)
|
||||
{
|
||||
p = allocate(size);
|
||||
return true;
|
||||
}
|
||||
auto r = realloc(p.ptr - psize, size + psize);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
onOutOfMemoryError();
|
||||
}
|
||||
p = r[psize.. psize + size];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow unittest
|
||||
{
|
||||
void[] p;
|
||||
|
||||
Mallocator.instance.reallocate(p, 20);
|
||||
assert(p.length == 20);
|
||||
|
||||
Mallocator.instance.reallocate(p, 30);
|
||||
assert(p.length == 30);
|
||||
|
||||
Mallocator.instance.reallocate(p, 10);
|
||||
assert(p.length == 10);
|
||||
|
||||
Mallocator.instance.reallocate(p, 0);
|
||||
assert(p is null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: The alignment offered.
|
||||
*/
|
||||
@property immutable(uint) alignment() shared const @safe pure nothrow
|
||||
{
|
||||
return cast(uint) max(double.alignof, real.alignof);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static allocator instance and initializer.
|
||||
*
|
||||
* Returns: The global $(D_PSYMBOL Allocator) instance.
|
||||
*/
|
||||
static @property ref shared(Mallocator) instance() @nogc nothrow
|
||||
{
|
||||
if (instance_ is null)
|
||||
{
|
||||
immutable size = __traits(classInstanceSize, Mallocator) + psize;
|
||||
void* p = malloc(size);
|
||||
|
||||
if (p is null)
|
||||
{
|
||||
onOutOfMemoryError();
|
||||
}
|
||||
p[psize..size] = typeid(Mallocator).initializer[];
|
||||
instance_ = cast(shared Mallocator) p[psize..size].ptr;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
///
|
||||
@nogc nothrow unittest
|
||||
{
|
||||
assert(instance is instance);
|
||||
}
|
||||
|
||||
private enum psize = 8;
|
||||
|
||||
private shared static Mallocator instance_;
|
||||
}
|
@ -83,7 +83,7 @@ class MmapPool : Allocator
|
||||
*
|
||||
* Returns: The pointer to the new allocated memory.
|
||||
*/
|
||||
void[] allocate(size_t size) shared @nogc @trusted nothrow
|
||||
void[] allocate(size_t size, TypeInfo ti = null) @nogc @trusted nothrow
|
||||
{
|
||||
if (!size)
|
||||
{
|
||||
@ -119,7 +119,7 @@ class MmapPool : Allocator
|
||||
*
|
||||
* Returns: Data the block points to or $(D_KEYWORD null).
|
||||
*/
|
||||
private void* findBlock(size_t size) shared @nogc nothrow
|
||||
private void* findBlock(size_t size) @nogc nothrow
|
||||
{
|
||||
Block block1;
|
||||
RegionLoop: for (auto r = head; r !is null; r = r.next)
|
||||
@ -177,7 +177,7 @@ class MmapPool : Allocator
|
||||
*
|
||||
* Returns: Whether the deallocation was successful.
|
||||
*/
|
||||
bool deallocate(void[] p) shared @nogc @trusted nothrow
|
||||
bool deallocate(void[] p) @nogc @trusted nothrow
|
||||
{
|
||||
if (p is null)
|
||||
{
|
||||
@ -233,7 +233,7 @@ class MmapPool : Allocator
|
||||
*
|
||||
* Returns: Whether the reallocation was successful.
|
||||
*/
|
||||
bool reallocate(ref void[] p, size_t size) shared @nogc @trusted nothrow
|
||||
bool reallocate(ref void[] p, size_t size) @nogc @trusted nothrow
|
||||
{
|
||||
void[] reallocP;
|
||||
|
||||
@ -301,7 +301,7 @@ class MmapPool : Allocator
|
||||
*
|
||||
* Returns: Global $(D_PSYMBOL MmapPool) instance.
|
||||
*/
|
||||
static @property ref shared(MmapPool) instance() @nogc @trusted nothrow
|
||||
static @property ref MmapPool instance() @nogc @trusted nothrow
|
||||
{
|
||||
if (instance_ is null)
|
||||
{
|
||||
@ -312,7 +312,7 @@ class MmapPool : Allocator
|
||||
if (data !is null)
|
||||
{
|
||||
data[0..instanceSize] = typeid(MmapPool).initializer[];
|
||||
instance_ = cast(shared MmapPool) data;
|
||||
instance_ = cast(MmapPool) data;
|
||||
instance_.head = head;
|
||||
}
|
||||
}
|
||||
@ -334,7 +334,6 @@ class MmapPool : Allocator
|
||||
*
|
||||
* Returns: A pointer to the data.
|
||||
*/
|
||||
pragma(inline)
|
||||
private static void* initializeRegion(size_t size,
|
||||
ref Region head) @nogc nothrow
|
||||
{
|
||||
@ -409,7 +408,7 @@ class MmapPool : Allocator
|
||||
}
|
||||
|
||||
/// Ditto.
|
||||
private void* initializeRegion(size_t size) shared @nogc nothrow
|
||||
private void* initializeRegion(size_t size) @nogc nothrow
|
||||
{
|
||||
return initializeRegion(size, head);
|
||||
}
|
||||
@ -451,13 +450,13 @@ class MmapPool : Allocator
|
||||
return x / pageSize * pageSize + pageSize;
|
||||
}
|
||||
|
||||
@property immutable(uint) alignment() shared const @nogc @safe pure nothrow
|
||||
@property uint alignment() const @nogc @safe pure nothrow
|
||||
{
|
||||
return alignment_;
|
||||
}
|
||||
private enum alignment_ = 8;
|
||||
|
||||
private shared static MmapPool instance_;
|
||||
private static MmapPool instance_;
|
||||
|
||||
private shared static immutable size_t pageSize;
|
||||
|
||||
|
@ -10,20 +10,10 @@
|
||||
*/
|
||||
module tanya.memory;
|
||||
|
||||
public
|
||||
{
|
||||
import tanya.memory.allocator;
|
||||
import std.experimental.allocator : make, dispose, shrinkArray, expandArray, makeArray, dispose;
|
||||
}
|
||||
public import tanya.memory.allocator;
|
||||
public import std.experimental.allocator;
|
||||
|
||||
shared Allocator allocator;
|
||||
|
||||
@property ref shared(Allocator) defaultAllocator()
|
||||
@property IAllocator defaultAllocator()
|
||||
{
|
||||
import tanya.memory.mallocator;
|
||||
if (allocator is null)
|
||||
{
|
||||
allocator = Mallocator.instance;
|
||||
}
|
||||
return allocator;
|
||||
return theAllocator;
|
||||
}
|
||||
|
Reference in New Issue
Block a user