aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2005-07-22 07:46:58 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2005-07-22 07:46:58 +0000
commitc841beb71b9fb3b0dca979ed3ae7c6b578a80b6f (patch)
tree15ee9511e300d661e303aef5fa85911ed5c1ef5e
parent762fc4f4ebe09692c449aa521df1d14ebadc5709 (diff)
EMEM : a simple and FAST api to allocate memory that will be automatically freed() when the next packet is dissected.
This offesr memory allocation with a packet scope making memory leaks less likely and memory management faster. Add initialization calls for both tethereal and ethereal. Convert the ip_to_str() function to use this and avoid doing the silly rotating buffers thing it previously did. We also need an equivalent set of functions for allocation with capture file scope (free when next capture is loaded) but i dont know where to put the free_all call. svn path=/trunk/; revision=14984
-rw-r--r--epan/Makefile.common2
-rw-r--r--epan/emem.c140
-rw-r--r--epan/emem.h49
-rw-r--r--epan/epan.c4
-rw-r--r--epan/to_str.c16
-rw-r--r--gtk/main.c3
-rw-r--r--tethereal.c5
7 files changed, 207 insertions, 12 deletions
diff --git a/epan/Makefile.common b/epan/Makefile.common
index 6b7a6e168c..a1ee4fd58a 100644
--- a/epan/Makefile.common
+++ b/epan/Makefile.common
@@ -43,6 +43,7 @@ LIBETHEREAL_SRC = \
crypt-md4.c \
crypt-md5.c \
crypt-rc4.c \
+ emem.c \
epan.c \
except.c \
filesystem.c \
@@ -101,6 +102,7 @@ LIBETHEREAL_INCLUDES = \
crypt-md4.h \
crypt-md5.h \
crypt-rc4.h \
+ emem.h \
epan.h \
epan_dissect.h \
except.h \
diff --git a/epan/emem.c b/epan/emem.c
new file mode 100644
index 0000000000..458a2d727f
--- /dev/null
+++ b/epan/emem.c
@@ -0,0 +1,140 @@
+/* emem.c
+ * Ethereal memory management and garbage collection functions
+ * Ronnie Sahlberg 2005
+ *
+ * $Id: emem.c 14510 2005-05-31 21:17:54Z ulfl $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <glib.h>
+#include "emem.h"
+
+/* When required, allocate more memory from the OS in this size chunks */
+#define EMEM_PACKET_CHUNK_SIZE 10485760
+
+typedef struct _emem_chunk_t {
+ struct _emem_chunk_t *next;
+ unsigned int amount_free;
+ unsigned int free_offset;
+ char *buf;
+} emem_chunk_t;
+
+typedef struct _emem_header_t {
+ emem_chunk_t *free_list;
+ emem_chunk_t *used_list;
+} emem_header_t;
+
+static emem_header_t emem_packet_mem;
+
+/* Initialize the packet-lifetime memory allocation pool.
+ * This function should be called only once when Etehreal or Tethereal starts
+ * up.
+ */
+void
+ep_init_chunk(void)
+{
+ emem_packet_mem.free_list=NULL;
+ emem_packet_mem.used_list=NULL;
+}
+
+/* allocate 'size' amount of memory with an allocation lifetime until the
+ * next packet.
+ */
+void *
+ep_alloc(size_t size)
+{
+ void *buf;
+
+ /* round up to 8 byte boundary */
+ if(size&0x07){
+ size=(size+7)&0xfffffff8;
+ }
+
+ /* make sure we dont try to allocate too much (arbitrary limit) */
+ g_assert(size<(EMEM_PACKET_CHUNK_SIZE>>2));
+
+ /* we dont have any free data, so we must allocate a new one */
+ if(!emem_packet_mem.free_list){
+ emem_chunk_t *npc;
+ npc=g_malloc(sizeof(emem_chunk_t));
+ npc->next=NULL;
+ npc->amount_free=EMEM_PACKET_CHUNK_SIZE;
+ npc->free_offset=0;
+ npc->buf=g_malloc(EMEM_PACKET_CHUNK_SIZE);
+ emem_packet_mem.free_list=npc;
+ }
+
+ /* oops, we need to allocate more memory to serve this request
+ * than we have free. move this node to the used list and try again
+ */
+ if(size>emem_packet_mem.free_list->amount_free){
+ emem_chunk_t *npc;
+ npc=emem_packet_mem.free_list;
+ emem_packet_mem.free_list=emem_packet_mem.free_list->next;
+ npc->next=emem_packet_mem.used_list;
+ emem_packet_mem.used_list=npc;
+ }
+
+ /* we dont have any free data, so we must allocate a new one */
+ if(!emem_packet_mem.free_list){
+ emem_chunk_t *npc;
+ npc=g_malloc(sizeof(emem_chunk_t));
+ npc->next=NULL;
+ npc->amount_free=EMEM_PACKET_CHUNK_SIZE;
+ npc->free_offset=0;
+ npc->buf=g_malloc(EMEM_PACKET_CHUNK_SIZE);
+ emem_packet_mem.free_list=npc;
+ }
+
+
+ buf=emem_packet_mem.free_list->buf+emem_packet_mem.free_list->free_offset;
+
+ emem_packet_mem.free_list->amount_free-=size;
+ emem_packet_mem.free_list->free_offset+=size;
+
+ return buf;
+}
+
+/* release all allocated memory back to the pool.
+ */
+void
+ep_free_all(void)
+{
+ emem_chunk_t *npc;
+
+ /* move all used chunks ove to the free list */
+ while(emem_packet_mem.used_list){
+ npc=emem_packet_mem.used_list;
+ emem_packet_mem.used_list=emem_packet_mem.used_list->next;
+ npc->next=emem_packet_mem.free_list;
+ emem_packet_mem.free_list=npc;
+ }
+
+ /* clear them all out */
+ for(npc=emem_packet_mem.free_list;npc;npc=npc->next){
+ npc->amount_free=EMEM_PACKET_CHUNK_SIZE;
+ npc->free_offset=0;
+ }
+}
+
+
+
diff --git a/epan/emem.h b/epan/emem.h
new file mode 100644
index 0000000000..740ea081fe
--- /dev/null
+++ b/epan/emem.h
@@ -0,0 +1,49 @@
+/* emem.h
+ * Definitions for ethereal memory management and garbage collection
+ * Ronnie Sahlberg 2005
+ *
+ * $Id: emem.h 14436 2005-05-25 23:28:59Z ulfl $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EMEM_H__
+#define __EMEM_H__
+
+/* Functions for handling memory allocation and garbage collection with
+ * a packet lifetime scope.
+ * These functions are used to allocate memory that will only remain persistent
+ * until ethereal starts dissecting the next packet in the list.
+ * Everytime ethereal starts decoding the next packet all memory allocated
+ * through these functions will be released back to the free pool.
+ *
+ * These functions are very fast and offer automatic garbage collection:
+ * Everytime a new packet is dissected, all memory allocations done in
+ * the previous packet is freed.
+ */
+/* Initialize packet-lifetime memory allocation pool. This function is called
+ * once when [t]ethereal is initialized to set up the required structures.
+ */
+void ep_init_chunk(void);
+/* Allocate memory with a packet lifetime scope */
+void *ep_alloc(size_t size);
+/* release all memory allocated in the previous packet dissector */
+void ep_free_all(void);
+
+#endif /* emem.h */
diff --git a/epan/epan.c b/epan/epan.c
index e623d418dc..f4a75eae50 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -21,6 +21,7 @@
#include "column-utils.h"
#include "tap.h"
#include "addr_resolv.h"
+#include "emem.h"
static void (*report_failure_func)(const char *, va_list);
static void (*report_open_failure_func)(const char *, int, gboolean);
@@ -150,6 +151,9 @@ void
epan_dissect_run(epan_dissect_t *edt, void* pseudo_header,
const guint8* data, frame_data *fd, column_info *cinfo)
{
+ /* free all memory allocated during previous packet */
+ ep_free_all();
+
dissect_packet(edt, pseudo_header, data, fd, cinfo);
}
diff --git a/epan/to_str.c b/epan/to_str.c
index 5189242260..4fdb376964 100644
--- a/epan/to_str.c
+++ b/epan/to_str.c
@@ -67,6 +67,7 @@
#include <epan/dissectors/packet-mtp3.h>
#include <stdio.h>
#include <time.h>
+#include "emem.h"
#define MAX_BYTESTRING_LEN 6
@@ -140,18 +141,11 @@ ether_to_str(const guint8 *ad)
*/
gchar *
ip_to_str(const guint8 *ad) {
- static gchar str[4][16];
- static guint32 cur_idx=0;
- gchar *cur;
+ gchar *buf;
- cur_idx++;
- if(cur_idx>3){
- cur_idx=0;
- }
- cur=&str[cur_idx][0];
-
- ip_to_str_buf(ad, cur);
- return cur;
+ buf=ep_alloc(16);
+ ip_to_str_buf(ad, buf);
+ return buf;
}
/*
diff --git a/gtk/main.c b/gtk/main.c
index 06befcf45e..cb6d50f338 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -138,6 +138,7 @@
#endif
#include "capture_ui_utils.h"
#include "log.h"
+#include "../epan/emem.h"
@@ -1637,6 +1638,8 @@ main(int argc, char *argv[])
char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_CHILD) + sizeof(OPTSTRING_WIN32) - 2] =
OPTSTRING_INIT OPTSTRING_WIN32;
+ /* initialize memory allocation subsystem */
+ ep_init_chunk();
/*** create the compile and runtime version strings ***/
#ifdef _WIN32
diff --git a/tethereal.c b/tethereal.c
index 4bedfabfb0..5e499deb3a 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -103,7 +103,7 @@
#endif /* _WIN32 */
#include "capture.h"
#endif /* HAVE_LIBPCAP */
-
+#include "epan/emem.h"
/*
* This is the template for the decode as option; it is shared between the
@@ -654,6 +654,9 @@ main(int argc, char *argv[])
dfilter_t *rfcode = NULL;
e_prefs *prefs;
char badopt;
+
+ /* initialize memory allocation subsystem */
+ ep_init_chunk();
#ifdef HAVE_LIBPCAP
capture_opts_init(&capture_opts, NULL /* cfile */);