/src/open5gs/lib/core/ogs-memory.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com> |
3 | | * |
4 | | * This file is part of Open5GS. |
5 | | * |
6 | | * This program is free software: you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Affero General Public License as published by |
8 | | * the Free Software Foundation, either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | #include "ogs-core.h" |
21 | | |
22 | | #undef OGS_LOG_DOMAIN |
23 | 0 | #define OGS_LOG_DOMAIN __ogs_mem_domain |
24 | | |
25 | | /***************************************** |
26 | | * Memory Pool - Use talloc library |
27 | | *****************************************/ |
28 | | |
29 | | void *__ogs_talloc_core; |
30 | | |
31 | | static ogs_thread_mutex_t mutex; |
32 | | |
33 | | void ogs_mem_init(void) |
34 | 1 | { |
35 | 1 | ogs_thread_mutex_init(&mutex); |
36 | | |
37 | 1 | talloc_enable_null_tracking(); |
38 | | |
39 | 1 | #define TALLOC_MEMSIZE 1 |
40 | 1 | __ogs_talloc_core = talloc_named_const(NULL, TALLOC_MEMSIZE, "core"); |
41 | 1 | } |
42 | | |
43 | | void ogs_mem_final(void) |
44 | 0 | { |
45 | 0 | if (talloc_total_size(__ogs_talloc_core) != TALLOC_MEMSIZE) |
46 | 0 | talloc_report_full(__ogs_talloc_core, stderr); |
47 | |
|
48 | 0 | talloc_free(__ogs_talloc_core); |
49 | |
|
50 | 0 | ogs_thread_mutex_destroy(&mutex); |
51 | 0 | } |
52 | | |
53 | | void *ogs_mem_get_mutex(void) |
54 | 0 | { |
55 | 0 | return &mutex; |
56 | 0 | } |
57 | | |
58 | | void *ogs_talloc_size(const void *ctx, size_t size, const char *name) |
59 | 0 | { |
60 | 0 | void *ptr = NULL; |
61 | |
|
62 | 0 | ogs_thread_mutex_lock(&mutex); |
63 | |
|
64 | 0 | ptr = talloc_named_const(ctx, size, name); |
65 | 0 | ogs_expect(ptr); |
66 | |
|
67 | 0 | ogs_thread_mutex_unlock(&mutex); |
68 | |
|
69 | 0 | return ptr; |
70 | 0 | } |
71 | | |
72 | | void *ogs_talloc_zero_size(const void *ctx, size_t size, const char *name) |
73 | 468 | { |
74 | 468 | void *ptr = NULL; |
75 | | |
76 | 468 | ogs_thread_mutex_lock(&mutex); |
77 | | |
78 | 468 | ptr = _talloc_zero(ctx, size, name); |
79 | 468 | ogs_expect(ptr); |
80 | | |
81 | 468 | ogs_thread_mutex_unlock(&mutex); |
82 | | |
83 | 468 | return ptr; |
84 | 468 | } |
85 | | |
86 | | void *ogs_talloc_realloc_size( |
87 | | const void *context, void *oldptr, size_t size, const char *name) |
88 | 0 | { |
89 | 0 | void *ptr = NULL; |
90 | |
|
91 | 0 | ogs_thread_mutex_lock(&mutex); |
92 | |
|
93 | 0 | ptr = _talloc_realloc(context, oldptr, size, name); |
94 | 0 | ogs_expect(ptr); |
95 | |
|
96 | 0 | ogs_thread_mutex_unlock(&mutex); |
97 | |
|
98 | 0 | return ptr; |
99 | 0 | } |
100 | | |
101 | | int ogs_talloc_free(void *ptr, const char *location) |
102 | 468 | { |
103 | 468 | int ret; |
104 | | |
105 | 468 | ogs_thread_mutex_lock(&mutex); |
106 | | |
107 | 468 | ret = _talloc_free(ptr, location); |
108 | | |
109 | 468 | ogs_thread_mutex_unlock(&mutex); |
110 | | |
111 | 468 | return ret; |
112 | 468 | } |
113 | | |
114 | | /***************************************** |
115 | | * Memory Pool - Use pkbuf library |
116 | | *****************************************/ |
117 | | |
118 | | void *ogs_malloc_debug(size_t size, const char *file_line) |
119 | 0 | { |
120 | 0 | size_t headroom = 0; |
121 | 0 | ogs_pkbuf_t *pkbuf = NULL; |
122 | |
|
123 | 0 | ogs_assert(size); |
124 | | |
125 | 0 | headroom = sizeof(ogs_pkbuf_t *); |
126 | 0 | pkbuf = ogs_pkbuf_alloc_debug(NULL, headroom + size, file_line); |
127 | 0 | if (!pkbuf) { |
128 | 0 | ogs_error("ogs_pkbuf_alloc_debug[headroom:%d, size:%d] failed", |
129 | 0 | (int)headroom, (int)size); |
130 | 0 | return NULL; |
131 | 0 | } |
132 | | |
133 | 0 | ogs_pkbuf_reserve(pkbuf, headroom); |
134 | 0 | memcpy(pkbuf->head, &pkbuf, headroom); |
135 | 0 | ogs_pkbuf_put(pkbuf, size); |
136 | |
|
137 | 0 | return pkbuf->data; |
138 | 0 | } |
139 | | |
140 | | int ogs_free_debug(void *ptr) |
141 | 0 | { |
142 | 0 | size_t headroom; |
143 | 0 | ogs_pkbuf_t *pkbuf = NULL; |
144 | |
|
145 | 0 | if (!ptr) |
146 | 0 | return OGS_ERROR; |
147 | | |
148 | 0 | headroom = sizeof(ogs_pkbuf_t *); |
149 | 0 | memcpy(&pkbuf, (unsigned char*)ptr - headroom, headroom); |
150 | 0 | ogs_assert(pkbuf); |
151 | | |
152 | 0 | ogs_pkbuf_free(pkbuf); |
153 | |
|
154 | 0 | return OGS_OK; |
155 | 0 | } |
156 | | |
157 | | void *ogs_calloc_debug(size_t nmemb, size_t size, const char *file_line) |
158 | 0 | { |
159 | 0 | void *ptr = NULL; |
160 | |
|
161 | 0 | ptr = ogs_malloc_debug(nmemb * size, file_line); |
162 | 0 | if (!ptr) { |
163 | 0 | ogs_error("ogs_malloc_debug[nmemb:%d, size:%d] failed", |
164 | 0 | (int)nmemb, (int)size); |
165 | 0 | return NULL; |
166 | 0 | } |
167 | | |
168 | 0 | memset(ptr, 0, nmemb * size); |
169 | 0 | return ptr; |
170 | 0 | } |
171 | | |
172 | | void *ogs_realloc_debug(void *ptr, size_t size, const char *file_line) |
173 | 0 | { |
174 | 0 | size_t headroom = 0; |
175 | 0 | ogs_pkbuf_t *pkbuf = NULL; |
176 | 0 | ogs_cluster_t *cluster = NULL; |
177 | |
|
178 | 0 | if (!ptr) |
179 | 0 | return ogs_malloc(size); |
180 | | |
181 | 0 | headroom = sizeof(ogs_pkbuf_t *); |
182 | |
|
183 | 0 | memcpy(&pkbuf, (unsigned char*)ptr - headroom, headroom); |
184 | |
|
185 | 0 | if (!pkbuf) { |
186 | 0 | ogs_error("Cannot get pkbuf from ptr[%p], headroom[%d]", |
187 | 0 | ptr, (int)headroom); |
188 | 0 | return NULL; |
189 | 0 | } |
190 | | |
191 | 0 | cluster = pkbuf->cluster; |
192 | 0 | if (!cluster) { |
193 | 0 | ogs_error("No cluster"); |
194 | 0 | return NULL; |
195 | 0 | } |
196 | | |
197 | 0 | if (!size) { |
198 | 0 | ogs_pkbuf_free(pkbuf); |
199 | 0 | return NULL; |
200 | 0 | } |
201 | | |
202 | 0 | if (size > (cluster->size - headroom)) { |
203 | 0 | void *new = NULL; |
204 | |
|
205 | 0 | new = ogs_malloc_debug(size, file_line); |
206 | 0 | if (!new) { |
207 | 0 | ogs_error("ogs_malloc_debug[%d] failed", (int)size); |
208 | 0 | return NULL; |
209 | 0 | } |
210 | | |
211 | 0 | memcpy(new, ptr, pkbuf->len); |
212 | |
|
213 | 0 | ogs_pkbuf_free(pkbuf); |
214 | 0 | return new; |
215 | 0 | } else { |
216 | 0 | pkbuf->tail = pkbuf->data + size; |
217 | 0 | pkbuf->len = size; |
218 | 0 | return ptr; |
219 | 0 | } |
220 | 0 | } |