Created
January 6, 2012 17:58
-
-
Save mikeash/1571661 to your computer and use it in GitHub Desktop.
mirrored ring buffer allocator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <mach/mach.h> | |
#include <mach/vm_map.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
void *allocate_pair(size_t howmuch) | |
{ | |
#define CHECK_ERR do { \ | |
if(err != KERN_SUCCESS) { \ | |
fprintf(stderr, "%d: got error %d\n", __LINE__, err); \ | |
exit(1); \ | |
} \ | |
} while(0) | |
void *mem = NULL; | |
int success = 0; | |
while(!success) | |
{ | |
kern_return_t err = vm_allocate(mach_task_self(), (vm_address_t *)&mem, howmuch * 2, VM_FLAGS_ANYWHERE); | |
CHECK_ERR; | |
void *target = mem + howmuch; | |
err = vm_deallocate(mach_task_self(), (vm_address_t)target, howmuch); | |
CHECK_ERR; | |
vm_prot_t cur_protection, max_protection; | |
err = vm_remap(mach_task_self(), | |
(vm_address_t *)&target, | |
howmuch, | |
0, // mask | |
0, // anywhere | |
mach_task_self(), | |
(vm_address_t)mem, | |
0, // copy | |
&cur_protection, | |
&max_protection, | |
VM_INHERIT_COPY); | |
if(err == KERN_PROTECTION_FAILURE) | |
{ | |
err = vm_deallocate(mach_task_self(), (vm_address_t)mem, howmuch); | |
CHECK_ERR; | |
} | |
else | |
{ | |
success = 1; | |
CHECK_ERR; | |
} | |
} | |
return mem; | |
} | |
int main(void) | |
{ | |
int len = 4096; | |
char *mem = allocate_pair(len); | |
printf("%d: equal=%s\n", __LINE__, memcmp(mem, mem + len, len) == 0 ? "YES" : "NO"); | |
int i; | |
for(i = 0; i < len; i++) | |
mem[i] = i; | |
printf("%d: equal=%s\n", __LINE__, memcmp(mem, mem + len, len) == 0 ? "YES" : "NO"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment