static void * mmap_checked(size_t size, size_t align, int flags) { /* The size must be a power of two. */ assert((size & (size - 1)) == 0); assert((align & (align - 1)) == 0); /* * mmap twice the requested amount to be able to align * the mapped address. * @todo all mappings except the first are likely to * be aligned already. Find out if trying to map * optimistically exactly the requested amount and fall * back to double-size mapping is a viable strategy. */ void *map = mmap(NULL, size + align, PROT_READ | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0); if (map == MAP_FAILED) return NULL; /* Align the mapped address around slab size. */ size_t offset = (intptr_t) map & (align - 1); if (offset != 0) { /* Unmap unaligned prefix and postfix. */ munmap_checked(map, align - offset); map += align - offset; munmap_checked(map + size, offset); } else { /* The address is returned aligned. */ munmap_checked(map + size, align); } return map; }
void slab_arena_destroy(struct slab_arena *arena) { void *ptr; size_t total = 0; while ((ptr = lf_lifo_pop(&arena->cache))) { if (arena->arena == NULL || ptr < arena->arena || ptr >= arena->arena + arena->prealloc) { munmap_checked(ptr, arena->slab_size); } total += arena->slab_size; } if (arena->arena) munmap_checked(arena->arena, arena->prealloc); assert(total == arena->used); }
static void * mmap_checked(size_t size, size_t align, int flags) { /* The alignment must be a power of two. */ assert((align & (align - 1)) == 0); /* The size must be a multiple of alignment */ assert((size & (align - 1)) == 0); /* * All mappings except the first are likely to * be aligned already. Be optimistic by trying * to map exactly the requested amount. */ void *map = mmap(NULL, size, PROT_READ | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0); if (map == MAP_FAILED) return NULL; if (((intptr_t) map & (align - 1)) == 0) return map; munmap_checked(map, size); /* * mmap enough amount to be able to align * the mapped address. This can lead to virtual memory * fragmentation depending on the kernels allocation * strategy. */ map = mmap(NULL, size + align, PROT_READ | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0); if (map == MAP_FAILED) return NULL; /* Align the mapped address around slab size. */ size_t offset = (intptr_t) map & (align - 1); if (offset != 0) { /* Unmap unaligned prefix and postfix. */ munmap_checked(map, align - offset); map += align - offset; munmap_checked(map + size, offset); } else { /* The address is returned aligned. */ munmap_checked(map + size, align); } return map; }