diff options
author | Evan Huus <eapache@gmail.com> | 2014-05-18 22:17:30 -0400 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2014-05-23 03:37:53 +0000 |
commit | 1f265368c4387ccd23d6534b42b7163e5ba6a982 (patch) | |
tree | a98b9445b69441e8e468c53a46b852eab9c6ce91 /epan/wmem | |
parent | 7a706d6e4d0de6a2aa57f26521188be2e5893933 (diff) |
Add jumbo-allocation support to wmem fast block
As it turns out, we do occasionally need it.
Bug:10115
Change-Id: Ifec79e4d2470bbc09f15674534d01418a6571a0d
Reviewed-on: https://code.wireshark.org/review/1688
Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan/wmem')
-rw-r--r-- | epan/wmem/wmem_allocator_block_fast.c | 61 | ||||
-rw-r--r-- | epan/wmem/wmem_test.c | 1 |
2 files changed, 57 insertions, 5 deletions
diff --git a/epan/wmem/wmem_allocator_block_fast.c b/epan/wmem/wmem_allocator_block_fast.c index b14d9caf59..6e1de7f6d7 100644 --- a/epan/wmem/wmem_allocator_block_fast.c +++ b/epan/wmem/wmem_allocator_block_fast.c @@ -66,12 +66,19 @@ typedef struct { } wmem_block_fast_chunk_t; #define WMEM_CHUNK_HEADER_SIZE WMEM_ALIGN_SIZE(sizeof(wmem_block_fast_chunk_t)) +#define JUMBO_MAGIC 0xFFFFFFFF +typedef struct _wmem_block_fast_jumbo { + struct _wmem_block_fast_jumbo *prev, *next; +} wmem_block_fast_jumbo_t; +#define WMEM_JUMBO_HEADER_SIZE WMEM_ALIGN_SIZE(sizeof(wmem_block_fast_jumbo_t)) + typedef struct { - wmem_block_fast_hdr_t *block_list; + wmem_block_fast_hdr_t *block_list; + wmem_block_fast_jumbo_t *jumbo_list; } wmem_block_fast_allocator_t; /* Creates a new block, and initializes it. */ -static void +static inline void wmem_block_fast_new_block(wmem_block_fast_allocator_t *allocator) { wmem_block_fast_hdr_t *block; @@ -94,7 +101,22 @@ wmem_block_fast_alloc(void *private_data, const size_t size) wmem_block_fast_chunk_t *chunk; gint32 real_size; - g_assert(size <= WMEM_BLOCK_MAX_ALLOC_SIZE); + if (size > WMEM_BLOCK_MAX_ALLOC_SIZE) { + wmem_block_fast_jumbo_t *block; + + /* allocate/initialize a new block of the necessary size */ + block = (wmem_block_fast_jumbo_t *)wmem_alloc(NULL, + size + WMEM_JUMBO_HEADER_SIZE + WMEM_CHUNK_HEADER_SIZE); + + block->next = allocator->jumbo_list; + block->prev = NULL; + allocator->jumbo_list = block; + + chunk = ((wmem_block_fast_chunk_t*)((guint8*)(block) + WMEM_JUMBO_HEADER_SIZE)); + chunk->len = JUMBO_MAGIC; + + return WMEM_CHUNK_TO_DATA(chunk); + } real_size = (gint32)(WMEM_ALIGN_SIZE(size) + WMEM_CHUNK_HEADER_SIZE); @@ -127,8 +149,26 @@ wmem_block_fast_realloc(void *private_data, void *ptr, const size_t size) chunk = WMEM_DATA_TO_CHUNK(ptr); - /* grow */ - if (chunk->len < size) { + if (chunk->len == JUMBO_MAGIC) { + wmem_block_fast_jumbo_t *block; + + block = ((wmem_block_fast_jumbo_t*)((guint8*)(chunk) - WMEM_JUMBO_HEADER_SIZE)); + block = (wmem_block_fast_jumbo_t*)wmem_realloc(NULL, block, + size + WMEM_JUMBO_HEADER_SIZE + WMEM_CHUNK_HEADER_SIZE); + if (block->prev) { + block->prev->next = block; + } + else { + wmem_block_fast_allocator_t *allocator = (wmem_block_fast_allocator_t*) private_data; + allocator->jumbo_list = block; + } + if (block->next) { + block->next->prev = block; + } + return ((void*)((guint8*)(block) + WMEM_JUMBO_HEADER_SIZE + WMEM_CHUNK_HEADER_SIZE)); + } + else if (chunk->len < size) { + /* grow */ void *newptr; /* need to alloc and copy; free is no-op, so don't call it */ @@ -147,6 +187,7 @@ wmem_block_fast_free_all(void *private_data) { wmem_block_fast_allocator_t *allocator = (wmem_block_fast_allocator_t*) private_data; wmem_block_fast_hdr_t *cur, *nxt; + wmem_block_fast_jumbo_t *cur_jum, *nxt_jum; /* iterate through the blocks, freeing all but the first and reinitializing * that one */ @@ -164,6 +205,15 @@ wmem_block_fast_free_all(void *private_data) wmem_free(NULL, cur); cur = nxt; } + + /* now do the jumbo blocks, freeing all of them */ + cur_jum = allocator->jumbo_list; + while (cur_jum) { + nxt_jum = cur_jum->next; + wmem_free(NULL, cur_jum); + cur_jum = nxt_jum; + } + allocator->jumbo_list = NULL; } static void @@ -203,6 +253,7 @@ wmem_block_fast_allocator_init(wmem_allocator_t *allocator) allocator->private_data = (void*) block_allocator; block_allocator->block_list = NULL; + block_allocator->jumbo_list = NULL; } /* diff --git a/epan/wmem/wmem_test.c b/epan/wmem/wmem_test.c index 16cba1c529..e141b407d7 100644 --- a/epan/wmem/wmem_test.c +++ b/epan/wmem/wmem_test.c @@ -415,6 +415,7 @@ wmem_test_allocator_block_fast(void) { wmem_test_allocator(WMEM_ALLOCATOR_BLOCK_FAST, NULL, MAX_SIMULTANEOUS_ALLOCS*4); + wmem_test_allocator_jumbo(WMEM_ALLOCATOR_BLOCK, NULL); } static void |