aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wmem
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2014-05-18 22:17:30 -0400
committerEvan Huus <eapache@gmail.com>2014-05-23 03:37:53 +0000
commit1f265368c4387ccd23d6534b42b7163e5ba6a982 (patch)
treea98b9445b69441e8e468c53a46b852eab9c6ce91 /epan/wmem
parent7a706d6e4d0de6a2aa57f26521188be2e5893933 (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.c61
-rw-r--r--epan/wmem/wmem_test.c1
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