aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2012-11-10 14:43:27 +0000
committerEvan Huus <eapache@gmail.com>2012-11-10 14:43:27 +0000
commitffd9a73b69bd84c1503b45ac05756e8c18a8b719 (patch)
tree34d38494a0e56af27529de3b2ecdca6fe70e7af1 /doc
parent6f1847f60667f4ebb33f33f9b50c550052577f65 (diff)
More wmem documentation.
svn path=/trunk/; revision=45989
Diffstat (limited to 'doc')
-rw-r--r--doc/README.wmem82
1 files changed, 62 insertions, 20 deletions
diff --git a/doc/README.wmem b/doc/README.wmem
index 710ddd16a4..d12d720f77 100644
--- a/doc/README.wmem
+++ b/doc/README.wmem
@@ -2,14 +2,14 @@ $Id$
1. Introduction
-NB: Wmem is still very much incomplete and under construction. New code will
- likely want to continue using emem for the time being.
+NB: Wmem is still incomplete and under construction. New code may need to
+ continue using emem for the time being.
The 'emem' memory manager (described in README.malloc) has been a part of
Wireshark since 2005 and has served us well, but is starting to show its age.
The framework has become increasingly difficult to maintain, and limitations
-in the API have blocked progress on other long-term goals (like multi-
-threading, and opening multiple files at once).
+in the API have blocked progress on other long-term goals such as multi-
+threading, and opening multiple files at once.
The 'wmem' memory manager is an attempt to write a new memory management
framework to replace emem. It provides a significantly updated API, a more
@@ -28,9 +28,9 @@ should be very similar to using emem. All you need to do is include the header
a memory pool, see the section "3. Usage for Producers" below).
A memory pool is an opaque pointer to an object of type wmem_allocator_t, and
-it should be the very first parameter passed to almost every call you make to
-wmem. Other than that (and the fact that functions are prefixed wmem_ instead
-of ep_ or se_) usage is exactly like that of emem. For example:
+it is the very first parameter passed to almost every call you make to wmem.
+Other than that parameter (and the fact that functions are prefixed wmem_
+instead of ep_ or se_) usage is exactly like that of emem. For example:
wmem_alloc(myPool, 20);
@@ -48,11 +48,13 @@ program. The packet pool is scoped to the dissection of each packet, replacing
emem's ep_ allocators. The file pool is scoped to the dissection of each file,
replacing emem's se_ allocators. For example:
- ep_malloc(20);
+ ep_malloc(32);
+ se_malloc(sizeof(guint));
could be replaced with
- wmem_alloc(wmem_packet_scope(), 20);
+ wmem_alloc(wmem_packet_scope(), 32);
+ wmem_alloc(wmem_file_scope(), sizeof(guint));
NB: Using these pools outside of the appropriate scope (eg using the packet
pool when there isn't a packet being dissected) will throw an assertion.
@@ -89,16 +91,16 @@ NB: If you're just writing a dissector, you probably don't need to read
One of the problems with the old emem framework was that there were basically
two allocator backends (glib and mmap) that were all mixed together in a mess
-of if statements, environment variables and even a few #ifdefs. In wmem the
-different allocator backends are cleanly separated out, and it's up to the
-maintainer of the pool to pick one.
+of if statements, environment variables and #ifdefs. In wmem the different
+allocator backends are cleanly separated out, and it's up to the owner of the
+pool to pick one.
3.1 Available Allocator Back-Ends
The currently available allocators are:
- glib (wmem_allocator_glib.h)
A simple allocator that g_allocs requested memory and tracks each
- allocation in a linked list.
+ allocation via a linked list.
3.2 Creating a Pool
@@ -116,7 +118,8 @@ helper functions in their headers). The "myPool" variable can be passed around
and used as normal in allocation requests as described in section 2 of this
document.
-All the other functions in this section can be found in epan/wmem/wmem.h.
+All the other functions described in this section can be found
+in epan/wmem/wmem.h.
3.3 Destroying a Pool
@@ -139,11 +142,10 @@ Destroying a pool will free all the memory allocated in it.
3.4 Reusing a Pool
It is possible to free all the memory in a pool without destroying it,
-allowing it to be reused later. This can be useful if you have a loop you
-wish to allocate memory in, but you don't want to pay the cost of destroying
-and creating an entire pool each time.
-
-The memory of a pool can be freed with a call to wmem_free_all(), like so:
+allowing it to be reused later. Depending on the type of allocator, doing this
+(by calling wmem_free_all()) can be significantly cheaper than fully destroying
+and recreating the pool. This method is therefore recommended, especially when
+the pool would otherwise be scoped to a single iteration of a loop. For example:
#include "wmem/wmem.h"
#include "wmem/wmem_allocator_glib.h"
@@ -155,13 +157,53 @@ The memory of a pool can be freed with a call to wmem_free_all(), like so:
/* Allocate some memory in myPool ... */
+ /* Free the memory, faster than destroying and recreating
+ the pool each time through the loop. */
wmem_free_all(myPool);
}
wmem_destroy_allocator(myPool);
4. Internal Design
-TODO
+Despite being written in Wireshark's standard C90, wmem follows a fairly
+object-oriented design pattern. Although efficiency is always a concern, the
+primary goals in writing wmem were maintainability, and preventing memory
+leaks.
+
+4.1 struct _wmem_allocator_t
+
+The heart of wmem is the _wmem_allocator_t structure defined in the
+wmem_allocator.h header file. This structure uses C function pointers to
+implement a common object-oriented pattern known as an interface (AKA 'abstract
+class' to those of you who are more familiar with C++).
+
+Different allocator implementations can provide exactly the same interface by
+assigning their own functions (of the appropriate signature) to the members of
+an instance of the structure. The structure currently has four values:
+
+ - alloc()
+ - free_all()
+ - destroy()
+ - private_data
+
+The private_data pointer is a void pointer that the implementation can use to
+store whatever internal structures it needs. The other three functions should
+be fairly obvious - each one is called with a pointer to the private_data in
+addition to any other arguments.
+
+4.2 Pool-Agnostic API
+
+One of the issues with emem was that the API (including the public data
+structures) required wrapper functions for each scope implemented. Even
+if there was a stack implementation in emem, it wasn't necessarily available
+for use with file-scope memory unless someone took the time to write se_stack_
+wrapper functions for the interface.
+
+In wmem, all public APIs take the pool as the first argument, so that they can
+be written once and used with any available memory pool. Data structures like
+wmem's stack implementation only take the pool when created - the provided
+pointer is stored internally with the data structure, and subsequent calls
+(like push and pop) will take the stack itself instead of the pool.
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html