Пример #1
0
int
slab_arena_create(struct slab_arena *arena, struct quota *quota,
		  size_t prealloc, uint32_t slab_size, int flags)
{
	assert(flags & (MAP_PRIVATE | MAP_SHARED));
	lf_lifo_init(&arena->cache);
	/*
	 * Round up the user supplied data - it can come in
	 * directly from the configuration file. Allow
	 * zero-size arena for testing purposes.
	 */
	arena->slab_size = small_round(MAX(slab_size, SLAB_MIN_SIZE));

	arena->quota = quota;
	/** Prealloc can not be greater than the quota */
	prealloc = MIN(prealloc, quota_total(quota));
	/** Extremely large sizes can not be aligned properly */
	prealloc = MIN(prealloc, SIZE_MAX - arena->slab_size);
	/* Align prealloc around a fixed number of slabs. */
	arena->prealloc = small_align(prealloc, arena->slab_size);

	arena->used = 0;

	arena->flags = flags;

	if (arena->prealloc) {
		arena->arena = mmap_checked(arena->prealloc,
					    arena->slab_size,
					    arena->flags);
	} else {
		arena->arena = NULL;
	}
	return arena->prealloc && !arena->arena ? -1 : 0;
}
Пример #2
0
void *
slab_map(struct slab_arena *arena)
{
	void *ptr;
	if ((ptr = lf_lifo_pop(&arena->cache)))
		return ptr;

	/** Need to allocate a new slab. */
	size_t used = __sync_add_and_fetch(&arena->used, arena->slab_size);
	if (used <= arena->prealloc)
		return arena->arena + used - arena->slab_size;

	if (used > arena->maxalloc) {
		__sync_sub_and_fetch(&arena->used, arena->slab_size);
		return NULL;
	}
	return mmap_checked(arena->slab_size, arena->slab_size,
			    arena->flags);
}
Пример #3
0
int
slab_arena_create(struct slab_arena *arena,
		  size_t prealloc, size_t maxalloc,
		  uint32_t slab_size, int flags)
{
	assert(flags & (MAP_PRIVATE | MAP_SHARED));
	lf_lifo_init(&arena->cache);
	/*
	 * Round up the user supplied data - it can come in
	 * directly from the configuration file. Allow
	 * zero-size arena for testing purposes.
	 */
	arena->slab_size = small_round(MAX(slab_size, SLAB_MIN_SIZE));

	if (maxalloc) {
		arena->maxalloc = small_round(MAX(maxalloc,
						      arena->slab_size));
	} else {
		arena->maxalloc = 0;
	}

	/* Align arena around a fixed number of slabs. */
	arena->prealloc = small_align(small_round(prealloc),
				      arena->slab_size);
	if (arena->maxalloc < arena->prealloc)
		arena->prealloc = arena->maxalloc;

	arena->used = 0;

	arena->flags = flags;

	if (arena->prealloc) {
		arena->arena = mmap_checked(arena->prealloc,
					    arena->slab_size,
					    arena->flags);
	} else {
		arena->arena = NULL;
	}
	return arena->prealloc && !arena->arena ? -1 : 0;
}
Пример #4
0
void *
slab_map(struct slab_arena *arena)
{
	void *ptr;
	if ((ptr = lf_lifo_pop(&arena->cache)))
		return ptr;

	if (quota_use(arena->quota, arena->slab_size) < 0)
		return NULL;

	/** Need to allocate a new slab. */
	size_t used = __sync_add_and_fetch(&arena->used, arena->slab_size);
	if (used <= arena->prealloc)
		return arena->arena + used - arena->slab_size;

	ptr = mmap_checked(arena->slab_size, arena->slab_size,
			   arena->flags);
	if (!ptr) {
		__sync_sub_and_fetch(&arena->used, arena->slab_size);
		quota_release(arena->quota, arena->slab_size);
	}
	return ptr;
}