std.experimental.allocator.building_blocks.free_list
- struct FreeList(ParentAllocator, size_t minSize, size_t maxSize = minSize, Flag!"adaptive" adaptive = No.adaptive);
-
Free list allocator, stackable on top of another allocator. Allocation requests between
min
andmax
bytes are rounded up tomax
and served from a singly-linked list of buffers deallocated in the past. All other allocations are directed toParentAllocator
. Due to the simplicity of free list management, allocations from the free list are fast. Ifadaptive
is set toYes.adaptive
, the free list gradually reduces its size if allocations tend to use the parent allocator much more than the lists' available nodes.One instantiation is of particular interest:
FreeList!(0, unbounded)
puts every deallocation in the freelist, and subsequently serves any allocation from the freelist (if not empty). There is no checking of size matching, which would be incorrect for a freestanding allocator but is both correct and fast when an owning allocator on top of the free list allocator (such asSegregator
) is already in charge of handling size checking.
The following methods are defined ifParentAllocator
defines them, and forward to it:expand
,owns
,reallocate
.- const @property size_t min();
-
Returns the smallest allocation size eligible for allocation from the freelist. (If
minSize != chooseAtRuntime
, this is simply an alias forminSize
.) - @property void min(size_t low);
-
If
FreeList
has been instantiated withminSize == chooseAtRuntime
, then themin
property is writable. Setting it must precede any allocation.- Parameters:
size_t low
new value for min
- Precondition
-
low <= max
, ormaxSize == chooseAtRuntime
andmax
has not yet been initialized. Also, no allocation has been yet done with this allocator.
- Postcondition
-
min == low
- const @property size_t max();
-
Returns the largest allocation size eligible for allocation from the freelist. (If
maxSize != chooseAtRuntime
, this is simply an alias formaxSize
.) All allocation requests for sizes greater than or equal tomin
and less than or equal tomax
are rounded tomax
and forwarded to the parent allocator. When the block fitting the same constraint gets deallocated, it is put in the freelist with the allocated size assumed to bemax
. - @property void max(size_t high);
-
If
FreeList
has been instantiated withmaxSize == chooseAtRuntime
, then themax
property is writable. Setting it must precede any allocation.- Parameters:
size_t high
new value for max
- Precondition
-
high >= min
, orminSize == chooseAtRuntime
andmin
has not yet been initialized. Alsohigh >= (void*).sizeof
. Also, no allocation has been yet done with this allocator.
- Postcondition
-
max == high
- ParentAllocator parent;
-
The parent allocator. Depending on whether
ParentAllocator
holds state or not, this is a member variable or an alias forParentAllocator.instance
. - alias alignment = ParentAllocator.alignment;
-
Alignment offered.
- size_t goodAllocSize(size_t bytes);
-
If
maxSize == unbounded
, returnsparent.goodAllocSize(bytes)
. Otherwise, returnsmax
for sizes in the interval[min, max]
, andparent.goodAllocSize(bytes)
otherwise.- Precondition
- If set at runtime,
min
and/ormax
must be initialized appropriately.
- Postcondition
-
result >= bytes
- void[] allocate(size_t n);
-
Allocates memory either off of the free list or from the parent allocator. If
n
is within[min, max]
or if the free list is unchecked (minSize == 0 && maxSize == size_t.max
), then the free list is consulted first. If not empty (hit), the block at the front of the free list is removed from the list and returned. Otherwise (miss), a new block ofmax
bytes is allocated, truncated ton
bytes, and returned.- Parameters:
size_t n
number of bytes to allocate
- Returns:
- The allocated block, or
null
.
- Precondition
- If set at runtime,
min
and/ormax
must be initialized appropriately.
- Postcondition
-
result.length == bytes || result is null
- bool deallocate(void[] block);
-
If
block.length
is within[min, max]
or if the free list is unchecked (minSize == 0 && maxSize == size_t.max
), then inserts the block at the front of the free list. For all others, forwards toparent.deallocate
ifParent.deallocate
is defined.- Parameters:
void[] block
Block to deallocate.
- Precondition
- If set at runtime,
min
and/ormax
must be initialized appropriately. The block must have been allocated with this freelist, and no dynamic changing ofmin
ormax
is allowed to occur between allocation and deallocation.
- bool deallocateAll();
-
Defined only if
ParentAllocator
definesdeallocateAll
. If so, forwards to it and resets the freelist. - void minimize();
-
Nonstandard function that minimizes the memory usage of the freelist by freeing each element in turn. Defined only if
ParentAllocator
definesdeallocate
.FreeList!(0, unbounded)
does not have this function.
- struct ContiguousFreeList(ParentAllocator, size_t minSize, size_t maxSize = minSize);
-
Free list built on top of exactly one contiguous block of memory. The block is assumed to have been allocated with
ParentAllocator
, and is released inContiguousFreeList
's destructor (unlessParentAllocator
isNullAllocator
).ContiguousFreeList
has most advantages ofFreeList
but fewer disadvantages. It has better cache locality because items are closer to one another. It imposes less fragmentation on its parent allocator.
The disadvantages ofContiguousFreeList
overFreeList
are its pay upfront model (as opposed toFreeList
's pay-as-you-go approach), and a hard limit on the number of nodes in the list. Thus, a large number of long- lived objects may occupy the entire block, making it unavailable for serving allocations from the free list. However, an absolute cap on the free list size may be beneficial.
The optionsminSize == unbounded
andmaxSize == unbounded
are not available forContiguousFreeList
.- Examples:
-
import std.experimental.allocator.building_blocks.allocator_list : AllocatorList; import std.experimental.allocator.gc_allocator : GCAllocator; import std.experimental.allocator.common : unbounded; alias ScalableFreeList = AllocatorList!((n) => ContiguousFreeList!(GCAllocator, 0, unbounded)(4096) );
- SParent parent;
-
The parent allocator. Depending on whether
ParentAllocator
holds state or not, this is a member variable or an alias forParentAllocator.instance
. - enum uint alignment;
-
Alignment offered.
- this(ubyte[] buffer);
this(ParentAllocator parent, ubyte[] buffer);
this(size_t bytes);
this(ParentAllocator parent, size_t bytes);
this(size_t bytes, size_t max);
this(ParentAllocator parent, size_t bytes, size_t max);
this(size_t bytes, size_t min, size_t max);
this(ParentAllocator parent, size_t bytes, size_t min, size_t max); -
Constructors setting up the memory structured as a free list.
- Parameters:
ubyte[] buffer
Buffer to structure as a free list. If ParentAllocator
is notNullAllocator
, the buffer is assumed to be allocated byparent
and will be freed in the destructor.ParentAllocator parent
Parent allocator. For construction from stateless allocators, use their instance
static member.size_t bytes
Bytes (not items) to be allocated for the free list. Memory will be allocated during construction and deallocated in the destructor. size_t max
Maximum size eligible for freelisting. Construction with this parameter is defined only if maxSize == chooseAtRuntime
ormaxSize == unbounded
.size_t min
Minimum size eligible for freelisting. Construction with this parameter is defined only if minSize == chooseAtRuntime
. If this condition is met and nomin
parameter is present,min
is initialized withmax
.
- size_t goodAllocSize(size_t n);
-
If
n
is eligible for freelisting, returnsmax
. Otherwise, returnsparent.goodAllocSize(n)
.- Precondition
- If set at runtime,
min
and/ormax
must be initialized appropriately.
- Postcondition
-
result >= bytes
- void[] allocate(size_t n);
-
Allocate
n
bytes of memory. Ifn
is eligible for freelist and the freelist is not empty, pops the memory off the free list. In all other cases, uses the parent allocator. - Ternary owns(void[] b);
-
Defined if
ParentAllocator
defines it. Checks whether the block belongs to this allocator. - bool deallocate(void[] b);
-
Deallocates
b
. If it's of eligible size, it's put on the free list. Otherwise, it's returned toparent
.- Precondition
-
b
has been allocated with this allocator, or isnull
.
- bool deallocateAll();
-
Deallocates everything from the parent.
- Ternary empty();
-
Returns
Ternary.yes
if no memory is currently allocated with this allocator,Ternary.no
otherwise. This method never returnsTernary.unknown
.
-
FreeList shared across threads. Allocation and deallocation are lock-free. The parameters have the same semantics as for
FreeList
.expand
is defined to forward toParentAllocator.expand
(it must be alsoshared
).- Examples:
-
import std.experimental.allocator.common : chooseAtRuntime; import std.experimental.allocator.mallocator : Mallocator; shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) a; a.setBounds(64, 128); writeln(a.max); // 128 writeln(a.min); // 64
- Examples:
-
import std.experimental.allocator.common : chooseAtRuntime; import std.experimental.allocator.mallocator : Mallocator; shared SharedFreeList!(Mallocator, 50, 50, chooseAtRuntime) a; // Set the maxSize first so setting the minSize doesn't throw a.approxMaxLength = 128; writeln(a.approxMaxLength); // 128 a.approxMaxLength = 1024; writeln(a.approxMaxLength); // 1024 a.approxMaxLength = 1; writeln(a.approxMaxLength); // 1
-
Properties for getting (and possibly setting) the bounds. Setting bounds is allowed only once , and before any allocation takes place. Otherwise, the primitives have the same semantics as those of
FreeList
. -
Properties for getting (and possibly setting) the approximate maximum length of a shared freelist.
-
The parent allocator. Depending on whether
ParentAllocator
holds state or not, this is a member variable or an alias forParentAllocator.instance
. -
Standard primitives.
-
Nonstandard function that minimizes the memory usage of the freelist by freeing each element in turn. Defined only if
ParentAllocator
definesdeallocate
.
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_experimental_allocator_building_blocks_free_list.html