2 * This file is part of the PCEPlib, a PCEP protocol library.
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
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.
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.
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/>.
19 * Author : Brady Johnson <brady@voltanet.io>
30 #include "pcep_utils_logging.h"
31 #include "pcep_utils_memory.h"
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
;
40 /* Internal memory types */
41 struct pceplib_memory_type pceplib_infra_mt
= {
42 .memory_type_name
= "PCEPlib Infrastructure memory",
43 .total_bytes_allocated
= 0,
45 .total_bytes_freed
= 0,
47 struct pceplib_memory_type pceplib_messages_mt
= {
48 .memory_type_name
= "PCEPlib Messages memory",
49 .total_bytes_allocated
= 0,
51 .total_bytes_freed
= 0,
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
;
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
,
65 PCEPLIB_INFRA
= (pceplib_infra_mt
? pceplib_infra_mt
: PCEPLIB_INFRA
);
67 (pceplib_messages_mt
? pceplib_messages_mt
: PCEPLIB_MESSAGES
);
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
);
78 void pceplib_memory_reset()
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;
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;
91 void pceplib_memory_dump()
96 "%s: Memory Type [%s] Total [allocs, alloc bytes, frees] [%d, %d, %d]",
98 ((struct pceplib_memory_type
*)PCEPLIB_INFRA
)
100 ((struct pceplib_memory_type
*)PCEPLIB_INFRA
)
102 ((struct pceplib_memory_type
*)PCEPLIB_INFRA
)
103 ->total_bytes_allocated
,
104 ((struct pceplib_memory_type
*)PCEPLIB_INFRA
)
108 if (PCEPLIB_MESSAGES
) {
111 "%s: Memory Type [%s] Total [allocs, alloc bytes, frees] [%d, %d, %d]",
113 ((struct pceplib_memory_type
*)PCEPLIB_MESSAGES
)
115 ((struct pceplib_memory_type
*)PCEPLIB_MESSAGES
)
117 ((struct pceplib_memory_type
*)PCEPLIB_MESSAGES
)
118 ->total_bytes_allocated
,
119 ((struct pceplib_memory_type
*)PCEPLIB_MESSAGES
)
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. */
129 void *pceplib_malloc(void *mem_type
, size_t size
)
132 if (mem_type
!= NULL
) {
133 ((struct pceplib_memory_type
*)mem_type
)
134 ->total_bytes_allocated
+= size
;
135 ((struct pceplib_memory_type
*)mem_type
)
141 return mfunc(mem_type
, size
);
145 void *pceplib_calloc(void *mem_type
, size_t size
)
148 if (mem_type
!= NULL
) {
149 ((struct pceplib_memory_type
*)mem_type
)
150 ->total_bytes_allocated
+= size
;
151 ((struct pceplib_memory_type
*)mem_type
)
155 return calloc(1, size
);
157 return cfunc(mem_type
, size
);
161 void *pceplib_realloc(void *mem_type
, void *ptr
, size_t size
)
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
)
173 return realloc(ptr
, size
);
175 return rfunc(mem_type
, ptr
, size
);
179 void *pceplib_strdup(void *mem_type
, const char *str
)
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
)
191 return sfunc(mem_type
, str
);
195 void pceplib_free(void *mem_type
, void *ptr
)
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
)
205 < ((struct pceplib_memory_type
*)mem_type
)
209 "%s: pceplib_free MT N_Alloc < N_Free: MemType [%s] NumAllocates [%d] NumFrees [%d]",
211 ((struct pceplib_memory_type
*)mem_type
)
213 ((struct pceplib_memory_type
*)mem_type
)
215 ((struct pceplib_memory_type
*)mem_type
)
222 return ffunc(mem_type
, ptr
);