wmem documentation updates
[metze/wireshark/wip.git] / doc / README.wmem
1 1. Introduction
2
3 The 'emem' memory manager (described in README.malloc) has been a part of
4 Wireshark since 2005 and has served us well, but is starting to show its age.
5 The framework has become increasingly difficult to maintain, and limitations
6 in the API have blocked progress on other long-term goals such as multi-
7 threading, and opening multiple files at once.
8
9 The 'wmem' memory manager is a new memory management framework that replaces
10 emem. It provides a significantly updated API, a more modular design, and it
11 isn't all jammed into one 2500-line file.
12
13 Wmem was originally conceived in this email to the wireshark-dev mailing list:
14 https://www.wireshark.org/lists/wireshark-dev/201210/msg00178.html
15
16 The wmem code can now be found in epan/wmem/ in the Wireshark source tree.
17
18 2. Usage for Consumers
19
20 If you're writing a dissector, or other "userspace" code, then using wmem
21 should be very similar to using emem. All you need to do is include the header
22 (epan/wmem/wmem.h) and get a handle to a memory pool (if you want to *create*
23 a memory pool, see the section "3. Usage for Producers" below).
24
25 A memory pool is an opaque pointer to an object of type wmem_allocator_t, and
26 it is the very first parameter passed to almost every call you make to wmem.
27 Other than that parameter (and the fact that functions are prefixed wmem_
28 instead of ep_ or se_) usage is exactly like that of emem. For example:
29
30     wmem_alloc(myPool, 20);
31
32 allocates 20 bytes in the pool pointed to by myPool.
33
34 2.1 Available Pools
35
36 2.1.1 (Sort Of) Global Pools
37
38 Dissectors that include the wmem header file will have three pools available
39 to them automatically: wmem_packet_scope(), wmem_file_scope() and
40 wmem_epan_scope();
41
42 The packet pool is scoped to the dissection of each packet, replacing
43 emem's ep_ allocators. The file pool is scoped to the dissection of each file,
44 replacing emem's se_ allocators. For example:
45
46     ep_malloc(32);
47     se_malloc(sizeof(guint));
48
49 could be replaced with
50
51     wmem_alloc(wmem_packet_scope(), 32);
52     wmem_alloc(wmem_file_scope(),   sizeof(guint));
53
54 NB: Using these pools outside of the appropriate scope (eg using the packet
55     pool when there isn't a packet being dissected) will throw an assertion.
56     See the comment in epan/wmem/wmem_scopes.c for details.
57
58 The epan pool is scoped to the library's lifetime - memory allocated in it is
59 not freed until epan_cleanup() is called, which is typically at the end of the
60 program.
61
62 2.1.2 Pinfo Pool
63
64 Certain allocations (such as AT_STRINGZ address allocations and anything that
65 might end up being passed to add_new_data_source) need their memory to stick
66 around a little longer than the usual packet scope - basically until the
67 next packet is dissected. This is, in fact, the scope of Wireshark's pinfo
68 structure, so the pinfo struct has a 'pool' member which is a wmem pool scoped
69 to the lifetime of the pinfo struct.
70
71 2.1.3 NULL Pool
72
73 Any function that takes a pointer to a wmem_allocator_t can also be passed NULL
74 instead. In this case the memory is not allocated in a pool at all - it is
75 manually managed, and *must* eventually be passed to wmem_free() in order to
76 prevent memory leaks. Note that passing wmem_allocated memory directly to free()
77 or g_free() is not safe; the backing type of manually managed memory may be
78 changed without warning.
79
80 2.2 API
81
82 Full documentation for each function (parameters, return values, behaviours)
83 lives (or will live) in Doxygen-format in the header files for those functions.
84 This is just an overview of which header files you should be looking at.
85
86 2.2.1 Core API
87
88 wmem_core.h
89  - Basic memory management functions (wmem_alloc, wmem_realloc, wmem_free).
90
91 2.2.2 Strings
92
93 wmem_strutl.h
94  - Utility functions for manipulating null-terminated C-style strings.
95    Functions like strdup and strdup_printf.
96
97 wmem_strbuf.h
98  - A managed string object implementation, similar to std::string in C++ or
99    GString from Glib.
100
101 2.2.3 Container Data Structures
102
103 wmem_array.h
104  - A growable array (AKA vector) implementation.
105
106 wmem_list.h
107  - A doubly-linked list implementation.
108
109 wmem_map.h
110  - A hash map (AKA hash table) implementation.
111
112 wmem_queue.h
113  - A queue implementation (first-in, first-out).
114
115 wmem_stack.h
116  - A stack implementation (last-in, first-out).
117
118 wmem_tree.h
119  - A balanced binary tree (red-black tree) implementation.
120
121 2.2.4 Miscellaneous Utilities
122
123 wmem_miscutl.h
124  - Misc. utility functions like memdup.
125
126 2.3 Callbacks
127
128 WARNING: You probably don't actually need these; use them only when you're
129          sure you understand the dangers.
130
131 Sometimes (though hopefully rarely) it may be necessary to store data in a wmem
132 pool that requires additional cleanup before it is freed. For example, perhaps
133 you have a pointer to a file-handle that needs to be closed. In this case, you
134 can register a callback with the wmem_register_cleanup_callback function
135 declared in wmem_user_cb.h. Every time the memory in a pool is freed, all
136 registered cleanup functions are called first.
137
138 Note that callback calling order is not defined, you cannot rely on a
139 certain callback being called before or after another.
140
141 WARNING: Manually freeing or moving memory (with wmem_free or wmem_realloc)
142          will NOT trigger any callbacks. It is an error to call either of
143          those functions on memory if you have a callback registered to deal
144          with the contents of that memory.
145
146 3. Usage for Producers
147
148 NB: If you're just writing a dissector, you probably don't need to read
149     this section.
150
151 One of the problems with the old emem framework was that there were basically
152 two allocator backends (glib and mmap) that were all mixed together in a mess
153 of if statements, environment variables and #ifdefs. In wmem the different
154 allocator backends are cleanly separated out, and it's up to the owner of the
155 pool to pick one.
156
157 3.1 Available Allocator Back-Ends
158
159 Each available allocator type has a corresponding entry in the
160 wmem_allocator_type_t enumeration defined in wmem_core.h. See the doxygen
161 comments in that header file for details on each type.
162
163 3.2 Creating a Pool
164
165 To create a pool, include the regular wmem header and call the
166 wmem_allocator_new() function with the appropriate type value.
167 For example:
168
169     #include "wmem/wmem.h"
170
171     wmem_allocator_t *myPool;
172     myPool = wmem_allocator_new(WMEM_ALLOCATOR_SIMPLE);
173
174 From here on in, you don't need to remember which type of allocator you used
175 (although allocator authors are welcome to expose additional allocator-specific
176 helper functions in their headers). The "myPool" variable can be passed around
177 and used as normal in allocation requests as described in section 2 of this
178 document.
179
180 3.3 Destroying a Pool
181
182 Regardless of which allocator you used to create a pool, it can be destroyed
183 with a call to the function wmem_destroy_allocator(). For example:
184
185     #include "wmem/wmem.h"
186
187     wmem_allocator_t *myPool;
188
189     myPool = wmem_allocator_new(WMEM_ALLOCATOR_SIMPLE);
190
191     /* Allocate some memory in myPool ... */
192
193     wmem_destroy_allocator(myPool);
194
195 Destroying a pool will free all the memory allocated in it.
196
197 3.4 Reusing a Pool
198
199 It is possible to free all the memory in a pool without destroying it,
200 allowing it to be reused later. Depending on the type of allocator, doing this
201 (by calling wmem_free_all()) can be significantly cheaper than fully destroying
202 and recreating the pool. This method is therefore recommended, especially when
203 the pool would otherwise be scoped to a single iteration of a loop. For example:
204
205     #include "wmem/wmem.h"
206
207     wmem_allocator_t *myPool;
208
209     myPool = wmem_allocator_new(WMEM_ALLOCATOR_SIMPLE);
210     for (...) {
211
212         /* Allocate some memory in myPool ... */
213
214         /* Free the memory, faster than destroying and recreating
215            the pool each time through the loop. */
216         wmem_free_all(myPool);
217     }
218     wmem_destroy_allocator(myPool);
219
220 4. Internal Design
221
222 Despite being written in Wireshark's standard C90, wmem follows a fairly
223 object-oriented design pattern. Although efficiency is always a concern, the
224 primary goals in writing wmem were maintainability and preventing memory
225 leaks.
226
227 4.1 struct _wmem_allocator_t
228
229 The heart of wmem is the _wmem_allocator_t structure defined in the
230 wmem_allocator.h header file. This structure uses C function pointers to
231 implement a common object-oriented design pattern known as an interface (also
232 known as an abstract class to those who are more familiar with C++).
233
234 Different allocator implementations can provide exactly the same interface by
235 assigning their own functions to the members of an instance of the structure.
236 The structure has eight members in three groups.
237
238 4.1.1 Implementation Details
239
240  - private_data
241  - type
242
243 The private_data pointer is a void pointer that the allocator implementation can
244 use to store whatever internal structures it needs. A pointer to private_data is
245 passed to almost all of the other functions that the allocator implementation
246 must define.
247
248 The type field is an enumeration of type wmem_allocator_type_t (see
249 section 3.1). Its value is set by the wmem_allocator_new() function, not
250 by the implementation-specific constructor. This field should be considered
251 read-only by the allocator implementation.
252
253 4.1.2 Consumer Functions
254
255  - alloc()
256  - free()
257  - realloc()
258
259 These function pointers should be set to functions with semantics obviously
260 similar to their standard-library namesakes. Each one takes an extra parameter
261 that is a copy of the allocator's private_data pointer.
262
263 Note that realloc() and free() are not expected to be called directly by user
264 code in most cases - they are primarily optimisations for use by data
265 structures that wmem might want to implement (it's inefficient, for example, to
266 implement a dynamically sized array without some form of realloc).
267
268 Also note that allocators do not have to handle NULL pointers or 0-length
269 requests in any way - those checks are done in an allocator-agnostic way
270 higher up in wmem. Allocator authors can assume that all incoming pointers
271 (to realloc and free) are non-NULL, and that all incoming lengths (to malloc
272 and realloc) are non-0.
273
274 4.1.3 Producer/Manager Functions
275
276  - free_all()
277  - gc()
278  - cleanup()
279
280 All of these functions take only one parameter, which is the allocator's
281 private_data pointer.
282
283 The free_all() function should free all the memory currently allocated in the
284 pool. Note that this is not necessarily exactly the same as calling free()
285 on all the allocated blocks - free_all() is allowed to do additional cleanup
286 or to make use of optimizations not available when freeing one block at a time.
287
288 The gc() function should do whatever it can to reduce excess memory usage in
289 the dissector by returning unused blocks to the OS, optimizing internal data
290 structures, etc.
291
292 The cleanup() function should do any final cleanup and free any and all memory.
293 It is basically the equivalent of a destructor function. For simplicity, wmem
294 is guaranteed to call free_all() immediately before calling this function. There
295 is no such guarantee that gc() has (ever) been called.
296
297 4.2 Pool-Agnostic API
298
299 One of the issues with emem was that the API (including the public data
300 structures) required wrapper functions for each scope implemented. Even
301 if there was a stack implementation in emem, it wasn't necessarily available
302 for use with file-scope memory unless someone took the time to write se_stack_
303 wrapper functions for the interface.
304
305 In wmem, all public APIs take the pool as the first argument, so that they can
306 be written once and used with any available memory pool. Data structures like
307 wmem's stack implementation only take the pool when created - the provided
308 pointer is stored internally with the data structure, and subsequent calls
309 (like push and pop) will take the stack itself instead of the pool.
310
311 4.3 Debugging
312
313 The primary debugging control for wmem is the WIRESHARK_DEBUG_WMEM_OVERRIDE
314 environment variable. If set, this value forces all calls to
315 wmem_allocator_new() to return the same type of allocator, regardless of which
316 type is requested normally by the code. It currently has three valid values:
317
318  - The value "simple" forces the use of WMEM_ALLOCATOR_SIMPLE. The valgrind
319    script currently sets this value, since the simple allocator is the only
320    one whose memory allocations are trackable properly by valgrind.
321
322  - The value "strict" forces the use of WMEM_ALLOCATOR_STRICT. The fuzz-test
323    script currently sets this value, since the goal when fuzz-testing is to find
324    as many errors as possible.
325
326  - The value "block" forces the use of WMEM_ALLOCATOR_BLOCK. This is not
327    currently used by any scripts, but is useful for stress-testing the block
328    allocator.
329
330  - The value "block_fast" forces the use of WMEM_ALLOCATOR_BLOCK_FAST. This is
331    not currently used by any scripts, but is useful for stress-testing the fast
332    block allocator.
333
334 Note that regardless of the value of this variable, it will always be safe to
335 call allocator-specific helpers functions. They are required to be safe no-ops
336 if the allocator argument is of the wrong type.
337
338 4.4 Testing
339
340 There is a simple test suite for wmem that lives in the file wmem_test.c and
341 should get automatically built into the binary 'wmem_test' when building
342 Wireshark. It contains at least basic tests for all existing functionality.
343 The suite is run automatically by the build-bots via the shell script
344 test/test.sh which calls out to test/suite-unittests.sh.
345
346 New features added to wmem (allocators, data structures, utility
347 functions, etc.) MUST also have tests added to this suite.
348
349 The test suite could potentially use a clean-up by someone more
350 intimately familiar with Glib's testing framework, but it does the job.
351
352 /*
353  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
354  *
355  * Local variables:
356  * c-basic-offset: 4
357  * tab-width: 8
358  * indent-tabs-mode: nil
359  * End:
360  *
361  * vi: set shiftwidth=4 tabstop=8 expandtab:
362  * :indentSize=4:tabSize=8:noTabs=true:
363  */