mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
78 lines
2.2 KiB
D
78 lines
2.2 KiB
D
///
|
|
module std.experimental.allocator.mmap_allocator;
|
|
|
|
// MmapAllocator
|
|
/**
|
|
|
|
Allocator (currently defined only for Posix and Windows) using $(D $(LUCKY mmap))
|
|
and $(D $(LUCKY munmap)) directly (or their Windows equivalents). There is no
|
|
additional structure: each call to $(D allocate(s)) issues a call to
|
|
$(D mmap(null, s, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)),
|
|
and each call to $(D deallocate(b)) issues $(D munmap(b.ptr, b.length)).
|
|
So $(D MmapAllocator) is usually intended for allocating large chunks to be
|
|
managed by fine-granular allocators.
|
|
|
|
*/
|
|
struct MmapAllocator
|
|
{
|
|
/// The one shared instance.
|
|
static shared MmapAllocator instance;
|
|
|
|
/**
|
|
Alignment is page-size and hardcoded to 4096 (even though on certain systems
|
|
it could be larger).
|
|
*/
|
|
enum size_t alignment = 4096;
|
|
|
|
version(Posix)
|
|
{
|
|
/// Allocator API.
|
|
void[] allocate(size_t bytes) shared
|
|
{
|
|
import core.sys.posix.sys.mman : mmap, MAP_ANON, PROT_READ,
|
|
PROT_WRITE, MAP_PRIVATE, MAP_FAILED;
|
|
if (!bytes) return null;
|
|
auto p = mmap(null, bytes, PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
if (p is MAP_FAILED) return null;
|
|
return p[0 .. bytes];
|
|
}
|
|
|
|
/// Ditto
|
|
bool deallocate(void[] b) shared
|
|
{
|
|
import core.sys.posix.sys.mman : munmap;
|
|
if (b.ptr) munmap(b.ptr, b.length) == 0 || assert(0);
|
|
return true;
|
|
}
|
|
}
|
|
else version(Windows)
|
|
{
|
|
import core.sys.windows.windows : VirtualAlloc, VirtualFree, MEM_COMMIT,
|
|
PAGE_READWRITE, MEM_RELEASE;
|
|
|
|
/// Allocator API.
|
|
void[] allocate(size_t bytes) shared
|
|
{
|
|
if (!bytes) return null;
|
|
auto p = VirtualAlloc(null, bytes, MEM_COMMIT, PAGE_READWRITE);
|
|
if (p == null)
|
|
return null;
|
|
return p[0 .. bytes];
|
|
}
|
|
|
|
/// Ditto
|
|
bool deallocate(void[] b) shared
|
|
{
|
|
return b.ptr is null || VirtualFree(b.ptr, 0, MEM_RELEASE) != 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
@system unittest
|
|
{
|
|
alias alloc = MmapAllocator.instance;
|
|
auto p = alloc.allocate(100);
|
|
assert(p.length == 100);
|
|
alloc.deallocate(p);
|
|
}
|