summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/iobuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/iobuf.c')
-rw-r--r--libglusterfs/src/iobuf.c836
1 files changed, 57 insertions, 779 deletions
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index 0e37c4fc6e2..aff0a3121ff 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -12,588 +12,80 @@
#include "glusterfs/statedump.h"
#include <stdio.h>
#include "glusterfs/libglusterfs-messages.h"
-
-/*
- TODO: implement destroy margins and prefetching of arenas
-*/
-
-#define IOBUF_ARENA_MAX_INDEX \
- (sizeof(gf_iobuf_init_config) / (sizeof(struct iobuf_init_config)))
-
-/* Make sure this array is sorted based on pagesize */
-struct iobuf_init_config gf_iobuf_init_config[] = {
- /* { pagesize, num_pages }, */
- {128, 1024}, {512, 512}, {2 * 1024, 512}, {8 * 1024, 128},
- {32 * 1024, 64}, {128 * 1024, 32}, {256 * 1024, 8}, {1 * 1024 * 1024, 2},
-};
-
-static int
-gf_iobuf_get_arena_index(const size_t page_size)
-{
- int i;
-
- for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
- if (page_size <= gf_iobuf_init_config[i].pagesize)
- return i;
- }
-
- return -1;
-}
-
-static size_t
-gf_iobuf_get_pagesize(const size_t page_size)
-{
- int i;
- size_t size = 0;
-
- for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
- size = gf_iobuf_init_config[i].pagesize;
- if (page_size <= size)
- return size;
- }
-
- return -1;
-}
-
-void
-__iobuf_arena_init_iobufs(struct iobuf_arena *iobuf_arena)
-{
- int iobuf_cnt = 0;
- struct iobuf *iobuf = NULL;
- int offset = 0;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
-
- iobuf_cnt = iobuf_arena->page_count;
-
- iobuf_arena->iobufs = GF_CALLOC(sizeof(*iobuf), iobuf_cnt,
- gf_common_mt_iobuf);
- if (!iobuf_arena->iobufs)
- return;
-
- iobuf = iobuf_arena->iobufs;
- for (i = 0; i < iobuf_cnt; i++) {
- INIT_LIST_HEAD(&iobuf->list);
- LOCK_INIT(&iobuf->lock);
-
- iobuf->iobuf_arena = iobuf_arena;
-
- iobuf->ptr = iobuf_arena->mem_base + offset;
-
- list_add(&iobuf->list, &iobuf_arena->passive.list);
- iobuf_arena->passive_cnt++;
-
- offset += iobuf_arena->page_size;
- iobuf++;
- }
-
-out:
- return;
-}
-
-void
-__iobuf_arena_destroy_iobufs(struct iobuf_arena *iobuf_arena)
-{
- int iobuf_cnt = 0;
- struct iobuf *iobuf = NULL;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
-
- iobuf_cnt = iobuf_arena->page_count;
-
- if (!iobuf_arena->iobufs) {
- gf_msg_callingfn(THIS->name, GF_LOG_ERROR, 0, LG_MSG_IOBUFS_NOT_FOUND,
- "iobufs not found");
- return;
- }
-
- iobuf = iobuf_arena->iobufs;
- for (i = 0; i < iobuf_cnt; i++) {
- GF_ASSERT(GF_ATOMIC_GET(iobuf->ref) == 0);
-
- LOCK_DESTROY(&iobuf->lock);
- list_del_init(&iobuf->list);
- iobuf++;
- }
-
- GF_FREE(iobuf_arena->iobufs);
-
-out:
- return;
-}
-
-void
-__iobuf_arena_destroy(struct iobuf_pool *iobuf_pool,
- struct iobuf_arena *iobuf_arena)
-{
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
-
- if (iobuf_pool->rdma_deregistration)
- iobuf_pool->rdma_deregistration(iobuf_pool->mr_list, iobuf_arena);
-
- __iobuf_arena_destroy_iobufs(iobuf_arena);
-
- if (iobuf_arena->mem_base && iobuf_arena->mem_base != MAP_FAILED)
- munmap(iobuf_arena->mem_base, iobuf_arena->arena_size);
-
- GF_FREE(iobuf_arena);
-out:
- return;
-}
-
-struct iobuf_arena *
-__iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_size,
- int32_t num_iobufs)
-{
- struct iobuf_arena *iobuf_arena = NULL;
- size_t rounded_size = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
-
- 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->all_list);
- INIT_LIST_HEAD(&iobuf_arena->active.list);
- INIT_LIST_HEAD(&iobuf_arena->passive.list);
- iobuf_arena->iobuf_pool = iobuf_pool;
-
- rounded_size = gf_iobuf_get_pagesize(page_size);
-
- iobuf_arena->page_size = rounded_size;
- iobuf_arena->page_count = num_iobufs;
-
- iobuf_arena->arena_size = rounded_size * num_iobufs;
-
- iobuf_arena->mem_base = mmap(NULL, iobuf_arena->arena_size,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (iobuf_arena->mem_base == MAP_FAILED) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_MAPPING_FAILED,
- "mapping failed");
- goto err;
- }
-
- if (iobuf_pool->rdma_registration) {
- iobuf_pool->rdma_registration(iobuf_pool->device, iobuf_arena);
- }
-
- list_add_tail(&iobuf_arena->all_list, &iobuf_pool->all_arenas);
-
- __iobuf_arena_init_iobufs(iobuf_arena);
- if (!iobuf_arena->iobufs) {
- gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_IOBUF_FAILED,
- "init failed");
- goto err;
- }
-
- iobuf_pool->arena_cnt++;
-
- return iobuf_arena;
-
-err:
- __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
-
-out:
- return NULL;
-}
-
-static struct iobuf_arena *
-__iobuf_arena_unprune(struct iobuf_pool *iobuf_pool, const size_t page_size,
- const int index)
-{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
-
- list_for_each_entry(tmp, &iobuf_pool->purge[index], list)
- {
- list_del_init(&tmp->list);
- iobuf_arena = tmp;
- break;
- }
-out:
- return iobuf_arena;
-}
-
-static struct iobuf_arena *
-__iobuf_pool_add_arena(struct iobuf_pool *iobuf_pool, const size_t page_size,
- const int32_t num_pages, const int index)
-{
- struct iobuf_arena *iobuf_arena = NULL;
-
- iobuf_arena = __iobuf_arena_unprune(iobuf_pool, page_size, index);
-
- if (!iobuf_arena) {
- iobuf_arena = __iobuf_arena_alloc(iobuf_pool, page_size, num_pages);
- if (!iobuf_arena) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
- "arena not found");
- return NULL;
- }
- }
- list_add(&iobuf_arena->list, &iobuf_pool->arenas[index]);
-
- return iobuf_arena;
-}
-
-/* This function destroys all the iobufs and the iobuf_pool */
-void
-iobuf_pool_destroy(struct iobuf_pool *iobuf_pool)
-{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
-
- pthread_mutex_lock(&iobuf_pool->mutex);
- {
- for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
- list_for_each_entry_safe(iobuf_arena, tmp, &iobuf_pool->arenas[i],
- list)
- {
- list_del_init(&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
-
- __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
- }
- list_for_each_entry_safe(iobuf_arena, tmp, &iobuf_pool->purge[i],
- list)
- {
- list_del_init(&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
- __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
- }
- /* If there are no iobuf leaks, there should be no
- * arenas in the filled list. If at all there are any
- * arenas in the filled list, the below function will
- * assert.
- */
- list_for_each_entry_safe(iobuf_arena, tmp, &iobuf_pool->filled[i],
- list)
- {
- list_del_init(&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
- __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
- }
- /* If there are no iobuf leaks, there shoould be
- * no standard allocated arenas, iobuf_put will free
- * such arenas.
- * TODO: Free the stdalloc arenas forcefully if present?
- */
- }
- }
- pthread_mutex_unlock(&iobuf_pool->mutex);
-
- pthread_mutex_destroy(&iobuf_pool->mutex);
-
- GF_FREE(iobuf_pool);
-
-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;
-}
+#include "glusterfs/atomic.h"
struct iobuf_pool *
iobuf_pool_new(void)
{
struct iobuf_pool *iobuf_pool = NULL;
- int i = 0;
- size_t page_size = 0;
- size_t arena_size = 0;
- int32_t num_pages = 0;
- int index;
iobuf_pool = GF_CALLOC(sizeof(*iobuf_pool), 1, gf_common_mt_iobuf_pool);
if (!iobuf_pool)
goto out;
- INIT_LIST_HEAD(&iobuf_pool->all_arenas);
- pthread_mutex_init(&iobuf_pool->mutex, NULL);
- 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]);
- }
-
- iobuf_pool->default_page_size = 128 * GF_UNIT_KB;
-
- iobuf_pool->rdma_registration = NULL;
- iobuf_pool->rdma_deregistration = NULL;
-
- for (i = 0; i < GF_RDMA_DEVICE_COUNT; i++) {
- iobuf_pool->device[i] = NULL;
- iobuf_pool->mr_list[i] = NULL;
- }
-
- pthread_mutex_lock(&iobuf_pool->mutex);
- {
- for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
- page_size = gf_iobuf_init_config[i].pagesize;
- num_pages = gf_iobuf_init_config[i].num_pages;
-
- index = gf_iobuf_get_arena_index(page_size);
- if (index == -1) {
- pthread_mutex_unlock(&iobuf_pool->mutex);
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available",
- page_size);
- return NULL;
- }
-
- __iobuf_pool_add_arena(iobuf_pool, page_size, num_pages, index);
-
- arena_size += page_size * num_pages;
- }
- }
- pthread_mutex_unlock(&iobuf_pool->mutex);
- /* Need an arena to handle all the bigger iobuf requests */
- iobuf_create_stdalloc_arena(iobuf_pool);
+ GF_ATOMIC_INIT(iobuf_pool->mem_pool_hit, 0);
+ GF_ATOMIC_INIT(iobuf_pool->mem_pool_miss, 0);
+ GF_ATOMIC_INIT(iobuf_pool->active_cnt, 0);
- iobuf_pool->arena_size = arena_size;
out:
-
return iobuf_pool;
}
-static void
-__iobuf_arena_prune(struct iobuf_pool *iobuf_pool,
- struct iobuf_arena *iobuf_arena, const int index)
-{
- /* code flow comes here only if the arena is in purge list and we can
- * free the arena only if we have at least one arena in 'arenas' list
- * (ie, at least few iobufs free in arena), that way, there won't
- * be spurious mmap/unmap of buffers
- */
- if (list_empty(&iobuf_pool->arenas[index]))
- goto out;
-
- /* All cases matched, destroy */
- list_del_init(&iobuf_arena->list);
- list_del_init(&iobuf_arena->all_list);
- iobuf_pool->arena_cnt--;
-
- __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
-
-out:
- return;
-}
-
void
-iobuf_pool_prune(struct iobuf_pool *iobuf_pool)
+iobuf_pool_destroy(struct iobuf_pool *iobuf_pool)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
+ if (!iobuf_pool)
+ return;
- pthread_mutex_lock(&iobuf_pool->mutex);
- {
- for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
- if (list_empty(&iobuf_pool->arenas[i])) {
- continue;
- }
-
- list_for_each_entry_safe(iobuf_arena, tmp, &iobuf_pool->purge[i],
- list)
- {
- __iobuf_arena_prune(iobuf_pool, iobuf_arena, i);
- }
- }
- }
- pthread_mutex_unlock(&iobuf_pool->mutex);
+ if (GF_ATOMIC_GET(iobuf_pool->active_cnt) != 0)
+ gf_msg_callingfn(THIS->name, GF_LOG_ERROR, 0, LG_MSG_IOBUFS_NOT_FOUND,
+ "iobuf_pool_destroy called, but there"
+ " are unfreed active iobufs:%" PRId64,
+ GF_ATOMIC_GET(iobuf_pool->active_cnt));
-out:
+ GF_FREE(iobuf_pool);
return;
}
-/* Always called under the iobuf_pool mutex lock */
-static struct iobuf_arena *
-__iobuf_select_arena(struct iobuf_pool *iobuf_pool, const size_t page_size,
- const int index)
-{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *trav = NULL;
-
- /* look for unused iobuf from the head-most arena */
- list_for_each_entry(trav, &iobuf_pool->arenas[index], list)
- {
- if (trav->passive_cnt) {
- iobuf_arena = trav;
- break;
- }
- }
-
- if (!iobuf_arena) {
- /* all arenas were full, find the right count to add */
- iobuf_arena = __iobuf_pool_add_arena(
- iobuf_pool, page_size, gf_iobuf_init_config[index].num_pages,
- index);
- }
-
- return iobuf_arena;
-}
-
-/* Always called under the iobuf_pool mutex lock */
-static struct iobuf *
-__iobuf_get(struct iobuf_pool *iobuf_pool, const size_t page_size,
- const int index)
-{
- struct iobuf *iobuf = NULL;
- struct iobuf_arena *iobuf_arena = NULL;
-
- /* most eligible arena for picking an iobuf */
- iobuf_arena = __iobuf_select_arena(iobuf_pool, page_size, index);
- if (!iobuf_arena)
- return NULL;
-
- list_for_each_entry(iobuf, &iobuf_arena->passive.list, list) break;
-
- list_del(&iobuf->list);
- iobuf_arena->passive_cnt--;
-
- list_add(&iobuf->list, &iobuf_arena->active.list);
- iobuf_arena->active_cnt++;
-
- /* no resetting requied for this element */
- iobuf_arena->alloc_cnt++;
-
- if (iobuf_arena->max_active < iobuf_arena->active_cnt)
- iobuf_arena->max_active = iobuf_arena->active_cnt;
-
- if (iobuf_arena->passive_cnt == 0) {
- list_del(&iobuf_arena->list);
- list_add(&iobuf_arena->list, &iobuf_pool->filled[index]);
- }
-
- return iobuf;
-}
-
struct iobuf *
-iobuf_get_from_stdalloc(struct iobuf_pool *iobuf_pool, size_t page_size)
+iobuf_get2(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;
+ gf_boolean_t hit = _gf_false;
- /* 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;
+ if (page_size == 0) {
+ page_size = GF_IOBUF_DEFAULT_PAGE_SIZE;
}
- iobuf = GF_CALLOC(1, sizeof(*iobuf), gf_common_mt_iobuf);
+ iobuf = mem_pool_get0(sizeof(struct iobuf), &hit);
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)
+ iobuf->free_ptr = mem_pool_get(page_size, &hit);
+ if (!iobuf->free_ptr) {
+ iobuf->free_ptr = GF_MALLOC(page_size, gf_common_mt_char);
+ iobuf->stdalloc = _gf_true;
+ }
+ if (!iobuf->free_ptr) {
+ mem_put(iobuf);
+ iobuf = NULL;
goto out;
+ }
+ if (hit == _gf_true)
+ GF_ATOMIC_INC(iobuf_pool->mem_pool_hit);
+ else
+ GF_ATOMIC_INC(iobuf_pool->mem_pool_miss);
- iobuf->ptr = GF_ALIGN_BUF(iobuf->free_ptr, GF_IOBUF_ALIGN_SIZE);
- iobuf->iobuf_arena = iobuf_arena;
+ iobuf->ptr = iobuf->free_ptr;
LOCK_INIT(&iobuf->lock);
- /* Hold a ref because you are allocating and using it */
- GF_ATOMIC_INIT(iobuf->ref, 1);
+ iobuf->page_size = page_size;
+ iobuf->iobuf_pool = iobuf_pool;
- ret = 0;
+ /* Hold a ref because you are allocating and using it */
+ iobuf_ref(iobuf);
+ GF_ATOMIC_INC(iobuf_pool->active_cnt);
out:
- if (ret && iobuf) {
- 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;
- size_t rounded_size = 0;
- int index = 0;
-
- if (page_size == 0) {
- page_size = iobuf_pool->default_page_size;
- }
-
- rounded_size = gf_iobuf_get_pagesize(page_size);
- if (rounded_size == -1) {
- /* make sure to provide the requested buffer with standard
- memory allocations */
- iobuf = iobuf_get_from_stdalloc(iobuf_pool, page_size);
-
- gf_msg_debug("iobuf", 0,
- "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 iobuf;
- }
-
- index = gf_iobuf_get_arena_index(page_size);
- if (index == -1) {
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available",
- page_size);
- return NULL;
- }
-
- pthread_mutex_lock(&iobuf_pool->mutex);
- {
- iobuf = __iobuf_get(iobuf_pool, rounded_size, index);
- if (!iobuf) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND,
- "iobuf not found");
- goto unlock;
- }
-
- iobuf_ref(iobuf);
- }
-unlock:
- pthread_mutex_unlock(&iobuf_pool->mutex);
-
return iobuf;
}
@@ -607,23 +99,13 @@ iobuf_get_page_aligned(struct iobuf_pool *iobuf_pool, size_t page_size,
req_size = page_size;
if (req_size == 0) {
- req_size = iobuf_pool->default_page_size;
+ req_size = GF_IOBUF_DEFAULT_PAGE_SIZE;
}
iobuf = iobuf_get2(iobuf_pool, req_size + align_size);
if (!iobuf)
return NULL;
- /* If std allocation was used, then free_ptr will be non-NULL. In this
- * case, we do not want to modify the original free_ptr.
- * On the other hand, if the buf was gotten through the available
- * arenas, then we use iobuf->free_ptr to store the original
- * pointer to the offset into the mmap'd block of memory and in turn
- * reuse iobuf->ptr to hold the page-aligned address. And finally, in
- * iobuf_put(), we copy iobuf->free_ptr into iobuf->ptr - back to where
- * it was originally when __iobuf_get() returned this iobuf.
- */
- if (!iobuf->free_ptr)
- iobuf->free_ptr = iobuf->ptr;
+
iobuf->ptr = GF_ALIGN_BUF(iobuf->ptr, align_size);
return iobuf;
@@ -632,118 +114,22 @@ iobuf_get_page_aligned(struct iobuf_pool *iobuf_pool, size_t page_size,
struct iobuf *
iobuf_get(struct iobuf_pool *iobuf_pool)
{
- struct iobuf *iobuf = NULL;
- int index = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
-
- index = gf_iobuf_get_arena_index(iobuf_pool->default_page_size);
- if (index == -1) {
- gf_msg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available",
- iobuf_pool->default_page_size);
- return NULL;
- }
-
- pthread_mutex_lock(&iobuf_pool->mutex);
- {
- iobuf = __iobuf_get(iobuf_pool, iobuf_pool->default_page_size, index);
- if (!iobuf) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND,
- "iobuf not found");
- goto unlock;
- }
-
- iobuf_ref(iobuf);
- }
-unlock:
- pthread_mutex_unlock(&iobuf_pool->mutex);
-
-out:
- return iobuf;
-}
-
-void
-__iobuf_put(struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
-{
- struct iobuf_pool *iobuf_pool = NULL;
- int index = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
- GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
-
- iobuf_pool = iobuf_arena->iobuf_pool;
-
- index = gf_iobuf_get_arena_index(iobuf_arena->page_size);
- if (index == -1) {
- gf_msg_debug("iobuf", 0,
- "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;
- }
-
- if (iobuf_arena->passive_cnt == 0) {
- list_del(&iobuf_arena->list);
- list_add_tail(&iobuf_arena->list, &iobuf_pool->arenas[index]);
- }
-
- list_del_init(&iobuf->list);
- iobuf_arena->active_cnt--;
-
- if (iobuf->free_ptr) {
- iobuf->ptr = iobuf->free_ptr;
- iobuf->free_ptr = NULL;
- }
-
- list_add(&iobuf->list, &iobuf_arena->passive.list);
- iobuf_arena->passive_cnt++;
-
- if (iobuf_arena->active_cnt == 0) {
- list_del(&iobuf_arena->list);
- list_add_tail(&iobuf_arena->list, &iobuf_pool->purge[index]);
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- __iobuf_arena_prune(iobuf_pool, iobuf_arena, index);
- }
-out:
- return;
+ return iobuf_get2(iobuf_pool, GF_IOBUF_DEFAULT_PAGE_SIZE);
}
void
iobuf_put(struct iobuf *iobuf)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_pool *iobuf_pool = NULL;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
+ LOCK_DESTROY(&iobuf->lock);
- iobuf_arena = iobuf->iobuf_arena;
- if (!iobuf_arena) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
- "arena not found");
- return;
- }
-
- iobuf_pool = iobuf_arena->iobuf_pool;
- if (!iobuf_pool) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND,
- "iobuf pool not found");
- return;
- }
+ if (iobuf->stdalloc)
+ GF_FREE(iobuf->free_ptr);
+ else
+ mem_put(iobuf->free_ptr);
- pthread_mutex_lock(&iobuf_pool->mutex);
- {
- __iobuf_put(iobuf, iobuf_arena);
- }
- pthread_mutex_unlock(&iobuf_pool->mutex);
+ GF_ATOMIC_DEC(iobuf->iobuf_pool->active_cnt);
+ mem_put(iobuf);
-out:
return;
}
@@ -967,25 +353,10 @@ out:
size_t
iobuf_size(struct iobuf *iobuf)
{
- size_t size = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
-
- if (!iobuf->iobuf_arena) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
- "arena not found");
- goto out;
- }
-
- if (!iobuf->iobuf_arena->iobuf_pool) {
- gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND,
- "pool not found");
- goto out;
- }
+ if (!iobuf)
+ return 0;
- size = iobuf->iobuf_arena->page_size;
-out:
- return size;
+ return iobuf->page_size;
}
size_t
@@ -1010,113 +381,20 @@ out:
}
void
-iobuf_info_dump(struct iobuf *iobuf, const char *key_prefix)
-{
- char key[GF_DUMP_MAX_BUF_LEN];
- struct iobuf my_iobuf;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
-
- ret = TRY_LOCK(&iobuf->lock);
- if (ret) {
- return;
- }
- memcpy(&my_iobuf, iobuf, sizeof(my_iobuf));
- UNLOCK(&iobuf->lock);
-
- gf_proc_dump_build_key(key, key_prefix, "ref");
- gf_proc_dump_write(key, "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(my_iobuf.ref));
- gf_proc_dump_build_key(key, key_prefix, "ptr");
- gf_proc_dump_write(key, "%p", my_iobuf.ptr);
-
-out:
- return;
-}
-
-void
-iobuf_arena_info_dump(struct iobuf_arena *iobuf_arena, const char *key_prefix)
-{
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
- struct iobuf *trav;
-
- GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
-
- gf_proc_dump_build_key(key, key_prefix, "mem_base");
- gf_proc_dump_write(key, "%p", iobuf_arena->mem_base);
- gf_proc_dump_build_key(key, key_prefix, "active_cnt");
- gf_proc_dump_write(key, "%d", iobuf_arena->active_cnt);
- gf_proc_dump_build_key(key, key_prefix, "passive_cnt");
- gf_proc_dump_write(key, "%d", iobuf_arena->passive_cnt);
- gf_proc_dump_build_key(key, key_prefix, "alloc_cnt");
- gf_proc_dump_write(key, "%" PRIu64, iobuf_arena->alloc_cnt);
- gf_proc_dump_build_key(key, key_prefix, "max_active");
- gf_proc_dump_write(key, "%d", iobuf_arena->max_active);
- gf_proc_dump_build_key(key, key_prefix, "page_size");
- gf_proc_dump_write(key, "%" GF_PRI_SIZET, iobuf_arena->page_size);
- list_for_each_entry(trav, &iobuf_arena->active.list, list)
- {
- gf_proc_dump_build_key(key, key_prefix, "active_iobuf.%d", i++);
- gf_proc_dump_add_section("%s", key);
- iobuf_info_dump(trav, key);
- }
-
-out:
- return;
-}
-
-void
iobuf_stats_dump(struct iobuf_pool *iobuf_pool)
{
- char msg[1024];
- struct iobuf_arena *trav = NULL;
- int i = 1;
- int j = 0;
- int ret = -1;
-
GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- ret = pthread_mutex_trylock(&iobuf_pool->mutex);
-
- if (ret) {
- return;
- }
gf_proc_dump_add_section("iobuf.global");
gf_proc_dump_write("iobuf_pool", "%p", iobuf_pool);
- gf_proc_dump_write("iobuf_pool.default_page_size", "%" GF_PRI_SIZET,
- iobuf_pool->default_page_size);
- gf_proc_dump_write("iobuf_pool.arena_size", "%" GF_PRI_SIZET,
- iobuf_pool->arena_size);
- gf_proc_dump_write("iobuf_pool.arena_cnt", "%d", iobuf_pool->arena_cnt);
+ gf_proc_dump_write("iobuf_pool.default_page_size", "%llu",
+ GF_IOBUF_DEFAULT_PAGE_SIZE);
+ gf_proc_dump_write("iobuf_pool.request_hits", "%" PRId64,
+ GF_ATOMIC_GET(iobuf_pool->mem_pool_hit));
gf_proc_dump_write("iobuf_pool.request_misses", "%" PRId64,
- iobuf_pool->request_misses);
-
- for (j = 0; j < IOBUF_ARENA_MAX_INDEX; j++) {
- list_for_each_entry(trav, &iobuf_pool->arenas[j], list)
- {
- snprintf(msg, sizeof(msg), "arena.%d", i);
- gf_proc_dump_add_section("%s", msg);
- iobuf_arena_info_dump(trav, msg);
- i++;
- }
- list_for_each_entry(trav, &iobuf_pool->purge[j], list)
- {
- snprintf(msg, sizeof(msg), "purge.%d", i);
- gf_proc_dump_add_section("%s", msg);
- iobuf_arena_info_dump(trav, msg);
- i++;
- }
- list_for_each_entry(trav, &iobuf_pool->filled[j], list)
- {
- snprintf(msg, sizeof(msg), "filled.%d", i);
- gf_proc_dump_add_section("%s", msg);
- iobuf_arena_info_dump(trav, msg);
- i++;
- }
- }
-
- pthread_mutex_unlock(&iobuf_pool->mutex);
+ GF_ATOMIC_GET(iobuf_pool->mem_pool_miss));
+ gf_proc_dump_write("iobuf_pool.active_cnt", "%" PRId64,
+ GF_ATOMIC_GET(iobuf_pool->active_cnt));
out:
return;