module gc.alloc;
+
// C OS-specific API
+
private extern (C) {
version (Win32) {
alias void* POINTER;
}
}
-static if (is(typeof(VirtualAlloc)))
-{
- /**
- * Map memory.
- */
- void *os_mem_map(size_t nbytes)
- {
- return VirtualAlloc(null, nbytes, MEM_RESERVE, PAGE_READWRITE);
- }
-
-
- /**
- * Commit memory.
- * Returns:
- * 0 success
- * !=0 failure
- */
- int os_mem_commit(void *base, size_t offset, size_t nbytes)
- { void *p;
-
- p = VirtualAlloc(base + offset, nbytes, MEM_COMMIT, PAGE_READWRITE);
- return cast(int)(p is null);
- }
+// Public interface
+version (D_Ddoc)
+{
/**
- * Decommit memory.
- * Returns:
- * 0 success
- * !=0 failure
+ * Map memory.
*/
- int os_mem_decommit(void *base, size_t offset, size_t nbytes)
- {
- return cast(int)(VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0);
- }
-
+ void* os_mem_map(size_t nbytes);
/**
* Unmap memory allocated with os_mem_map().
- * Memory must have already been decommitted.
* Returns:
- * 0 success
- * !=0 failure
+ * true success
+ * false failure
*/
- int os_mem_unmap(void *base, size_t nbytes)
- {
- return cast(int)(VirtualFree(base, 0, MEM_RELEASE) == 0);
- }
+ bool os_mem_unmap(void* base, size_t nbytes);
}
-else static if (is(typeof(mmap)) && is(typeof(MAP_ANON)))
+// Implementations
+else static if (is(typeof(VirtualAlloc)))
{
- void *os_mem_map(size_t nbytes)
- { void *p;
-
- p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
- return (p == MAP_FAILED) ? null : p;
- }
-
-
- int os_mem_commit(void *base, size_t offset, size_t nbytes)
+ void* os_mem_map(size_t nbytes)
{
- return 0;
+ return VirtualAlloc(null, nbytes, MEM_RESERVE | MEM_COMMIT,
+ PAGE_READWRITE);
}
-
- int os_mem_decommit(void *base, size_t offset, size_t nbytes)
- {
- return 0;
- }
-
-
- int os_mem_unmap(void *base, size_t nbytes)
+ bool os_mem_unmap(void* base, size_t nbytes)
{
- return munmap(base, nbytes);
+ return VirtualFree(base, 0, MEM_RELEASE) != 0;
}
}
-else static if (is(typeof(valloc)))
+else static if (is(typeof(mmap)) && is(typeof(MAP_ANON)))
{
- void *os_mem_map(size_t nbytes)
+ void* os_mem_map(size_t nbytes)
{
- return valloc(nbytes);
- }
-
-
- int os_mem_commit(void *base, size_t offset, size_t nbytes)
- {
- return 0;
+ void* p = mmap(null, nbytes,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ return (p == MAP_FAILED) ? null : p;
}
-
- int os_mem_decommit(void *base, size_t offset, size_t nbytes)
+ bool os_mem_unmap(void* base, size_t nbytes)
{
- return 0;
- }
-
-
- int os_mem_unmap(void *base, size_t nbytes)
- {
- free(base);
- return 0;
+ return munmap(base, nbytes) == 0;
}
}
else static if (is(typeof(malloc)))
// to PAGESIZE alignment, there will be space for a void* at the end
// after PAGESIZE bytes used by the GC.
-
import gcx; // for PAGESIZE
-
const size_t PAGE_MASK = PAGESIZE - 1;
-
- void *os_mem_map(size_t nbytes)
- { byte *p, q;
- p = cast(byte *) malloc(nbytes + PAGESIZE);
+ void* os_mem_map(size_t nbytes)
+ {
+ byte* p, q;
+ p = cast(byte* ) malloc(nbytes + PAGESIZE);
q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);
- * cast(void**)(q + nbytes) = p;
+ *cast(void**)(q + nbytes) = p;
return q;
}
-
- int os_mem_commit(void *base, size_t offset, size_t nbytes)
- {
- return 0;
- }
-
-
- int os_mem_decommit(void *base, size_t offset, size_t nbytes)
- {
- return 0;
- }
-
-
- int os_mem_unmap(void *base, size_t nbytes)
+ bool os_mem_unmap(void* base, size_t nbytes)
{
- free( *cast(void**)( cast(byte*) base + nbytes ) );
- return 0;
+ free(*cast(void**)(cast(byte*) base + nbytes));
+ return true;
}
}
else