summaryrefslogtreecommitdiff
path: root/epan/emem.c
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2012-10-08 15:23:36 +0000
committerEvan Huus <eapache@gmail.com>2012-10-08 15:23:36 +0000
commitb6f0d11c6f538a6214af9e93ce07f8fde227460b (patch)
tree675372de1de864ff91efa2d767c96404fcc5020c /epan/emem.c
parent92c3bc0228b40742c079a03b41f2b25d3e8591d6 (diff)
downloadwireshark-b6f0d11c6f538a6214af9e93ce07f8fde227460b.tar.gz
EDT structures now own their ep_ memory pools. This should finally clean
up the last little bits of: - https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5284 - https://www.wireshark.org/lists/wireshark-dev/201208/msg00128.html and possibly part of: - https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7775 This is a fairly invasive change that required some funky work with linked lists to avoid changing any of the public ep_* APIs, so if something breaks blame me :) svn path=/trunk/; revision=45389
Diffstat (limited to 'epan/emem.c')
-rw-r--r--epan/emem.c81
1 files changed, 57 insertions, 24 deletions
diff --git a/epan/emem.c b/epan/emem.c
index 1076f8f842..fb38d75532 100644
--- a/epan/emem.c
+++ b/epan/emem.c
@@ -152,7 +152,12 @@ typedef struct _emem_header_t {
} emem_header_t;
-static emem_header_t ep_packet_mem;
+static GSList *ep_pool_stack = NULL;
+/* Some functions use ep_ calls when there isn't actually a packet in scope.
+ * These should perhaps be fixed, but in the meantime, ep_fake_pool is used
+ * to handle those cases. */
+static emem_header_t ep_fake_pool;
+static emem_header_t *ep_packet_mem = &ep_fake_pool;
static emem_header_t se_packet_mem;
/*
@@ -259,11 +264,11 @@ ep_check_canary_integrity(const char* fmt, ...)
g_vsnprintf(here, sizeof(here), fmt, ap);
va_end(ap);
- for (npc = ep_packet_mem.free_list; npc != NULL; npc = npc->next) {
+ for (npc = ep_packet_mem->free_list; npc != NULL; npc = npc->next) {
void *canary_next = npc->canary_last;
while (canary_next != NULL) {
- canary_next = emem_canary_next(ep_packet_mem.canary, canary_next, NULL);
+ canary_next = emem_canary_next(ep_packet_mem->canary, canary_next, NULL);
/* XXX, check if canary_next is inside allocated memory? */
if (canary_next == (void *) -1)
@@ -293,21 +298,21 @@ emem_init_chunk(emem_header_t *mem)
* up.
*/
static void
-ep_init_chunk(void)
+ep_init_chunk(emem_header_t *mem)
{
- ep_packet_mem.free_list=NULL;
- ep_packet_mem.used_list=NULL;
- ep_packet_mem.trees=NULL; /* not used by this allocator */
+ mem->free_list=NULL;
+ mem->used_list=NULL;
+ mem->trees=NULL; /* not used by this allocator */
- ep_packet_mem.debug_use_chunks = (getenv("WIRESHARK_DEBUG_EP_NO_CHUNKS") == NULL);
- ep_packet_mem.debug_use_canary = ep_packet_mem.debug_use_chunks && (getenv("WIRESHARK_DEBUG_EP_NO_CANARY") == NULL);
- ep_packet_mem.debug_verify_pointers = (getenv("WIRESHARK_EP_VERIFY_POINTERS") != NULL);
+ mem->debug_use_chunks = (getenv("WIRESHARK_DEBUG_EP_NO_CHUNKS") == NULL);
+ mem->debug_use_canary = mem->debug_use_chunks && (getenv("WIRESHARK_DEBUG_EP_NO_CANARY") == NULL);
+ mem->debug_verify_pointers = (getenv("WIRESHARK_EP_VERIFY_POINTERS") != NULL);
#ifdef DEBUG_INTENSE_CANARY_CHECKS
intense_canary_checking = (getenv("WIRESHARK_DEBUG_EP_INTENSE_CANARY") != NULL);
#endif
- emem_init_chunk(&ep_packet_mem);
+ emem_init_chunk(mem);
}
/* Initialize the capture-lifetime memory allocation pool.
@@ -335,8 +340,8 @@ se_init_chunk(void)
void
emem_init(void)
{
- ep_init_chunk();
se_init_chunk();
+ ep_init_chunk(&ep_fake_pool);
if (getenv("WIRESHARK_DEBUG_SCRUB_MEMORY"))
debug_use_memory_scrubber = TRUE;
@@ -387,21 +392,21 @@ print_alloc_stats()
fprintf(stderr, "\n-------- EP allocator statistics --------\n");
fprintf(stderr, "%s chunks, %s canaries, %s memory scrubber\n",
- ep_packet_mem.debug_use_chunks ? "Using" : "Not using",
- ep_packet_mem.debug_use_canary ? "using" : "not using",
+ ep_packet_mem->debug_use_chunks ? "Using" : "Not using",
+ ep_packet_mem->debug_use_canary ? "using" : "not using",
debug_use_memory_scrubber ? "using" : "not using");
- if (! (ep_packet_mem.free_list || !ep_packet_mem.used_list)) {
+ if (! (ep_packet_mem->free_list || !ep_packet_mem->used_list)) {
fprintf(stderr, "No memory allocated\n");
ep_stat = FALSE;
}
- if (ep_packet_mem.debug_use_chunks && ep_stat) {
+ if (ep_packet_mem->debug_use_chunks && ep_stat) {
/* Nothing interesting without chunks */
/* Only look at the used_list since those chunks are fully
* used. Looking at the free list would skew our view of what
* we have wasted.
*/
- for (chunk = ep_packet_mem.used_list; chunk; chunk = chunk->next) {
+ for (chunk = ep_packet_mem->used_list; chunk; chunk = chunk->next) {
num_chunks++;
total_used += (chunk->amount_free_init - chunk->amount_free);
total_allocation += chunk->amount_free_init;
@@ -555,8 +560,8 @@ emem_verify_pointer(const emem_header_t *hdr, const void *ptr)
gboolean
ep_verify_pointer(const void *ptr)
{
- if (ep_packet_mem.debug_verify_pointers)
- return emem_verify_pointer(&ep_packet_mem, ptr);
+ if (ep_packet_mem->debug_verify_pointers)
+ return emem_verify_pointer(ep_packet_mem, ptr);
else
return FALSE;
}
@@ -864,7 +869,7 @@ emem_alloc(size_t size, emem_header_t *mem)
void *
ep_alloc(size_t size)
{
- return emem_alloc(size, &ep_packet_mem);
+ return emem_alloc(size, ep_packet_mem);
}
/* allocate 'size' amount of memory with an allocation lifetime until the
@@ -1237,11 +1242,39 @@ emem_free_all(emem_header_t *mem)
}
}
-/* release all allocated memory back to the pool. */
-void
-ep_free_all(void)
+emem_header_t *ep_create_pool(void)
+{
+ emem_header_t *mem;
+
+ mem = g_malloc(sizeof(emem_header_t));
+
+ ep_init_chunk(mem);
+
+ if (ep_pool_stack == NULL) {
+ emem_free_all(&ep_fake_pool);
+ }
+
+ ep_pool_stack = g_slist_prepend(ep_pool_stack, mem);
+
+ ep_packet_mem = mem;
+
+ return mem;
+}
+
+void ep_free_pool(emem_header_t *mem)
{
- emem_free_all(&ep_packet_mem);
+ ep_pool_stack = g_slist_remove(ep_pool_stack, mem);
+
+ emem_free_all(mem);
+
+ g_free(mem);
+
+ if (ep_pool_stack == NULL) {
+ ep_packet_mem = &ep_fake_pool;
+ }
+ else {
+ ep_packet_mem = ep_pool_stack->data;
+ }
}
/* release all allocated memory back to the pool. */