Skip to content
Snippets Groups Projects
Commit d28c0fef authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Add a few optimizations for the small object allocator.

parent 706776a0
No related branches found
No related tags found
No related merge requests found
......@@ -277,7 +277,7 @@ tuple_delete(struct tuple *tuple)
struct tuple_format *format = tuple_format(tuple);
char *ptr = (char *) tuple - format->field_map_size;
tuple_format_ref(format, -1);
if (tuple->version == snapshot_version)
if (!talloc.is_delayed_free_mode || tuple->version == snapshot_version)
smfree(&talloc, ptr);
else
smfree_delayed(&talloc, ptr);
......
......@@ -221,15 +221,6 @@ mempool_alloc_nothrow(struct mempool *pool)
return mslab_alloc(slab);
}
void
mempool_free(struct mempool *pool, void *obj)
{
struct mslab *slab = (struct mslab *)
slab_from_ptr(pool->cache, obj, pool->slab_order);
pool->slabs.stats.used -= pool->objsize;
mslab_free(pool, slab, obj);
}
void
mempool_stats(struct mempool *pool, struct mempool_stats *stats)
{
......
......@@ -225,12 +225,22 @@ mempool_destroy(struct mempool *pool);
void *
mempool_alloc_nothrow(struct mempool *pool);
void
mslab_free(struct mempool *pool, struct mslab *slab, void *ptr);
/**
* Free a single object.
* @pre the object is allocated in this pool.
*/
void
mempool_free(struct mempool *pool, void *ptr);
static inline void
mempool_free(struct mempool *pool, void *ptr)
{
struct mslab *slab = (struct mslab *)
slab_from_ptr(pool->cache, ptr, pool->slab_order);
pool->slabs.stats.used -= pool->objsize;
mslab_free(pool, slab, ptr);
}
/** How much memory is used by this pool. */
static inline size_t
......
......@@ -230,27 +230,10 @@ smalloc_nothrow(struct small_alloc *alloc, size_t size)
return mempool_alloc_nothrow(pool);
}
/**
* Free a small objects.
*
* This boils down to finding the object's mempool and delegating
* to mempool_free().
*
* If the pool becomes completely empty, and it's a factored pool,
* and the factored pool's cache is empty, put back the empty
* factored pool into the factored pool cache.
*/
void
smfree(struct small_alloc *alloc, void *ptr)
small_recycle_pool(struct small_alloc *alloc, struct mempool *pool)
{
struct mslab *slab = (struct mslab *)
slab_from_ptr(alloc->cache, ptr, alloc->slab_order);
struct mempool *pool = slab->pool;
mempool_free(pool, ptr);
/*
* Don't keep around empty factored pools
* if the allocator is out of them.
*/
if (mempool_used(pool) == 0 &&
pool->objsize > alloc->step_pool_objsize_max &&
alloc->factor_pool_next == NULL) {
......
......@@ -186,9 +186,34 @@ small_alloc_destroy(struct small_alloc *alloc);
void *
smalloc_nothrow(struct small_alloc *alloc, size_t size);
/** Free memory chunk allocated by the small allocator. */
void
smfree(struct small_alloc *alloc, void *ptr);
small_recycle_pool(struct small_alloc *alloc, struct mempool *pool);
/** Free memory chunk allocated by the small allocator. */
/**
* Free a small objects.
*
* This boils down to finding the object's mempool and delegating
* to mempool_free().
*
* If the pool becomes completely empty, and it's a factored pool,
* and the factored pool's cache is empty, put back the empty
* factored pool into the factored pool cache.
*/
static inline void
smfree(struct small_alloc *alloc, void *ptr)
{
struct mslab *slab = (struct mslab *)
slab_from_ptr(alloc->cache, ptr, alloc->slab_order);
struct mempool *pool = slab->pool;
mempool_free(pool, ptr);
/*
* Don't keep around empty factored pools
* if the allocator is out of them.
*/
if (mempool_used(pool) == 0)
small_recycle_pool(alloc, pool);
}
/**
* Free memory chunk allocated by the small allocator
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment