Coverage Report

Created: 2023-09-25 07:12

/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
}