std.experimental.allocator.building_blocks.ascending_page_allocator
- struct AscendingPageAllocator;
-
AscendingPageAllocator
is a fast and safe allocator that rounds all allocations to multiples of the system's page size. It reserves a range of virtual addresses (usingmmap
on Posix andVirtualAlloc
on Windows) and allocates memory at consecutive virtual addresses.When a chunk of memory is requested, the allocator finds a range of virtual pages that satisfy the requested size, changing their protection to read/write using OS primitives (
mprotect
andVirtualProtect
, respectively). The physical memory is allocated on demand, when the pages are accessed.
Deallocation removes any read/write permissions from the target pages and notifies the OS to reclaim the physical memory, while keeping the virtual memory.
Because the allocator does not reuse memory, any dangling references to deallocated memory will always result in deterministically crashing the process.- See Also:
- Simple Fast and Safe Manual Memory Management for the general approach.
- Examples:
-
import core.memory : pageSize; size_t numPages = 100; void[] buf; void[] prevBuf = null; AscendingPageAllocator a = AscendingPageAllocator(numPages * pageSize); foreach (i; 0 .. numPages) { // Allocation is rounded up to page size buf = a.allocate(pageSize - 100); writeln(buf.length); // pageSize - 100 // Allocations are served at increasing addresses if (prevBuf) writeln(prevBuf.ptr + pageSize); // buf.ptr assert(a.deallocate(buf)); prevBuf = buf; }
- nothrow @nogc this(size_t n);
-
Rounds the mapping size to the next multiple of the page size and calls the OS primitive responsible for creating memory mappings:
mmap
on POSIX andVirtualAlloc
on Windows.- Parameters:
size_t n
mapping size in bytes
- nothrow @nogc size_t goodAllocSize(size_t n);
-
Rounds the requested size to the next multiple of the page size.
- nothrow @nogc void deallocate(void[] b);
-
Decommit all physical memory associated with the buffer given as parameter, but keep the range of virtual addresses.
On POSIX systems
deallocate
callsmmap
with `MAP_FIXED' a second time to decommit the memory. On Windows, it usesVirtualFree
withMEM_DECOMMIT
. - nothrow @nogc Ternary owns(void[] buf);
-
Returns
Ternary.yes
if the passed buffer is inside the range of virtual adresses. Does not guarantee that the passed buffer is still valid. - nothrow @nogc bool deallocateAll();
-
Removes the memory mapping causing all physical memory to be decommited and the virtual address space to be reclaimed.
- nothrow @nogc size_t getAvailableSize();
-
Returns the available size for further allocations in bytes.
- nothrow @nogc void[] allocate(size_t n);
-
Rounds the allocation size to the next multiple of the page size. The allocation only reserves a range of virtual pages but the actual physical memory is allocated on demand, when accessing the memory.
- Parameters:
size_t n
Bytes to allocate
- Returns:
-
null
on failure or if the requested size exceeds the remaining capacity.
- nothrow @nogc void[] alignedAllocate(size_t n, uint a);
-
Rounds the allocation size to the next multiple of the page size. The allocation only reserves a range of virtual pages but the actual physical memory is allocated on demand, when accessing the memory.
The allocated memory is aligned to the specified alignment
a
.- Parameters:
size_t n
Bytes to allocate uint a
Alignment
- Returns:
-
null
on failure or if the requested size exceeds the remaining capacity.
- nothrow @nogc bool expand(ref void[] b, size_t delta);
-
If the passed buffer is not the last allocation, then
delta
can be at most the number of bytes left on the last page. Otherwise, we can expand the last allocation until the end of the virtual address range. - nothrow @nogc Ternary empty();
-
Returns
Ternary.yes
if the allocator does not contain any alive objects andTernary.no
otherwise.
-
SharedAscendingPageAllocator
is the threadsafe version ofAscendingPageAllocator
.- Examples:
-
import core.memory : pageSize; import core.thread : ThreadGroup; enum numThreads = 100; shared SharedAscendingPageAllocator a = SharedAscendingPageAllocator(pageSize * numThreads); void fun() { void[] b = a.allocate(pageSize); writeln(b.length); // pageSize assert(a.deallocate(b)); } auto tg = new ThreadGroup; foreach (i; 0 .. numThreads) { tg.create(&fun); } tg.joinAll();
-
Rounds the mapping size to the next multiple of the page size and calls the OS primitive responsible for creating memory mappings:
mmap
on POSIX andVirtualAlloc
on Windows.- Parameters:
size_t n
mapping size in bytes
-
Rounds the requested size to the next multiple of the page size.
-
Decommit all physical memory associated with the buffer given as parameter, but keep the range of virtual addresses.
On POSIX systems
deallocate
callsmmap
with `MAP_FIXED' a second time to decommit the memory. On Windows, it usesVirtualFree
withMEM_DECOMMIT
. -
Returns
Ternary.yes
if the passed buffer is inside the range of virtual adresses. Does not guarantee that the passed buffer is still valid. -
Removes the memory mapping causing all physical memory to be decommited and the virtual address space to be reclaimed.
-
Returns the available size for further allocations in bytes.
-
Rounds the allocation size to the next multiple of the page size. The allocation only reserves a range of virtual pages but the actual physical memory is allocated on demand, when accessing the memory.
- Parameters:
size_t n
Bytes to allocate
- Returns:
-
null
on failure or if the requested size exceeds the remaining capacity.
-
Rounds the allocation size to the next multiple of the page size. The allocation only reserves a range of virtual pages but the actual physical memory is allocated on demand, when accessing the memory.
The allocated memory is aligned to the specified alignment
a
.- Parameters:
size_t n
Bytes to allocate uint a
Alignment
- Returns:
-
null
on failure or if the requested size exceeds the remaining capacity.
-
If the passed buffer is not the last allocation, then
delta
can be at most the number of bytes left on the last page. Otherwise, we can expand the last allocation until the end of the virtual address range.
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_experimental_allocator_building_blocks_ascending_page_allocator.html