2 * Definitions for the Wireshark Memory Manager Core
3 * Copyright 2012, Evan Huus <eapache@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #ifndef __WMEM_CORE_H__
13 #define __WMEM_CORE_H__
19 #include <ws_symbol_export.h>
20 #include <ws_attributes.h>
21 #include <ws_posix_compat.h>
25 #endif /* __cplusplus */
27 /** @defgroup wmem Wireshark Memory Manager
29 * Wmem is a memory management framework for Wireshark that makes it simple to
30 * write dissectors (and other 'user-space' code) that doesn't leak memory. The
31 * core module provides basic functions like malloc, realloc and free, but
32 * many other functions are available (see the "Modules" list at the top of
33 * the generated doxygen HTML).
35 * Any wmem functions which allocate memory are guaranteed to either succeed or
36 * abort the program. However, they *can* still legally return NULL when the
37 * amount of requested memory is zero.
42 struct _wmem_allocator_t
;
43 /** A public opaque type representing one wmem allocation pool. */
44 typedef struct _wmem_allocator_t wmem_allocator_t
;
46 /** An enumeration of the different types of available allocators. */
47 typedef enum _wmem_allocator_type_t
{
48 WMEM_ALLOCATOR_SIMPLE
, /**< A trivial allocator that mallocs requested
49 memory and tracks allocations via a hash table. As simple as
50 possible, intended more as a demo than for practical usage. Also
51 has the benefit of being friendly to tools like valgrind. */
52 WMEM_ALLOCATOR_BLOCK
, /**< A block allocator that grabs large chunks of
53 memory at a time (8 MB currently) and serves allocations out of
54 those chunks. Designed for efficiency, especially in the
55 free_all operation. */
56 WMEM_ALLOCATOR_STRICT
, /**< An allocator that does its best to find invalid
57 memory usage via things like canaries and scrubbing freed
58 memory. Valgrind is the better choice on platforms that support
60 WMEM_ALLOCATOR_BLOCK_FAST
/**< A block allocator like WMEM_ALLOCATOR_BLOCK
61 but even faster by tracking absolutely minimal metadata and
62 making 'free' a no-op. Useful only for very short-lived scopes
63 where there's no reason to free individual allocations because
64 the next free_all is always just around the corner. */
65 } wmem_allocator_type_t
;
67 /** Allocate the requested amount of memory in the given pool.
69 * @param allocator The allocator object to use to allocate the memory.
70 * @param size The amount of memory to allocate.
71 * @return A void pointer to the newly allocated memory.
75 wmem_alloc(wmem_allocator_t
*allocator
, const size_t size
)
79 /** Allocate memory sufficient to hold one object of the given type.
81 * @param allocator The allocator object to use to allocate the memory.
82 * @param type The type that the newly allocated memory will hold.
83 * @return A void pointer to the newly allocated memory.
85 #define wmem_new(allocator, type) \
86 ((type*)wmem_alloc((allocator), sizeof(type)))
89 * Overflow-safe multiplication of the size of a type by a number of
90 * items of that type, returning 0 if the result would overflow (or
91 * if the number of elements is negative), and the product otherwise.
93 #define wmem_safe_mult_type_size(type, num) \
94 ((((num) <= 0) || ((size_t)sizeof(type) > (G_MAXSSIZE / (size_t)(num)))) ? 0 : (sizeof(type) * (num)))
96 /** Allocate memory sufficient to hold n objects of the given type.
98 * @param allocator The allocator object to use to allocate the memory.
99 * @param type The type that the newly allocated memory will hold.
100 * @param num The number of objects that the newly allocated memory will hold.
101 * @return A void pointer to the newly allocated memory.
103 #define wmem_alloc_array(allocator, type, num) \
104 ((type*)wmem_alloc((allocator), wmem_safe_mult_type_size(type, (num))))
106 /** Allocate the requested amount of memory in the given pool. Initializes the
107 * allocated memory with zeroes.
109 * @param allocator The allocator object to use to allocate the memory.
110 * @param size The amount of memory to allocate.
111 * @return A void pointer to the newly allocated and zeroed memory.
115 wmem_alloc0(wmem_allocator_t
*allocator
, const size_t size
)
117 G_GNUC_ALLOC_SIZE(2);
119 /** Allocate memory sufficient to hold one object of the given type.
120 * Initializes the allocated memory with zeroes.
122 * @param allocator The allocator object to use to allocate the memory.
123 * @param type The type that the newly allocated memory will hold.
124 * @return A void pointer to the newly allocated and zeroed memory.
126 #define wmem_new0(allocator, type) \
127 ((type*)wmem_alloc0((allocator), sizeof(type)))
129 /** Allocate memory sufficient to hold n objects of the given type.
130 * Initializes the allocated memory with zeroes.
132 * @param allocator The allocator object to use to allocate the memory.
133 * @param type The type that the newly allocated memory will hold.
134 * @param num The number of objects that the newly allocated memory will hold.
135 * @return A void pointer to the newly allocated and zeroed memory.
137 #define wmem_alloc0_array(allocator, type, num) \
138 ((type*)wmem_alloc0((allocator), wmem_safe_mult_type_size(type, (num))))
140 /** Returns the allocated memory to the allocator. This function should only
141 * be called directly by allocators when the allocated block is sufficiently
142 * large that the reduced memory usage is worth the cost of the extra function
143 * call. It's usually easier to just let it get cleaned up when wmem_free_all()
146 * @param allocator The allocator object used to originally allocate the memory.
147 * @param ptr The pointer to the memory block to free. After this function
148 * returns it no longer points to valid memory.
152 wmem_free(wmem_allocator_t
*allocator
, void *ptr
);
154 /** Resizes a block of memory, potentially moving it if resizing it in place
157 * @param allocator The allocator object used to originally allocate the memory.
158 * @param ptr The pointer to the memory block to resize.
159 * @param size The new size for the memory block.
160 * @return The new location of the memory block. If this is different from ptr
161 * then ptr no longer points to valid memory.
165 wmem_realloc(wmem_allocator_t
*allocator
, void *ptr
, const size_t size
)
166 G_GNUC_ALLOC_SIZE(3);
168 /** Frees all the memory allocated in a pool. Depending on the allocator
169 * implementation used this can be significantly cheaper than calling
170 * wmem_free() on all the individual blocks. It also doesn't require you to have
171 * external pointers to those blocks.
173 * @param allocator The allocator to free the memory from.
177 wmem_free_all(wmem_allocator_t
*allocator
);
179 /** Triggers a garbage-collection in the allocator. This does not free any
180 * memory, but it can return unused blocks to the operating system or perform
181 * other optimizations.
183 * @param allocator The allocator in which to trigger the garbage collection.
187 wmem_gc(wmem_allocator_t
*allocator
);
189 /** Destroy the given allocator, freeing all memory allocated in it. Once this
190 * function has been called, no memory allocated with the allocator is valid.
192 * @param allocator The allocator to destroy.
196 wmem_destroy_allocator(wmem_allocator_t
*allocator
);
198 /** Create a new allocator of the given type. The type may be overridden by the
199 * WIRESHARK_DEBUG_WMEM_OVERRIDE environment variable.
201 * @param type The type of allocator to create.
202 * @return The new allocator.
206 wmem_allocator_new(const wmem_allocator_type_t type
);
208 /** Initialize the wmem subsystem. This must be called before any other wmem
209 * function, usually at the very beginning of your program.
215 /** Teardown the wmem subsystem. This must be called after all other wmem
216 * functions, usually at the very end of your program. This function will not
217 * destroy outstanding allocators, you must do that yourself.
225 wmem_enter_scope(wmem_allocator_t
*allocator
);
229 wmem_leave_scope(wmem_allocator_t
*allocator
);
233 wmem_in_scope(wmem_allocator_t
*allocator
);
239 #endif /* __cplusplus */
241 #endif /* __WMEM_CORE_H__ */
244 * Editor modelines - https://www.wireshark.org/tools/modelines.html
249 * indent-tabs-mode: nil
252 * vi: set shiftwidth=4 tabstop=8 expandtab:
253 * :indentSize=4:tabSize=8:noTabs=true: