/** Initialize the small allocator. */ void small_alloc_create(struct small_alloc *alloc, struct slab_cache *cache, uint32_t objsize_min, float alloc_factor) { alloc->cache = cache; /* Align sizes. */ objsize_min = small_align(objsize_min, sizeof(intptr_t)); alloc->slab_order = cache->order_max; /* Make sure at least 4 largest objects can fit in a slab. */ alloc->objsize_max = mempool_objsize_max(slab_order_size(cache, alloc->slab_order)); assert(alloc->objsize_max > objsize_min + STEP_POOL_MAX * STEP_SIZE); struct mempool *step_pool; for (step_pool = alloc->step_pools; step_pool < alloc->step_pools + STEP_POOL_MAX; step_pool++) { mempool_create_with_order(step_pool, alloc->cache, objsize_min, alloc->slab_order); objsize_min += STEP_SIZE; } alloc->step_pool_objsize_max = (step_pool - 1)->objsize; if (alloc_factor > 2.0) alloc_factor = 2.0; /* * Correct the user-supplied alloc_factor to ensure that * it actually produces growing object sizes. */ if (alloc->step_pool_objsize_max * alloc_factor < alloc->step_pool_objsize_max + STEP_SIZE) { alloc_factor = (alloc->step_pool_objsize_max + STEP_SIZE + 0.5)/ alloc->step_pool_objsize_max; } alloc->factor = alloc_factor; /* Initialize the factored pool cache. */ struct factor_pool *factor_pool = alloc->factor_pool_cache; do { factor_pool->next = factor_pool + 1; factor_pool++; } while (factor_pool != alloc->factor_pool_cache + FACTOR_POOL_MAX - 1); factor_pool->next = NULL; alloc->factor_pool_next = alloc->factor_pool_cache; factor_tree_new(&alloc->factor_pools); (void) factor_pool_create(alloc, NULL, alloc->objsize_max); alloc->is_delayed_free_mode = false; }
void mempool_create_with_order(struct mempool *pool, struct slab_cache *cache, uint32_t objsize, uint8_t order) { assert(order <= cache->order_max); lifo_init(&pool->link); lifo_init(&pool->delayed); pool->cache = cache; slab_list_create(&pool->slabs); mslab_tree_new(&pool->free_slabs); pool->spare = NULL; pool->objsize = objsize; pool->slab_order = order; /* Total size of slab */ uint32_t slab_size = slab_order_size(pool->cache, pool->slab_order); /* Calculate how many objects will actually fit in a slab. */ pool->objcount = (slab_size - mslab_sizeof()) / objsize; assert(pool->objcount); pool->objoffset = slab_size - pool->objcount * pool->objsize; }
void mempool_stats(struct mempool *pool, struct mempool_stats *stats) { /* Object size. */ stats->objsize = pool->objsize; /* Number of objects. */ stats->objcount = pool->slabs.stats.used/pool->objsize; /* Size of the slab. */ stats->slabsize = slab_order_size(pool->cache, pool->slab_order); /* The number of slabs. */ stats->slabcount = pool->slabs.stats.total/stats->slabsize; /* How much memory is used for slabs. */ stats->totals.used = pool->slabs.stats.used; /* * How much memory is available. Subtract the slab size, * which is allocation overhead and is not available * memory. */ stats->totals.total = pool->slabs.stats.total - mslab_sizeof() * stats->slabcount; }