summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/mem-pool.c
diff options
context:
space:
mode:
authorPoornima G <pgurusid@redhat.com>2018-11-21 10:01:08 +0530
committerAmar Tumballi <amarts@redhat.com>2018-12-17 17:26:59 +0000
commit9ff080382cb8c8aab561f4131c3f631e33670338 (patch)
tree5a18a0e6715f86a87429a92e25dee400f18f97bb /libglusterfs/src/mem-pool.c
parent822779332e193471a6caa3199f0f618d2aa2c900 (diff)
mem-pool: Add api to mem_get based on requested size
Currently mem-pool implementation provides api to get from the mem pool based on the struct type. This is to retain api compatibility with the old implementation of mem pool. Internally in the mem pool structure there is a mapping from struct to size based pools. In this patch, we are adding new APIs to fetch memory from mem pool, given a size. Change-Id: Ib220ee45ebd134a7be8f6482db5a592dbb7b9211 Updates: #325 Signed-off-by: Poornima G <pgurusid@redhat.com>
Diffstat (limited to 'libglusterfs/src/mem-pool.c')
-rw-r--r--libglusterfs/src/mem-pool.c122
1 files changed, 102 insertions, 20 deletions
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index 1130c4f736f..81badc0ba0b 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -373,10 +373,6 @@ free:
FREE(ptr);
}
-#define POOL_SMALLEST 7 /* i.e. 128 */
-#define POOL_LARGEST 20 /* i.e. 1048576 */
-#define NPOOLS (POOL_LARGEST - POOL_SMALLEST + 1)
-
static pthread_key_t pool_key;
static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
static struct list_head pool_threads;
@@ -696,7 +692,7 @@ struct mem_pool *
mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
unsigned long count, char *name)
{
- unsigned int i;
+ unsigned int power;
struct mem_pool *new = NULL;
struct mem_pool_shared *pool = NULL;
@@ -706,18 +702,16 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
return NULL;
}
- for (i = 0; i < NPOOLS; ++i) {
- if (sizeof_type <= AVAILABLE_SIZE(pools[i].power_of_two)) {
- pool = &pools[i];
- break;
- }
- }
-
- if (!pool) {
+ /* We ensure sizeof_type > 1 and the next power of two will be, at least,
+ * 2^POOL_SMALLEST */
+ sizeof_type |= (1 << POOL_SMALLEST) - 1;
+ power = sizeof(sizeof_type) * 8 - __builtin_clzl(sizeof_type - 1) + 1;
+ if (power > POOL_LARGEST) {
gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
"invalid argument");
return NULL;
}
+ pool = &pools[power - POOL_SMALLEST];
new = GF_CALLOC(sizeof(struct mem_pool), 1, gf_common_mt_mem_pool);
if (!new)
@@ -729,6 +723,10 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
new->name = name;
new->pool = pool;
GF_ATOMIC_INIT(new->active, 0);
+#ifdef DEBUG
+ GF_ATOMIC_INIT(new->hit, 0);
+ GF_ATOMIC_INIT(new->miss, 0);
+#endif
INIT_LIST_HEAD(&new->owner);
LOCK(&ctx->lock);
@@ -807,7 +805,8 @@ mem_get_pool_list(void)
}
pooled_obj_hdr_t *
-mem_get_from_pool(struct mem_pool *mem_pool)
+mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool,
+ gf_boolean_t *hit)
{
per_thread_pool_list_t *pool_list;
per_thread_pool_t *pt_pool;
@@ -818,7 +817,16 @@ mem_get_from_pool(struct mem_pool *mem_pool)
return NULL;
}
- pt_pool = &pool_list->pools[mem_pool->pool->power_of_two - POOL_SMALLEST];
+ if (mem_pool) {
+ pt_pool = &pool_list
+ ->pools[mem_pool->pool->power_of_two - POOL_SMALLEST];
+ } else {
+ pt_pool = &pool_list->pools[pool->power_of_two - POOL_SMALLEST];
+ }
+
+#ifdef DEBUG
+ *hit = _gf_true;
+#endif
(void)pthread_spin_lock(&pool_list->lock);
@@ -836,15 +844,30 @@ mem_get_from_pool(struct mem_pool *mem_pool)
} else {
(void)pthread_spin_unlock(&pool_list->lock);
GF_ATOMIC_INC(pt_pool->parent->allocs_stdc);
- retval = malloc(1 << pt_pool->parent->power_of_two);
+ retval = malloc((1 << pt_pool->parent->power_of_two) +
+ sizeof(pooled_obj_hdr_t));
+#ifdef DEBUG
+ *hit = _gf_false;
+#endif
}
}
if (retval != NULL) {
+ if (mem_pool) {
+ retval->pool = mem_pool;
+ retval->power_of_two = mem_pool->pool->power_of_two;
+#ifdef DEBUG
+ if (*hit == _gf_true)
+ GF_ATOMIC_INC(mem_pool->hit);
+ else
+ GF_ATOMIC_INC(mem_pool->miss);
+#endif
+ } else {
+ retval->power_of_two = pool->power_of_two;
+ retval->pool = NULL;
+ }
retval->magic = GF_MEM_HEADER_MAGIC;
- retval->pool = mem_pool;
retval->pool_list = pool_list;
- retval->power_of_two = mem_pool->pool->power_of_two;
}
return retval;
@@ -857,6 +880,7 @@ mem_get(struct mem_pool *mem_pool)
return GF_MALLOC(mem_pool->sizeof_type, gf_common_mt_mem_pool);
#else
pooled_obj_hdr_t *retval;
+ gf_boolean_t hit;
if (!mem_pool) {
gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
@@ -864,7 +888,7 @@ mem_get(struct mem_pool *mem_pool)
return NULL;
}
- retval = mem_get_from_pool(mem_pool);
+ retval = mem_get_from_pool(mem_pool, NULL, &hit);
if (!retval) {
return NULL;
}
@@ -875,6 +899,63 @@ mem_get(struct mem_pool *mem_pool)
#endif /* GF_DISABLE_MEMPOOL */
}
+void *
+mem_pool_get(unsigned long sizeof_type, gf_boolean_t *hit)
+{
+#if defined(GF_DISABLE_MEMPOOL)
+ return GF_MALLOC(sizeof_type, gf_common_mt_mem_pool);
+#else
+ pooled_obj_hdr_t *retval;
+ unsigned int power;
+ struct mem_pool_shared *pool = NULL;
+
+ if (!sizeof_type) {
+ gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+
+ /* We ensure sizeof_type > 1 and the next power of two will be, at least,
+ * 2^POOL_SMALLEST */
+ sizeof_type |= (1 << POOL_SMALLEST) - 1;
+ power = sizeof(sizeof_type) * 8 - __builtin_clzl(sizeof_type - 1) + 1;
+ if (power > POOL_LARGEST) {
+ gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+ pool = &pools[power - POOL_SMALLEST];
+
+ retval = mem_get_from_pool(NULL, pool, hit);
+
+ return retval + 1;
+#endif /* GF_DISABLE_MEMPOOL */
+}
+
+void *
+mem_pool_get0(unsigned long sizeof_type, gf_boolean_t *hit)
+{
+ void *ptr = NULL;
+ unsigned int power;
+ struct mem_pool_shared *pool = NULL;
+
+ ptr = mem_pool_get(sizeof_type, hit);
+ if (ptr) {
+#if defined(GF_DISABLE_MEMPOOL)
+ memset(ptr, 0, sizeof_type);
+#else
+ /* We ensure sizeof_type > 1 and the next power of two will be, at
+ * least, 2^POOL_SMALLEST */
+ sizeof_type |= (1 << POOL_SMALLEST) - 1;
+ power = sizeof(sizeof_type) * 8 - __builtin_clzl(sizeof_type - 1) + 1;
+ pool = &pools[power - POOL_SMALLEST];
+ memset(ptr, 0, AVAILABLE_SIZE(pool->power_of_two));
+#endif
+ }
+
+ return ptr;
+}
+
void
mem_put(void *ptr)
{
@@ -899,7 +980,8 @@ mem_put(void *ptr)
pool_list = hdr->pool_list;
pt_pool = &pool_list->pools[hdr->power_of_two - POOL_SMALLEST];
- GF_ATOMIC_DEC(hdr->pool->active);
+ if (hdr->pool)
+ GF_ATOMIC_DEC(hdr->pool->active);
hdr->magic = GF_MEM_INVALID_MAGIC;