diff options
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/glusterfs/common-utils.h | 5 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/glusterfs.h | 5 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs/mem-pool.h | 22 | ||||
-rw-r--r-- | libglusterfs/src/mem-pool.c | 122 |
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; |