Skip to content

Instantly share code, notes, and snippets.

@mikeash
Created January 6, 2012 17:58
Show Gist options
  • Save mikeash/1571661 to your computer and use it in GitHub Desktop.
Save mikeash/1571661 to your computer and use it in GitHub Desktop.
mirrored ring buffer allocator
#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