TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags
[wireshark-sm.git] / wsutil / wmem / wmem_core.c
blob6a589db1d30da6015fda24a90d985822a7d3e5ac
1 /* wmem_core.c
2 * 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 #include <stdlib.h>
13 #include <string.h>
14 #include <glib.h>
16 #include "wmem-int.h"
17 #include "wmem_core.h"
18 #include "wmem_map_int.h"
19 #include "wmem_user_cb_int.h"
20 #include "wmem_allocator.h"
21 #include "wmem_allocator_simple.h"
22 #include "wmem_allocator_block.h"
23 #include "wmem_allocator_block_fast.h"
24 #include "wmem_allocator_strict.h"
26 /* Set according to the WIRESHARK_DEBUG_WMEM_OVERRIDE environment variable in
27 * wmem_init. Should not be set again. */
28 static bool do_override;
29 static wmem_allocator_type_t override_type;
31 void *
32 wmem_alloc(wmem_allocator_t *allocator, const size_t size)
34 if (allocator == NULL) {
35 return g_malloc(size);
38 ws_assert(allocator->in_scope);
40 if (size == 0) {
41 return NULL;
44 return allocator->walloc(allocator->private_data, size);
47 void *
48 wmem_alloc0(wmem_allocator_t *allocator, const size_t size)
50 void *buf;
52 buf = wmem_alloc(allocator, size);
54 if (buf) {
55 memset(buf, 0, size);
58 return buf;
61 void
62 wmem_free(wmem_allocator_t *allocator, void *ptr)
64 if (allocator == NULL) {
65 g_free(ptr);
66 return;
69 ws_assert(allocator->in_scope);
71 if (ptr == NULL) {
72 return;
75 allocator->wfree(allocator->private_data, ptr);
78 void *
79 wmem_realloc(wmem_allocator_t *allocator, void *ptr, const size_t size)
81 if (allocator == NULL) {
82 return g_realloc(ptr, size);
85 if (ptr == NULL) {
86 return wmem_alloc(allocator, size);
89 if (size == 0) {
90 wmem_free(allocator, ptr);
91 return NULL;
94 ws_assert(allocator->in_scope);
96 return allocator->wrealloc(allocator->private_data, ptr, size);
99 static void
100 wmem_free_all_real(wmem_allocator_t *allocator, bool final)
102 wmem_call_callbacks(allocator,
103 final ? WMEM_CB_DESTROY_EVENT : WMEM_CB_FREE_EVENT);
104 allocator->free_all(allocator->private_data);
107 void
108 wmem_free_all(wmem_allocator_t *allocator)
110 wmem_free_all_real(allocator, false);
113 void
114 wmem_gc(wmem_allocator_t *allocator)
116 allocator->gc(allocator->private_data);
119 void
120 wmem_destroy_allocator(wmem_allocator_t *allocator)
123 wmem_free_all_real(allocator, true);
124 allocator->cleanup(allocator->private_data);
125 wmem_free(NULL, allocator);
128 wmem_allocator_t *
129 wmem_allocator_new(const wmem_allocator_type_t type)
131 wmem_allocator_t *allocator;
132 wmem_allocator_type_t real_type;
134 if (do_override) {
135 real_type = override_type;
137 else {
138 real_type = type;
141 allocator = wmem_new(NULL, wmem_allocator_t);
142 allocator->type = real_type;
143 allocator->callbacks = NULL;
144 allocator->in_scope = true;
146 switch (real_type) {
147 case WMEM_ALLOCATOR_SIMPLE:
148 wmem_simple_allocator_init(allocator);
149 break;
150 case WMEM_ALLOCATOR_BLOCK:
151 wmem_block_allocator_init(allocator);
152 break;
153 case WMEM_ALLOCATOR_BLOCK_FAST:
154 wmem_block_fast_allocator_init(allocator);
155 break;
156 case WMEM_ALLOCATOR_STRICT:
157 wmem_strict_allocator_init(allocator);
158 break;
159 default:
160 g_assert_not_reached();
161 break;
164 return allocator;
167 void
168 wmem_init(void)
170 const char *override_env;
172 /* Our valgrind script uses this environment variable to override the
173 * usual allocator choice so that everything goes through system-level
174 * allocations that it understands and can track. Otherwise it will get
175 * confused by the block allocator etc. */
176 override_env = getenv("WIRESHARK_DEBUG_WMEM_OVERRIDE");
178 if (override_env == NULL) {
179 do_override = false;
181 else {
182 do_override = true;
183 if (strncmp(override_env, "simple", strlen("simple")) == 0) {
184 override_type = WMEM_ALLOCATOR_SIMPLE;
186 else if (strncmp(override_env, "block", strlen("block")) == 0) {
187 override_type = WMEM_ALLOCATOR_BLOCK;
189 else if (strncmp(override_env, "strict", strlen("strict")) == 0) {
190 override_type = WMEM_ALLOCATOR_STRICT;
192 else if (strncmp(override_env, "block_fast", strlen("block_fast")) == 0) {
193 override_type = WMEM_ALLOCATOR_BLOCK_FAST;
195 else {
196 g_warning("Unrecognized wmem override");
197 do_override = false;
201 wmem_init_hashing();
204 void
205 wmem_cleanup(void)
209 void
210 wmem_enter_scope(wmem_allocator_t *allocator)
212 allocator->in_scope = true;
215 void
216 wmem_leave_scope(wmem_allocator_t *allocator)
218 wmem_free_all(allocator);
219 allocator->in_scope = false;
222 bool
223 wmem_in_scope(wmem_allocator_t *allocator)
225 return allocator->in_scope;
230 * Editor modelines - https://www.wireshark.org/tools/modelines.html
232 * Local variables:
233 * c-basic-offset: 4
234 * tab-width: 8
235 * indent-tabs-mode: nil
236 * End:
238 * vi: set shiftwidth=4 tabstop=8 expandtab:
239 * :indentSize=4:tabSize=8:noTabs=true: