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