aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-01-19 16:15:32 +0000
committerEvan Huus <eapache@gmail.com>2013-01-19 16:15:32 +0000
commit21453d5db64a4e6c950b0915d793a7ed6f1b5b85 (patch)
tree3ac7d385dcbc61069090fe89edd7112ce0a7778b
parentf177deead0f3c0d7c22f1a4510e6af06ae8ef731 (diff)
Add three more slots to the wmem allocater definition (not yet implemented
by any particular allocator) and better document the entire structure. svn path=/trunk/; revision=47163
-rw-r--r--doc/README.wmem60
-rw-r--r--epan/wmem/wmem_allocator.h15
-rw-r--r--epan/wmem/wmem_allocator_block.c6
-rw-r--r--epan/wmem/wmem_allocator_simple.c6
-rw-r--r--epan/wmem/wmem_allocator_strict.c6
5 files changed, 76 insertions, 17 deletions
diff --git a/doc/README.wmem b/doc/README.wmem
index b21bf01bf2..21d24f2898 100644
--- a/doc/README.wmem
+++ b/doc/README.wmem
@@ -215,7 +215,7 @@ the pool would otherwise be scoped to a single iteration of a loop. For example:
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
+primary goals in writing wmem were maintainability and preventing memory
leaks.
4.1 struct _wmem_allocator_t
@@ -227,21 +227,59 @@ known as an abstract class to those who are more familiar with C++).
Different allocator implementations can provide exactly the same interface by
assigning their own functions to the members of an instance of the structure.
-The structure currently has five members:
+The structure has eight members in three groups.
+
+4.1.1 Implementation Details
+
+ - private_data
+ - type
+
+The private_data pointer is a void pointer that the allocator implementation can
+use to store whatever internal structures it needs. A pointer to private_data is
+passed to almost all of the other functions that the allocator implementation
+must define.
+
+The type field is an enumeration of type wmem_allocator_type_t (see
+section 3.1). Its value is set by the wmem_allocator_new() function, not
+by the implementation-specific constructor. This field should be considered
+read-only by the allocator implementation.
+
+4.1.2 Consumer Functions
- alloc()
+ - realloc()
+ - free()
+
+These function pointers should be set to functions with semantics obviously
+similar to their standard-library namesakes. Each one takes an extra parameter
+that is a copy of the allocator's private_data pointer.
+
+Note that realloc() and free() are not expected to be called directly by user
+code in most cases - they are primarily optimisations for use by data
+structures that wmem might want to implement (it's hard, for example, to
+implement a dynamically sized array without some form of realloc).
+
+4.1.3 Producer/Manager Functions
+
- free_all()
+ - gc()
- destroy()
- - private_data
- - type
-The private_data pointer is a void pointer that the implementation can use to
-store whatever internal structures it needs. The type field is an enumeration of
-type wmem_allocator_type_t (see section 3.1) set by the wmem_allocator_new()
-function. This field must NEVER be written to by the allocator implementation,
-although it may be read. The three function pointers should be fairly obvious;
-alloc and free_all are called with pointers to the private_data field, and
-destroy is called with a pointer to the allocator itself.
+The free_all() function takes the private_data pointer and should free all the
+memory currently allocated in the pool. Note that this is not necessarilly
+exactly the same as calling free() on all the allocated blocks - free_all() is
+allowed to do additional cleanup or to make use of optimizations not available
+when freeing one block at a time.
+
+The gc() function takes the private_data pointer and should do whatever it can
+to reduce excess memory usage in the dissector by returning unused blocks to
+the OS, optimizing internal data structures, etc.
+
+The destroy() function does NOT take the private_data pointer - it instead takes
+a pointer to the allocator structure as a whole, since that structure may also
+need freeing. This function can assume that free_all() has been called
+immediately before it (though it can make no assumptions about whether or not
+gc() has ever been called).
4.2 Pool-Agnostic API
diff --git a/epan/wmem/wmem_allocator.h b/epan/wmem/wmem_allocator.h
index 7ec2d46b92..ded017a979 100644
--- a/epan/wmem/wmem_allocator.h
+++ b/epan/wmem/wmem_allocator.h
@@ -34,13 +34,22 @@ extern "C" {
enum _wmem_allocator_type_t;
+/* See section "4. Internal Design" of doc/README.wmem for details
+ * on this structure */
struct _wmem_allocator_t {
+ /* Implementation details */
+ void *private_data;
+ enum _wmem_allocator_type_t type;
+
+ /* Consumer functions */
void *(*alloc)(void *private_data, const size_t size);
+ void *(*realloc)(void *private_data, void *ptr, const size_t size);
+ void (*free)(void *private_data, void *ptr);
+
+ /* Producer/Manager functions */
void (*free_all)(void *private_data);
+ void (*gc)(void *private_data);
void (*destroy)(struct _wmem_allocator_t *allocator);
-
- void *private_data;
- enum _wmem_allocator_type_t type;
};
#ifdef __cplusplus
diff --git a/epan/wmem/wmem_allocator_block.c b/epan/wmem/wmem_allocator_block.c
index b2f9b520b4..887bb3ae60 100644
--- a/epan/wmem/wmem_allocator_block.c
+++ b/epan/wmem/wmem_allocator_block.c
@@ -194,13 +194,17 @@ wmem_block_allocator_new(void)
allocator->destroy = &wmem_block_allocator_destroy;
allocator->private_data = (void*) block_allocator;
+ /* TODO */
+ allocator->realloc = NULL;
+ allocator->free = NULL;
+ allocator->gc = NULL;
+
block_allocator->free_list = NULL;
block_allocator->full_list = NULL;
return allocator;
}
-
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/wmem/wmem_allocator_simple.c b/epan/wmem/wmem_allocator_simple.c
index c5d9f25d47..86bd3565d8 100644
--- a/epan/wmem/wmem_allocator_simple.c
+++ b/epan/wmem/wmem_allocator_simple.c
@@ -89,12 +89,16 @@ wmem_simple_allocator_new(void)
allocator->destroy = &wmem_simple_allocator_destroy;
allocator->private_data = (void*) simple_allocator;
+ /* TODO */
+ allocator->realloc = NULL;
+ allocator->free = NULL;
+ allocator->gc = NULL;
+
simple_allocator->block_list = NULL;
return allocator;
}
-
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/wmem/wmem_allocator_strict.c b/epan/wmem/wmem_allocator_strict.c
index dff214d412..5955d41c47 100644
--- a/epan/wmem/wmem_allocator_strict.c
+++ b/epan/wmem/wmem_allocator_strict.c
@@ -160,12 +160,16 @@ wmem_strict_allocator_new(void)
allocator->destroy = &wmem_strict_allocator_destroy;
allocator->private_data = (void*) strict_allocator;
+ /* TODO */
+ allocator->realloc = NULL;
+ allocator->free = NULL;
+ allocator->gc = NULL;
+
strict_allocator->block_list = NULL;
return allocator;
}
-
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*