1 /// 2 module std.experimental.allocator.mmap_allocator; 3 4 // MmapAllocator 5 /** 6 7 Allocator (currently defined only for Posix and Windows) using 8 $(D $(LINK2 https://en.wikipedia.org/wiki/Mmap, mmap)) 9 and $(D $(LUCKY munmap)) directly (or their Windows equivalents). There is no 10 additional structure: each call to $(D allocate(s)) issues a call to 11 $(D mmap(null, s, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)), 12 and each call to $(D deallocate(b)) issues $(D munmap(b.ptr, b.length)). 13 So $(D MmapAllocator) is usually intended for allocating large chunks to be 14 managed by fine-granular allocators. 15 16 */ 17 struct MmapAllocator 18 { 19 /// The one shared instance. 20 static shared MmapAllocator instance; 21 22 /** 23 Alignment is page-size and hardcoded to 4096 (even though on certain systems 24 it could be larger). 25 */ 26 enum size_t alignment = 4096; 27 versionMmapAllocator28 version (Posix) 29 { 30 /// Allocator API. 31 void[] allocate(size_t bytes) shared 32 { 33 import core.sys.posix.sys.mman : mmap, MAP_ANON, PROT_READ, 34 PROT_WRITE, MAP_PRIVATE, MAP_FAILED; 35 if (!bytes) return null; 36 auto p = mmap(null, bytes, PROT_READ | PROT_WRITE, 37 MAP_PRIVATE | MAP_ANON, -1, 0); 38 if (p is MAP_FAILED) return null; 39 return p[0 .. bytes]; 40 } 41 42 /// Ditto 43 bool deallocate(void[] b) shared 44 { 45 import core.sys.posix.sys.mman : munmap; 46 if (b.ptr) munmap(b.ptr, b.length) == 0 || assert(0); 47 return true; 48 } 49 50 // Anonymous mmap might be zero-filled on all Posix systems but 51 // not all commit to this in the documentation. 52 version (linux) 53 // http://man7.org/linux/man-pages/man2/mmap.2.html 54 package alias allocateZeroed = allocate; 55 else version (NetBSD) 56 // http://netbsd.gw.com/cgi-bin/man-cgi?mmap+2+NetBSD-current 57 package alias allocateZeroed = allocate; 58 else version (Solaris) 59 // https://docs.oracle.com/cd/E88353_01/html/E37841/mmap-2.html 60 package alias allocateZeroed = allocate; 61 else version (AIX) 62 // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.basetrf1/mmap.htm 63 package alias allocateZeroed = allocate; 64 } versionMmapAllocator65 else version (Windows) 66 { 67 import core.sys.windows.windows : VirtualAlloc, VirtualFree, MEM_COMMIT, 68 PAGE_READWRITE, MEM_RELEASE; 69 70 /// Allocator API. 71 void[] allocate(size_t bytes) shared 72 { 73 if (!bytes) return null; 74 auto p = VirtualAlloc(null, bytes, MEM_COMMIT, PAGE_READWRITE); 75 if (p == null) 76 return null; 77 return p[0 .. bytes]; 78 } 79 80 /// Ditto 81 bool deallocate(void[] b) shared 82 { 83 return b.ptr is null || VirtualFree(b.ptr, 0, MEM_RELEASE) != 0; 84 } 85 86 package alias allocateZeroed = allocate; 87 } 88 } 89 90 @system unittest 91 { 92 alias alloc = MmapAllocator.instance; 93 auto p = alloc.allocate(100); 94 assert(p.length == 100); 95 alloc.deallocate(p); 96 } 97