forked from osmocom/wireshark
More block allocator fixes and cleanup. Most of the issues seem to have been
from one case I consistently forgot when typing it up originally, even though it's clearly listed several places in my design notes. Also include an #if0-ed out block of code to redirect emem to wmem for easy testing (since there are very few common dissectors that use wmem right now). svn path=/trunk/; revision=48434
This commit is contained in:
parent
a6d37fe9f3
commit
b7b30a7cdf
18
epan/emem.c
18
epan/emem.c
|
@ -43,6 +43,7 @@
|
|||
|
||||
#include "proto.h"
|
||||
#include "emem.h"
|
||||
#include "wmem/wmem.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> /* VirtualAlloc, VirtualProtect */
|
||||
|
@ -841,7 +842,22 @@ emem_alloc_glib(size_t size, emem_pool_t *mem)
|
|||
static void *
|
||||
emem_alloc(size_t size, emem_pool_t *mem)
|
||||
{
|
||||
void *buf = mem->memory_alloc(size, mem);
|
||||
void *buf;
|
||||
|
||||
#if 0
|
||||
/* For testing wmem, effectively redirects most emem memory to wmem.
|
||||
* You will also have to comment out several assertions in
|
||||
* wmem_packet_scope() and wmem_file_scope() since they are much
|
||||
* stricter about when they are permitted to be called. */
|
||||
if (mem == &ep_packet_mem) {
|
||||
return wmem_alloc(wmem_packet_scope(), size);
|
||||
}
|
||||
else if (mem == &se_packet_mem) {
|
||||
return wmem_alloc(wmem_file_scope(), size);
|
||||
}
|
||||
#endif
|
||||
|
||||
buf = mem->memory_alloc(size, mem);
|
||||
|
||||
/* XXX - this is a waste of time if the allocator function is going to
|
||||
* memset this straight back to 0.
|
||||
|
|
|
@ -251,19 +251,25 @@ wmem_block_remove_from_free_list(wmem_block_allocator_t *allocator,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Update our predecessor's 'next' pointer */
|
||||
if (freeChunk->prev) {
|
||||
g_assert(WMEM_GET_FREE(freeChunk->prev)->in_free_list);
|
||||
g_assert(WMEM_GET_FREE(freeChunk->prev)->next == chunk);
|
||||
WMEM_GET_FREE(freeChunk->prev)->next = freeChunk->next;
|
||||
}
|
||||
else {
|
||||
g_assert(allocator->free_list_head == chunk);
|
||||
allocator->free_list_head = freeChunk->next;
|
||||
}
|
||||
|
||||
/* Update our successor's 'prev' pointer */
|
||||
if (freeChunk->next) {
|
||||
g_assert(WMEM_GET_FREE(freeChunk->next)->in_free_list);
|
||||
g_assert(WMEM_GET_FREE(freeChunk->next)->prev == chunk);
|
||||
WMEM_GET_FREE(freeChunk->next)->prev = freeChunk->prev;
|
||||
}
|
||||
|
||||
/* If we were the insert point, our predecessor is now */
|
||||
if (allocator->free_insert_point == chunk) {
|
||||
allocator->free_insert_point = freeChunk->prev;
|
||||
}
|
||||
|
@ -304,7 +310,7 @@ wmem_block_add_to_free_list_after(wmem_block_allocator_t *allocator,
|
|||
freeChunk->next = WMEM_GET_FREE(insertPoint)->next;
|
||||
freeChunk->prev = insertPoint;
|
||||
|
||||
WMEM_GET_FREE(insertPoint)->next = chunk;
|
||||
WMEM_GET_FREE(insertPoint)->next = chunk;
|
||||
if (freeChunk->next) {
|
||||
WMEM_GET_FREE(freeChunk->next)->prev = chunk;
|
||||
}
|
||||
|
@ -381,11 +387,16 @@ wmem_block_merge_free(wmem_block_allocator_t *allocator,
|
|||
tmp->len += chunk->len;
|
||||
|
||||
/* The chunk pointer passed in is no longer valid, it's been merged to
|
||||
* its left, so return the chunk to our left */
|
||||
return tmp;
|
||||
* its left, so use the chunk to our left */
|
||||
chunk = tmp;
|
||||
}
|
||||
|
||||
/* Now update the following chunk to have the correct 'prev' count */
|
||||
tmp = WMEM_CHUNK_NEXT(chunk);
|
||||
if (tmp) {
|
||||
tmp->prev = chunk->len;
|
||||
}
|
||||
|
||||
/* Otherwise return the chunk as passed in */
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
@ -492,6 +503,12 @@ wmem_block_split_free_chunk(wmem_block_allocator_t *allocator,
|
|||
extra->last = last;
|
||||
extra->prev = (guint32) (aligned_size + sizeof(wmem_block_chunk_t));
|
||||
extra->used = FALSE;
|
||||
|
||||
/* Correctly update the following chunk's back-pointer */
|
||||
chunk = WMEM_CHUNK_NEXT(extra);
|
||||
if (chunk) {
|
||||
chunk->prev = extra->len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Takes a used chunk and a size, and splits it into two chunks if possible.
|
||||
|
@ -540,6 +557,12 @@ wmem_block_split_used_chunk(wmem_block_allocator_t *allocator,
|
|||
extra->prev = (guint32) (aligned_size + sizeof(wmem_block_chunk_t));
|
||||
extra->used = FALSE;
|
||||
|
||||
/* Correctly update the following chunk's back-pointer */
|
||||
chunk = WMEM_CHUNK_NEXT(extra);
|
||||
if (chunk) {
|
||||
chunk->prev = extra->len;
|
||||
}
|
||||
|
||||
/* merge it to its right if possible (it can't be merged left, obviously) */
|
||||
wmem_block_merge_free(allocator, extra);
|
||||
|
||||
|
@ -672,14 +695,27 @@ wmem_block_realloc(void *private_data, void *ptr, const size_t size)
|
|||
|
||||
if (size > WMEM_CHUNK_DATA_LEN(chunk)) {
|
||||
/* grow */
|
||||
if (WMEM_CHUNK_NEXT(chunk) &&
|
||||
(!WMEM_CHUNK_NEXT(chunk)->used) &&
|
||||
(size < WMEM_CHUNK_DATA_LEN(chunk) + WMEM_CHUNK_NEXT(chunk)->len)) {
|
||||
wmem_block_chunk_t *tmp;
|
||||
|
||||
tmp = WMEM_CHUNK_NEXT(chunk);
|
||||
|
||||
if (tmp && (!tmp->used) &&
|
||||
(size < WMEM_CHUNK_DATA_LEN(chunk) + tmp->len)) {
|
||||
|
||||
/* the next chunk is free and has enough extra, so just grab
|
||||
* from that */
|
||||
wmem_block_split_free_chunk(allocator, chunk,
|
||||
wmem_block_split_free_chunk(allocator, tmp,
|
||||
(size - WMEM_CHUNK_DATA_LEN(chunk)
|
||||
- sizeof(wmem_block_chunk_t)));
|
||||
|
||||
/* Now update our 'next' count and our successor's 'prev' count */
|
||||
chunk->len += tmp->len;
|
||||
tmp = WMEM_CHUNK_NEXT(chunk);
|
||||
if (tmp) {
|
||||
tmp->prev = chunk->len;
|
||||
}
|
||||
|
||||
/* And return the same old pointer */
|
||||
return ptr;
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue