name change
[obnox/wireshark/wip.git] / epan / emem.h
1 /* emem.h
2  * Definitions for ethereal memory management and garbage collection
3  * Ronnie Sahlberg 2005
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifndef __EMEM_H__
27 #define __EMEM_H__
28
29 #include "gnuc_format_check.h"
30
31 /* Functions for handling memory allocation and garbage collection with 
32  * a packet lifetime scope.
33  * These functions are used to allocate memory that will only remain persistent
34  * until ethereal starts dissecting the next packet in the list.
35  * Everytime ethereal starts decoding the next packet all memory allocated
36  * through these functions will be released back to the free pool.
37  *
38  * These functions are very fast and offer automatic garbage collection:
39  * Everytime a new packet is dissected, all memory allocations done in
40  * the previous packet is freed.
41  */
42 /* Initialize packet-lifetime memory allocation pool. This function is called 
43  * once when [t]ethereal is initialized to set up the required structures.
44  */
45 void ep_init_chunk(void);
46
47 /* Allocate memory with a packet lifetime scope */
48 void *ep_alloc(size_t size);
49 #define ep_new(type) ((type*)ep_alloc(sizeof(type)))
50
51 /* Allocate memory with a packet lifetime scope and fill it with zeros*/
52 void* ep_alloc0(size_t size);
53 #define ep_new0(type) ((type*)ep_alloc0(sizeof(type)))
54
55 /* Duplicate a string with a packet lifetime scope */
56 gchar* ep_strdup(const gchar* src);
57
58 /* Duplicate at most n characters of a string with a packet lifetime scope */
59 gchar* ep_strndup(const gchar* src, size_t len);
60
61 /* Duplicate a buffer with a packet lifetime scope */
62 void* ep_memdup(const void* src, size_t len);
63
64 /* Create a formatted string with a packet lifetime scope */
65 gchar* ep_strdup_vprintf(const gchar* fmt, va_list ap);
66 gchar* ep_strdup_printf(const gchar* fmt, ...)
67     GNUC_FORMAT_CHECK(printf, 1, 2);
68
69 /* allocates with a packet lifetime scope an array of type made of num elements */
70 #define ep_alloc_array(type,num) (type*)ep_alloc(sizeof(type)*(num))
71
72 /* 
73  * Splits a string into a maximum of max_tokens pieces, using the given
74  * delimiter. If max_tokens is reached, the remainder of string is appended
75  * to the last token. Consecutive delimiters are treated as a single delimiter.
76  *
77  * the vector and all the strings are allocated with packet lifetime scope
78  */
79 gchar** ep_strsplit(const gchar* string, const gchar* delimiter, int max_tokens);
80
81 /* release all memory allocated in the previous packet dissector */
82 void ep_free_all(void);
83
84
85 /* a stack implemented using ephemeral allocators */
86
87 typedef struct _ep_stack_frame_t** ep_stack_t;
88
89 struct _ep_stack_frame_t {
90     void* payload;
91     struct _ep_stack_frame_t* below;
92     struct _ep_stack_frame_t* above;
93 };
94
95 /*
96  * creates an empty stack with a packet lifetime scope
97  */
98 ep_stack_t ep_stack_new(void);
99
100 /*
101  * pushes item into stack, returns item
102  */
103 void* ep_stack_push(ep_stack_t stack, void* item);
104
105 /*
106  * pops an item from the stack
107  */
108 void* ep_stack_pop(ep_stack_t stack);
109
110 /*
111  * returns the item on top of the stack without popping it
112  */
113 #define ep_stack_peek(stack) ((*(stack))->payload)
114
115
116 /* Functions for handling memory allocation and garbage collection with 
117  * a capture lifetime scope.
118  * These functions are used to allocate memory that will only remain persistent
119  * until ethereal opens a new capture or capture file.
120  * Everytime ethereal starts a new capture or opens a new capture file
121  * all the data allocated through these functions will be released back 
122  * to the free pool.
123  *
124  * These functions are very fast and offer automatic garbage collection.
125  */
126 /* Initialize capture-lifetime memory allocation pool. This function is called 
127  * once when [t]ethereal is initialized to set up the required structures.
128  */
129 void se_init_chunk(void);
130
131 /* Allocate memory with a capture lifetime scope */
132 void *se_alloc(size_t size);
133
134 /* Allocate memory with a capture lifetime scope and fill it with zeros*/
135 void* se_alloc0(size_t size);
136
137 /* Duplicate a string with a capture lifetime scope */
138 gchar* se_strdup(const gchar* src);
139
140 /* Duplicate at most n characters of a string with a capture lifetime scope */
141 gchar* se_strndup(const gchar* src, size_t len);
142
143 /* Duplicate a buffer with a capture lifetime scope */
144 void* se_memdup(const void* src, size_t len);
145
146 /* Create a formatted string with a capture lifetime scope */
147 gchar* se_strdup_vprintf(const gchar* fmt, va_list ap);
148 gchar* se_strdup_printf(const gchar* fmt, ...)
149     GNUC_FORMAT_CHECK(printf, 1, 2);
150
151 /* allocates with a capture lifetime scope an array of type made of num elements */
152 #define se_alloc_array(type,num) (type*)se_alloc(sizeof(type)*(num))
153
154 /* release all memory allocated */
155 void se_free_all(void);
156
157
158
159
160 /**************************************************************
161  * binary trees with SE allocation 
162  **************************************************************/
163 #define SE_TREE_RB_COLOR_RED    0x00
164 #define SE_TREE_RB_COLOR_BLACK  0x01
165 typedef struct _se_tree_node_t {
166         struct _se_tree_node_t *parent;
167         struct _se_tree_node_t *left;
168         struct _se_tree_node_t *right;
169         union {
170                 guint32 rb_color;
171         } u;
172         guint32 key32;
173         void *data;
174 } se_tree_node_t;
175
176 /* list of all se trees so they can all be reset automatically when
177  * we free all se memory
178  */
179 /* Right now we only do basic red/black trees   but in the future we might want
180  * to try something different, such as a tree where each node keeps track
181  * of how many times it has been looked up, and letting often looked up
182  * nodes bubble upwards in the tree using rotate_right/left.
183  * That would probably be good for things like nfs filehandles 
184  */
185 #define SE_TREE_TYPE_RED_BLACK  1
186 typedef struct _se_tree_t {
187         struct _se_tree_t *next;
188         int type;
189         char *name;    /* just a string to make debugging easier */
190         se_tree_node_t *tree;
191 } se_tree_t;
192 extern se_tree_t *se_trees;
193
194
195 /* This function is used to create a se based tree with monitoring.
196  * When the SE heap is released back to the system the pointer to the 
197  * tree is automatically reset to NULL.
198  *
199  * type is : SE_TREE_TYPE_RED_BLACK for a standard red/black tree.
200  */
201 se_tree_t *se_tree_create(int type, char *name);
202
203 /* This function is used to insert a node indexed by a guint32 key value.
204  * The data pointer should be allocated by SE allocators so that the
205  * data will be released at the same time as the tree itself is destroyed.
206  */
207 void se_tree_insert32(se_tree_t *se_tree, guint32 key, void *data);
208
209 /* This function will look up a node in the tree indexed by a guint32 integer
210  * value.
211  */
212 void *se_tree_lookup32(se_tree_t *se_tree, guint32 key);
213
214 /* This function will look up a node in the tree indexed by a guint32 integer
215  * value.
216  * The function will return the node that has the largest key that is 
217  * equal to or smaller than the search key, or NULL if no such key was
218  * found.
219  */
220 void *se_tree_lookup32_le(se_tree_t *se_tree, guint32 key);
221
222
223 /* This function is similar to the se_tree_create() call but with the
224  * difference that when the se memory is release everything including the 
225  * pointer to the tree itself will be released.
226  * This tree will not be just reset to zero  it will be completely forgotten
227  * by the allocator.
228  * Use this function for when you want to store the pointer to a tree inside
229  * another structure that is also se allocated so that when the structure is
230  * released, the tree will be completely released as well.
231  */
232 se_tree_t *se_tree_create_non_persistent(int type, char *name);
233
234 typedef struct _se_tree_key_t {
235         guint32 length;                 /*length in guint32 words */
236         guint32 *key;
237 } se_tree_key_t;
238
239 /* This function is used to insert a node indexed by a sequence of guint32 
240  * key values.
241  * The data pointer should be allocated by SE allocators so that the
242  * data will be released at the same time as the tree itself is destroyed.
243  *
244  * If you use ...32_array() calls you MUST make sure that every single node
245  * you add to a specific tree always has a key of exactly the same number of 
246  * keylen words or things will most likely crash. Or at least that every single
247  * item that sits behind the same top level node always have exactly the same
248  * number of words.
249  *
250  * One way to guarantee this is the way that NFS does this for the
251  * nfs_name_snoop_known  tree which holds filehandles for both v2 and v3.
252  * v2 filehandles are always 32 bytes (8 words) while v3 filehandles can have
253  * any length (though 32bytes are most common).
254  * The NFS dissector handles this by providing a guint32 containing the length
255  * as the very first item in this vector :
256  *
257  *                      se_tree_key_t fhkey[3];
258  *
259  *                      fhlen=nns->fh_length;
260  *                      fhkey[0].length=1;
261  *                      fhkey[0].key=&fhlen;
262  *                      fhkey[1].length=fhlen/4;
263  *                      fhkey[1].key=nns->fh;
264  *                      fhkey[2].length=0;
265  */
266 void se_tree_insert32_array(se_tree_t *se_tree, se_tree_key_t *key, void *data);
267
268 /* This function will look up a node in the tree indexed by a sequence of
269  * guint32 integer values.
270  */
271 void *se_tree_lookup32_array(se_tree_t *se_tree, se_tree_key_t *key);
272
273 /*
274  * A hash table with string keys based on the red/black tree
275  */
276 typedef struct _se_tree_t se_string_hash_t;
277
278 /* Create a new string based hash table */
279 #define se_tree_create_string() se_tree_create(SE_TREE_TYPE_RED_BLACK)
280
281 /* Insert a new value under a string key */
282 void se_tree_insert_string(se_string_hash_t* h, const gchar* k, void* v);
283
284 /* Lookup the value under a string key */
285 void* se_tree_lookup_string(se_string_hash_t* h, const gchar* k);
286
287
288 #endif /* emem.h */