diff options
Diffstat (limited to 'libglusterfs/src')
| -rw-r--r-- | libglusterfs/src/iobuf.c | 99 | ||||
| -rw-r--r-- | libglusterfs/src/iobuf.h | 8 | 
2 files changed, 99 insertions, 8 deletions
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index e1cf334ba01..c2d74fd7ef3 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -317,6 +317,31 @@ out:          return;  } +static void +iobuf_create_stdalloc_arena (struct iobuf_pool *iobuf_pool) +{ +        struct iobuf_arena *iobuf_arena = NULL; + +        /* No locking required here as its called only once during init */ +        iobuf_arena = GF_CALLOC (sizeof (*iobuf_arena), 1, +                                 gf_common_mt_iobuf_arena); +        if (!iobuf_arena) +                goto err; + +        INIT_LIST_HEAD (&iobuf_arena->list); +        INIT_LIST_HEAD (&iobuf_arena->active.list); +        INIT_LIST_HEAD (&iobuf_arena->passive.list); + +        iobuf_arena->iobuf_pool = iobuf_pool; + +        iobuf_arena->page_size = 0x7fffffff; + +        list_add_tail (&iobuf_arena->list, +                       &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX]); + +err: +        return; +}  struct iobuf_pool *  iobuf_pool_new (void) @@ -333,7 +358,7 @@ iobuf_pool_new (void)                  goto out;          pthread_mutex_init (&iobuf_pool->mutex, NULL); -        for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) { +        for (i = 0; i <= IOBUF_ARENA_MAX_INDEX; i++) {                  INIT_LIST_HEAD (&iobuf_pool->arenas[i]);                  INIT_LIST_HEAD (&iobuf_pool->filled[i]);                  INIT_LIST_HEAD (&iobuf_pool->purge[i]); @@ -351,6 +376,9 @@ iobuf_pool_new (void)                  arena_size += page_size * num_pages;          } +        /* Need an arena to handle all the bigger iobuf requests */ +        iobuf_create_stdalloc_arena (iobuf_pool); +          iobuf_pool->arena_size = arena_size;  out: @@ -509,6 +537,51 @@ out:  }  struct iobuf * +iobuf_get_from_stdalloc (struct iobuf_pool *iobuf_pool, size_t page_size) +{ +        struct iobuf       *iobuf       = NULL; +        struct iobuf_arena *iobuf_arena = NULL; +        struct iobuf_arena *trav        = NULL; +        int                 ret         = -1; + +        /* The first arena in the 'MAX-INDEX' will always be used for misc */ +        list_for_each_entry (trav, &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX], +                             list) { +                iobuf_arena = trav; +                break; +        } + +        iobuf = GF_CALLOC (1, sizeof (*iobuf), gf_common_mt_iobuf); +        if (!iobuf) +                goto out; + +        /* 4096 is the alignment */ +        iobuf->free_ptr = GF_CALLOC (1, ((page_size + GF_IOBUF_ALIGN_SIZE) - 1), +                                     gf_common_mt_char); +        if (!iobuf->free_ptr) +                goto out; + +        iobuf->ptr = GF_ALIGN_BUF (iobuf->free_ptr, GF_IOBUF_ALIGN_SIZE); +        iobuf->iobuf_arena = iobuf_arena; +        LOCK_INIT (&iobuf->lock); + +        /* Hold a ref because you are allocating and using it */ +        iobuf->ref = 1; + +        ret = 0; +out: +        if (ret && iobuf) { +                if (iobuf->free_ptr) +                        GF_FREE (iobuf->free_ptr); +                GF_FREE (iobuf); +                iobuf = NULL; +        } + +        return iobuf; +} + + +struct iobuf *  iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size)  {          struct iobuf       *iobuf        = NULL; @@ -521,11 +594,17 @@ iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size)          rounded_size = gf_iobuf_get_pagesize (page_size);          if (rounded_size == -1) { -                gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of " -                        "iobufs in arena being requested is greater than max " -                        "available", page_size); +                /* make sure to provide the requested buffer with standard +                   memory allocations */ +                iobuf = iobuf_get_from_stdalloc (iobuf_pool, page_size); + +                gf_log ("iobuf", GF_LOG_DEBUG, "request for iobuf of size %zu " +                        "is serviced using standard calloc() (%p) as it " +                        "exceeds the maximum available buffer size", +                        page_size, iobuf); +                  iobuf_pool->request_misses++; -                return NULL; +                return iobuf;          }          pthread_mutex_lock (&iobuf_pool->mutex); @@ -594,9 +673,13 @@ __iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)          index = gf_iobuf_get_arena_index (iobuf_arena->page_size);          if (index == -1) { -                gf_log ("iobuf", GF_LOG_ERROR, "page_size (%zu) of " -                        "iobufs in arena being added is greater than max " -                        "available", iobuf_arena->page_size); +                gf_log ("iobuf", GF_LOG_DEBUG, "freeing the iobuf (%p) " +                        "allocated with standard calloc()", iobuf); + +                /* free up properly without bothering about lists and all */ +                LOCK_DESTROY (&iobuf->lock); +                GF_FREE (iobuf->free_ptr); +                GF_FREE (iobuf);                  return;          } diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h index 46a54dbfc95..c9792ae8a7c 100644 --- a/libglusterfs/src/iobuf.h +++ b/libglusterfs/src/iobuf.h @@ -40,6 +40,11 @@  #define MAP_ANONYMOUS MAP_ANON  #endif +#define GF_ALIGN_BUF(ptr,bound) ((void *)((unsigned long)(ptr + bound - 1) & \ +                                          (unsigned long)(~(bound - 1)))) + +#define GF_IOBUF_ALIGN_SIZE 512 +  /* one allocatable unit for the consumers of the IOBUF API */  /* each unit hosts @page_size bytes of memory */  struct iobuf; @@ -71,6 +76,9 @@ struct iobuf {          int                  ref;  /* 0 == passive, >0 == active */          void                *ptr;  /* usable memory region by the consumer */ + +        void                *free_ptr; /* in case of stdalloc, this is the +                                          one to be freed */  };  | 
