diff options
| -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;  | 
