/src/wireshark/wsutil/wmem/wmem_allocator_simple.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* wmem_allocator_simple.c |
2 | | * Wireshark Memory Manager Simple Allocator |
3 | | * Copyright 2012, Evan Huus <eapache@gmail.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | #include <string.h> |
15 | | |
16 | | #include <glib.h> |
17 | | |
18 | | #include "wmem_core.h" |
19 | | #include "wmem_allocator.h" |
20 | | #include "wmem_allocator_simple.h" |
21 | | |
22 | 366 | #define DEFAULT_ALLOCS 8192 |
23 | | |
24 | | typedef struct _wmem_simple_allocator_t { |
25 | | int size; |
26 | | int count; |
27 | | void **ptrs; |
28 | | } wmem_simple_allocator_t; |
29 | | |
30 | | static void * |
31 | | wmem_simple_alloc(void *private_data, const size_t size) |
32 | 194M | { |
33 | 194M | wmem_simple_allocator_t *allocator; |
34 | | |
35 | 194M | allocator = (wmem_simple_allocator_t*) private_data; |
36 | | |
37 | 194M | if (G_UNLIKELY(allocator->count == allocator->size)) { |
38 | 96 | allocator->size *= 2; |
39 | 96 | allocator->ptrs = (void**)wmem_realloc(NULL, allocator->ptrs, |
40 | 96 | sizeof(void*) * allocator->size); |
41 | 96 | } |
42 | | |
43 | 194M | return allocator->ptrs[allocator->count++] = wmem_alloc(NULL, size); |
44 | 194M | } |
45 | | |
46 | | static void |
47 | | wmem_simple_free(void *private_data, void *ptr) |
48 | 1.78M | { |
49 | 1.78M | int i; |
50 | 1.78M | wmem_simple_allocator_t *allocator; |
51 | | |
52 | 1.78M | allocator = (wmem_simple_allocator_t*) private_data; |
53 | | |
54 | 1.78M | wmem_free(NULL, ptr); |
55 | 1.78M | allocator->count--; |
56 | | |
57 | 32.2M | for (i=allocator->count; i>=0; i--) { |
58 | 32.2M | if (ptr == allocator->ptrs[i]) { |
59 | 1.78M | if (i < allocator->count) { |
60 | 1.34M | allocator->ptrs[i] = allocator->ptrs[allocator->count]; |
61 | 1.34M | } |
62 | 1.78M | return; |
63 | 1.78M | } |
64 | 32.2M | } |
65 | | |
66 | 0 | g_assert_not_reached(); |
67 | 0 | } |
68 | | |
69 | | static void * |
70 | | wmem_simple_realloc(void *private_data, void *ptr, const size_t size) |
71 | 1.22M | { |
72 | 1.22M | int i; |
73 | 1.22M | wmem_simple_allocator_t *allocator; |
74 | | |
75 | 1.22M | allocator = (wmem_simple_allocator_t*) private_data; |
76 | | |
77 | 4.08M | for (i=allocator->count-1; i>=0; i--) { |
78 | 4.08M | if (ptr == allocator->ptrs[i]) { |
79 | 1.22M | return allocator->ptrs[i] = wmem_realloc(NULL, allocator->ptrs[i], size); |
80 | 1.22M | } |
81 | 4.08M | } |
82 | | |
83 | 0 | g_assert_not_reached(); |
84 | | /* not reached */ |
85 | 0 | return NULL; |
86 | 0 | } |
87 | | |
88 | | static void |
89 | | wmem_simple_free_all(void *private_data) |
90 | 208k | { |
91 | 208k | wmem_simple_allocator_t *allocator; |
92 | 208k | int i; |
93 | | |
94 | 208k | allocator = (wmem_simple_allocator_t*) private_data; |
95 | | |
96 | 191M | for (i = 0; i<allocator->count; i++) { |
97 | 191M | wmem_free(NULL, allocator->ptrs[i]); |
98 | 191M | } |
99 | 208k | allocator->count = 0; |
100 | 208k | } |
101 | | |
102 | | static void |
103 | | wmem_simple_gc(void *private_data _U_) |
104 | 0 | { |
105 | | /* In this simple allocator, there is nothing to garbage-collect */ |
106 | 0 | } |
107 | | |
108 | | static void |
109 | | wmem_simple_allocator_cleanup(void *private_data) |
110 | 268 | { |
111 | 268 | wmem_simple_allocator_t *allocator; |
112 | | |
113 | 268 | allocator = (wmem_simple_allocator_t*) private_data; |
114 | | |
115 | 268 | wmem_free(NULL, allocator->ptrs); |
116 | 268 | wmem_free(NULL, allocator); |
117 | 268 | } |
118 | | |
119 | | void |
120 | | wmem_simple_allocator_init(wmem_allocator_t *allocator) |
121 | 366 | { |
122 | 366 | wmem_simple_allocator_t *simple_allocator; |
123 | | |
124 | 366 | simple_allocator = wmem_new(NULL, wmem_simple_allocator_t); |
125 | | |
126 | 366 | allocator->walloc = &wmem_simple_alloc; |
127 | 366 | allocator->wrealloc = &wmem_simple_realloc; |
128 | 366 | allocator->wfree = &wmem_simple_free; |
129 | | |
130 | 366 | allocator->free_all = &wmem_simple_free_all; |
131 | 366 | allocator->gc = &wmem_simple_gc; |
132 | 366 | allocator->cleanup = &wmem_simple_allocator_cleanup; |
133 | | |
134 | 366 | allocator->private_data = (void*) simple_allocator; |
135 | | |
136 | 366 | simple_allocator->count = 0; |
137 | 366 | simple_allocator->size = DEFAULT_ALLOCS; |
138 | 366 | simple_allocator->ptrs = wmem_alloc_array(NULL, void*, DEFAULT_ALLOCS); |
139 | 366 | } |
140 | | |
141 | | /* |
142 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
143 | | * |
144 | | * Local variables: |
145 | | * c-basic-offset: 4 |
146 | | * tab-width: 8 |
147 | | * indent-tabs-mode: nil |
148 | | * End: |
149 | | * |
150 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
151 | | * :indentSize=4:tabSize=8:noTabs=true: |
152 | | */ |