diff options
author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-03-10 20:44:06 -0700 |
---|---|---|
committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-03-10 20:44:06 -0700 |
commit | f81d7cc0184b1586270ecf41386d98942df3cf99 (patch) | |
tree | 8d3e5a7d5880d02c6af2fdaa8f97e23035ad66e7 /tests/allocator.cpp | |
parent | e5ecbd63ce75de0a8f1473cbe0c1f9eea657dd02 (diff) | |
parent | 604861e520d2d6579674a1c2bd5e59cb10f7ecd2 (diff) |
Merge branch 'master' into compact
Diffstat (limited to 'tests/allocator.cpp')
-rw-r--r-- | tests/allocator.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/tests/allocator.cpp b/tests/allocator.cpp index 094d5e5..74bbf10 100644 --- a/tests/allocator.cpp +++ b/tests/allocator.cpp @@ -66,6 +66,50 @@ namespace VirtualProtect(rptr, aligned_size + PAGE_SIZE, PAGE_NOACCESS, &old_flags); } } +#elif defined(__APPLE__) || defined(__linux__) +# include <sys/mman.h> + +namespace +{ + const size_t PAGE_SIZE = 4096; + + size_t align_to_page(size_t value) + { + return (value + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + } + + void* allocate_page_aligned(size_t size) + { + return mmap(0, size + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + } + + void* allocate(size_t size) + { + size_t aligned_size = align_to_page(size); + + void* ptr = allocate_page_aligned(aligned_size + PAGE_SIZE); + if (!ptr) return 0; + + char* end = static_cast<char*>(ptr) + aligned_size; + + int res = mprotect(end, PAGE_SIZE, PROT_NONE); + assert(res == 0); + (void)!res; + + return end - size; + } + + void deallocate(void* ptr, size_t size) + { + size_t aligned_size = align_to_page(size); + + void* rptr = static_cast<char*>(ptr) + size - aligned_size; + + int res = mprotect(rptr, aligned_size + PAGE_SIZE, PROT_NONE); + assert(res == 0); + (void)!res; + } +} #else # include <stdlib.h> |