Example #1
0
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;
}
Example #2
0
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);
}
Example #3
0
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;
}