summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/glusterfs/common-utils.h5
-rw-r--r--libglusterfs/src/glusterfs/glusterfs.h5
-rw-r--r--libglusterfs/src/glusterfs/mem-pool.h22
-rw-r--r--libglusterfs/src/mem-pool.c122
4 files changed, 127 insertions, 27 deletions
diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h
index 075a355f786..55d8f8cc931 100644
--- a/libglusterfs/src/glusterfs/common-utils.h
+++ b/libglusterfs/src/glusterfs/common-utils.h
@@ -151,11 +151,6 @@ trap(void);
#define GF_THREAD_NAME_PREFIX "glfs_"
#define GF_THREAD_NAME_PREFIX_LEN 5
-#include <stdbool.h>
-#define gf_boolean_t bool
-#define _gf_false false
-#define _gf_true true
-
/*
* we could have initialized these as +ve values and treated
* them as negative while comparing etc.. (which would have
diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h
index 9f14f2f5440..325241818c0 100644
--- a/libglusterfs/src/glusterfs/glusterfs.h
+++ b/libglusterfs/src/glusterfs/glusterfs.h
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -369,6 +370,10 @@ enum gf_internal_fop_indicator {
#define GF_CS_OBJECT_STATUS "trusted.glusterfs.cs.status"
#define GF_CS_OBJECT_REPAIR "trusted.glusterfs.cs.repair"
+#define gf_boolean_t bool
+#define _gf_false false
+#define _gf_true true
+
typedef enum {
GF_CS_LOCAL = 1,
GF_CS_REMOTE = 2,
diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h
index 1c7e868ab75..90905fb6ba4 100644
--- a/libglusterfs/src/glusterfs/mem-pool.h
+++ b/libglusterfs/src/glusterfs/mem-pool.h
@@ -38,6 +38,10 @@
#define GF_MEM_TRAILER_MAGIC 0xBAADF00D
#define GF_MEM_INVALID_MAGIC 0xDEADC0DE
+#define POOL_SMALLEST 7 /* i.e. 128 */
+#define POOL_LARGEST 20 /* i.e. 1048576 */
+#define NPOOLS (POOL_LARGEST - POOL_SMALLEST + 1)
+
struct mem_acct_rec {
const char *typestr;
uint64_t size;
@@ -207,7 +211,10 @@ struct mem_pool {
unsigned long count; /* requested pool size (unused) */
char *name;
gf_atomic_t active; /* current allocations */
-
+#ifdef DEBUG
+ gf_atomic_t hit; /* number of allocations served from pt_pool */
+ gf_atomic_t miss; /* number of std allocs due to miss */
+#endif
struct list_head owner; /* glusterfs_ctx_t->mempool_list */
glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */
@@ -224,7 +231,7 @@ typedef struct pooled_obj_hdr {
struct mem_pool *pool;
} pooled_obj_hdr_t;
-#define AVAILABLE_SIZE(p2) ((1 << (p2)) - sizeof(pooled_obj_hdr_t))
+#define AVAILABLE_SIZE(p2) (1 << (p2))
typedef struct per_thread_pool {
/* the pool that was used to request this allocation */
@@ -301,4 +308,15 @@ mem_pool_destroy(struct mem_pool *pool);
void
gf_mem_acct_enable_set(void *ctx);
+/* hit will be set to :
+ * _gf_true if the memory is served from mem pool
+ * _gf_false if the requested size was not present in mem pool and hence
+ * std alloc'd.
+ */
+void *
+mem_pool_get(unsigned long sizeof_type, gf_boolean_t *hit);
+
+void *
+mem_pool_get0(unsigned long sizeof_type, gf_boolean_t *hit);
+
#endif /* _MEM_POOL_H */
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;