]> git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_utils_memory.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / pceplib / pcep_utils_memory.c
1 /*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "pcep_utils_logging.h"
31 #include "pcep_utils_memory.h"
32
33 /* Set default values for memory function pointers */
34 static pceplib_malloc_func mfunc = NULL;
35 static pceplib_calloc_func cfunc = NULL;
36 static pceplib_realloc_func rfunc = NULL;
37 static pceplib_strdup_func sfunc = NULL;
38 static pceplib_free_func ffunc = NULL;
39
40 /* Internal memory types */
41 struct pceplib_memory_type pceplib_infra_mt = {
42 .memory_type_name = "PCEPlib Infrastructure memory",
43 .total_bytes_allocated = 0,
44 .num_allocates = 0,
45 .total_bytes_freed = 0,
46 .num_frees = 0};
47 struct pceplib_memory_type pceplib_messages_mt = {
48 .memory_type_name = "PCEPlib Messages memory",
49 .total_bytes_allocated = 0,
50 .num_allocates = 0,
51 .total_bytes_freed = 0,
52 .num_frees = 0};
53
54 /* The memory type pointers default to the internal memory types */
55 void *PCEPLIB_INFRA = &pceplib_infra_mt;
56 void *PCEPLIB_MESSAGES = &pceplib_messages_mt;
57
58 /* Initialize memory function pointers and memory type pointers */
59 bool pceplib_memory_initialize(void *pceplib_infra_mt,
60 void *pceplib_messages_mt,
61 pceplib_malloc_func mf, pceplib_calloc_func cf,
62 pceplib_realloc_func rf, pceplib_strdup_func sf,
63 pceplib_free_func ff)
64 {
65 PCEPLIB_INFRA = (pceplib_infra_mt ? pceplib_infra_mt : PCEPLIB_INFRA);
66 PCEPLIB_MESSAGES =
67 (pceplib_messages_mt ? pceplib_messages_mt : PCEPLIB_MESSAGES);
68
69 mfunc = (mf ? mf : mfunc);
70 cfunc = (cf ? cf : cfunc);
71 rfunc = (rf ? rf : rfunc);
72 sfunc = (sf ? sf : sfunc);
73 ffunc = (ff ? ff : ffunc);
74
75 return true;
76 }
77
78 void pceplib_memory_reset(void)
79 {
80 pceplib_infra_mt.total_bytes_allocated = 0;
81 pceplib_infra_mt.num_allocates = 0;
82 pceplib_infra_mt.total_bytes_freed = 0;
83 pceplib_infra_mt.num_frees = 0;
84
85 pceplib_messages_mt.total_bytes_allocated = 0;
86 pceplib_messages_mt.num_allocates = 0;
87 pceplib_messages_mt.total_bytes_freed = 0;
88 pceplib_messages_mt.num_frees = 0;
89 }
90
91 void pceplib_memory_dump(void)
92 {
93 if (PCEPLIB_INFRA) {
94 pcep_log(
95 LOG_INFO,
96 "%s: Memory Type [%s] Total [allocs, alloc bytes, frees] [%d, %d, %d]",
97 __func__,
98 ((struct pceplib_memory_type *)PCEPLIB_INFRA)
99 ->memory_type_name,
100 ((struct pceplib_memory_type *)PCEPLIB_INFRA)
101 ->num_allocates,
102 ((struct pceplib_memory_type *)PCEPLIB_INFRA)
103 ->total_bytes_allocated,
104 ((struct pceplib_memory_type *)PCEPLIB_INFRA)
105 ->num_frees);
106 }
107
108 if (PCEPLIB_MESSAGES) {
109 pcep_log(
110 LOG_INFO,
111 "%s: Memory Type [%s] Total [allocs, alloc bytes, frees] [%d, %d, %d]",
112 __func__,
113 ((struct pceplib_memory_type *)PCEPLIB_MESSAGES)
114 ->memory_type_name,
115 ((struct pceplib_memory_type *)PCEPLIB_MESSAGES)
116 ->num_allocates,
117 ((struct pceplib_memory_type *)PCEPLIB_MESSAGES)
118 ->total_bytes_allocated,
119 ((struct pceplib_memory_type *)PCEPLIB_MESSAGES)
120 ->num_frees);
121 }
122 }
123
124 /* PCEPlib memory functions:
125 * They either call the supplied function pointers, or use the internal
126 * implementations, which just increment simple counters and call the
127 * C stdlib memory implementations. */
128
129 void *pceplib_malloc(void *mem_type, size_t size)
130 {
131 if (mfunc == NULL) {
132 if (mem_type != NULL) {
133 ((struct pceplib_memory_type *)mem_type)
134 ->total_bytes_allocated += size;
135 ((struct pceplib_memory_type *)mem_type)
136 ->num_allocates++;
137 }
138
139 return malloc(size);
140 } else {
141 return mfunc(mem_type, size);
142 }
143 }
144
145 void *pceplib_calloc(void *mem_type, size_t size)
146 {
147 if (cfunc == NULL) {
148 if (mem_type != NULL) {
149 ((struct pceplib_memory_type *)mem_type)
150 ->total_bytes_allocated += size;
151 ((struct pceplib_memory_type *)mem_type)
152 ->num_allocates++;
153 }
154
155 return calloc(1, size);
156 } else {
157 return cfunc(mem_type, size);
158 }
159 }
160
161 void *pceplib_realloc(void *mem_type, void *ptr, size_t size)
162 {
163 if (rfunc == NULL) {
164 if (mem_type != NULL) {
165 /* TODO should add previous allocated bytes to
166 * total_bytes_freed */
167 ((struct pceplib_memory_type *)mem_type)
168 ->total_bytes_allocated += size;
169 ((struct pceplib_memory_type *)mem_type)
170 ->num_allocates++;
171 }
172
173 return realloc(ptr, size);
174 } else {
175 return rfunc(mem_type, ptr, size);
176 }
177 }
178
179 void *pceplib_strdup(void *mem_type, const char *str)
180 {
181 if (sfunc == NULL) {
182 if (mem_type != NULL) {
183 ((struct pceplib_memory_type *)mem_type)
184 ->total_bytes_allocated += strlen(str);
185 ((struct pceplib_memory_type *)mem_type)
186 ->num_allocates++;
187 }
188
189 return strdup(str);
190 } else {
191 return sfunc(mem_type, str);
192 }
193 }
194
195 void pceplib_free(void *mem_type, void *ptr)
196 {
197 if (ffunc == NULL) {
198 if (mem_type != NULL) {
199 /* TODO in order to increment total_bytes_freed, we need
200 * to keep track of the bytes allocated per pointer.
201 * Currently not implemented. */
202 ((struct pceplib_memory_type *)mem_type)->num_frees++;
203 if (((struct pceplib_memory_type *)mem_type)
204 ->num_allocates
205 < ((struct pceplib_memory_type *)mem_type)
206 ->num_frees) {
207 pcep_log(
208 LOG_ERR,
209 "%s: pceplib_free MT N_Alloc < N_Free: MemType [%s] NumAllocates [%d] NumFrees [%d]",
210 __func__,
211 ((struct pceplib_memory_type *)mem_type)
212 ->memory_type_name,
213 ((struct pceplib_memory_type *)mem_type)
214 ->num_allocates,
215 ((struct pceplib_memory_type *)mem_type)
216 ->num_frees);
217 }
218 }
219
220 return free(ptr);
221 } else {
222 return ffunc(mem_type, ptr);
223 }
224 }