1 /// Qualified (`@safe pure nothrow @nogc`) C memory management. 2 module nxt.qcmeman; 3 4 extern(C) 5 { 6 // qualified C memory allocations 7 pure nothrow @nogc: 8 9 /* See_Also: 10 * https://forum.dlang.org/post/mailman.1130.1521239659.3374.digitalmars-d@puremagic.com 11 * for an explanation of why `pureMalloc` and `pureCalloc` both can 12 * be @trusted. */ 13 void* malloc(size_t size) @trusted; 14 15 void* calloc(size_t nmemb, size_t size) @trusted; 16 17 void* realloc(void* ptr, size_t size) @system; 18 19 void* alloca(size_t length) @safe; 20 21 void free(void* ptr) @system; 22 23 void gc_addRange(in void* p, size_t sz, const TypeInfo ti = null); 24 void gc_removeRange(in void* p ); 25 } 26 27 /** 28 * Pure variants of C's memory allocation functions `malloc`, `calloc`, and 29 * `realloc` and deallocation function `free`. 30 * 31 * Purity is achieved by saving and restoring the value of `errno`, thus 32 * behaving as if it were never changed. 33 * 34 * See_Also: 35 * $(LINK2 https://dlang.org/spec/function.html#pure-functions, D's rules for purity), 36 * which allow for memory allocation under specific circumstances. 37 */ 38 private void* pureMalloc(size_t size) @trusted pure @nogc nothrow 39 { 40 debug const errno = fakePureGetErrno(); 41 void* ret = fakePureMalloc(size); 42 debug if (!ret || errno != 0) 43 { 44 cast(void)fakePureSetErrno(errno); 45 } 46 return ret; 47 } 48 /// ditto 49 private void* pureCalloc(size_t nmemb, size_t size) @trusted pure @nogc nothrow 50 { 51 debug const errno = fakePureGetErrno(); 52 void* ret = fakePureCalloc(nmemb, size); 53 debug if (!ret || errno != 0) 54 { 55 cast(void)fakePureSetErrno(errno); 56 } 57 return ret; 58 } 59 /// ditto 60 private void* pureRealloc(void* ptr, size_t size) @system pure @nogc nothrow 61 { 62 debug const errno = fakePureGetErrno(); 63 void* ret = fakePureRealloc(ptr, size); 64 debug if (!ret || errno != 0) 65 { 66 cast(void)fakePureSetErrno(errno); 67 } 68 return ret; 69 } 70 /// ditto 71 void pureFree(void* ptr) @system pure @nogc nothrow 72 { 73 debug const errno = fakePureGetErrno(); 74 fakePureFree(ptr); 75 debug cast(void)fakePureSetErrno(errno); 76 } 77 78 // locally purified for internal use here only 79 extern (C) private pure @system @nogc nothrow 80 { 81 pragma(mangle, "getErrno") int fakePureGetErrno(); 82 pragma(mangle, "setErrno") int fakePureSetErrno(int); 83 84 pragma(mangle, "malloc") void* fakePureMalloc(size_t); 85 pragma(mangle, "calloc") void* fakePureCalloc(size_t nmemb, size_t size); 86 pragma(mangle, "realloc") void* fakePureRealloc(void* ptr, size_t size); 87 88 pragma(mangle, "free") void fakePureFree(void* ptr); 89 }