BRL-CAD
malloc.h
Go to the documentation of this file.
1/* M A L L O C . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2023 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * 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
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20
21#ifndef BU_MALLOC_H
22#define BU_MALLOC_H
23
24#include "common.h"
25#include <stddef.h> /* for size_t */
26
27#include "bu/defines.h"
28#include "bu/magic.h"
29
30__BEGIN_DECLS
31
32/** @addtogroup bu_malloc
33 *
34 * @brief Parallel-protected debugging-enhanced wrapper around system malloc().
35 *
36 * Provides a parallel-safe interface to the system memory allocator
37 * with standardized error checking, optional memory-use logging, and
38 * optional run-time pointer and memory corruption testing.
39 *
40 * The bu_*alloc() routines can't use bu_log() because that uses the
41 * bu_vls() routines which depend on bu_malloc(). So it goes direct
42 * to stderr, semaphore protected.
43 *
44 */
45/** @{ */
46/** @file bu/malloc.h */
47
48BU_EXPORT extern size_t bu_n_malloc;
49BU_EXPORT extern size_t bu_n_realloc;
50BU_EXPORT extern size_t bu_n_free;
51
52
53/**
54 * Compilation constant for a page of memory.
55 *
56 * This is basically intended to be the minimum size for a contiguous
57 * block of virtual memory that hopefully, but not necessarily, aligns
58 * with or is a smaller evenly divisible fraction of the operating
59 * system's virtual memory page size. We could look page size up at
60 * runtime but the primary purpose of this define is to help routines
61 * using static memory buffers for processing pick a fixed array size.
62 */
63#ifndef BU_PAGE_SIZE
64# include <limits.h>
65# if defined(PAGE_SIZE)
66 /* use the system page size if handy */
67# define BU_PAGE_SIZE PAGE_SIZE
68# else
69 /* common enough default */
70# define BU_PAGE_SIZE 4096
71# endif
72#endif /* BU_PAGE_SIZE */
73
74
75/**
76 * This routine only returns on successful allocation. We promise
77 * never to return a NULL pointer; caller doesn't have to check.
78 * Allocation failure results in bu_bomb() being called.
79 */
80BU_EXPORT extern void *bu_malloc(size_t siz,
81 const char *str);
82
83/**
84 * This routine only returns on successful allocation.
85 * We promise never to return a NULL pointer; caller doesn't have to check.
86 * Failure results in bu_bomb() being called.
87 */
88BU_EXPORT extern void *bu_calloc(size_t nelem,
89 size_t elsize,
90 const char *str);
91
92/**
93 * Free dynamically allocated memory.
94 *
95 * This routine releases memory allocated by bu_malloc(), bu_calloc(),
96 * or bu_realloc(). An optional 'str' string will be written out to
97 * stderr if there is an error. NULL pointers are silently ignored.
98 * Caller book-keeping may set pointers to -1L to detect invalid calls
99 * to bu_free().
100 *
101 * bu_free() intentionally wipes out the first four bytes pointed to
102 * by ptr prior to releasing memory as a basic memory safeguard. All
103 * bits are set to one (0xFFFFFFFF). This is intended to wipe out any
104 * magic number in structures and provide a distinct memory signature
105 * if the address happens to be accessed via some other pointer.
106 * While not guaranteed after memory is released, many implementations
107 * leave the value intact which can help with debugging.
108 */
109BU_EXPORT extern void bu_free(void *ptr,
110 const char *str);
111
112/**
113 * bu_malloc()/bu_free() compatible wrapper for realloc().
114 *
115 * this routine mimics the C99 standard behavior of realloc() except
116 * that NULL will never be returned. it will bomb if siz is zero and
117 * ptr is NULL. it will return a minimum allocation suitable for
118 * bu_free() if siz is zero and ptr is non-NULL.
119 *
120 * While the string 'str' is provided for the log messages, don't
121 * disturb the str value, so that this storage allocation can be
122 * tracked back to its original creator.
123 */
124BU_EXPORT extern void *bu_realloc(void *ptr,
125 size_t siz,
126 const char *str);
127
128/**
129 * On systems with the CalTech malloc(), the amount of storage
130 * ACTUALLY ALLOCATED is the amount requested rounded UP to the
131 * nearest power of two. For structures which are acquired and
132 * released often, this works well, but for structures which will
133 * remain unchanged for the duration of the program, this wastes as
134 * much as 50% of the address space (and usually memory as well).
135 * Here, we round up a byte size to the nearest power of two, leaving
136 * off the malloc header, so as to ask for storage without wasting
137 * any.
138 *
139 * On systems with the traditional malloc(), this strategy will just
140 * consume the memory in somewhat larger chunks, but overall little
141 * unused memory will be consumed.
142 */
143BU_EXPORT extern int bu_malloc_len_roundup(int nbytes);
144
145/**
146 * really fast heap-based memory allocation intended for "small"
147 * allocation sizes (e.g., single structs).
148 *
149 * the implementation allocates chunks of memory ('pages') in order to
150 * substantially reduce calls to system malloc. it has a nice
151 * property of having O(1) constant time complexity and profiles
152 * significantly faster than system malloc().
153 *
154 * release memory with bu_heap_put() only.
155 */
156BU_EXPORT extern void *bu_heap_get(size_t sz);
157
158/**
159 * counterpart to bu_heap_get() for releasing fast heap-based memory
160 * allocations.
161 *
162 * the implementation may do nothing, relying on free-on-exit, or may
163 * mark deallocations for reuse. pass a NULL pointer and zero size to
164 * force compaction of any unused memory.
165 */
166BU_EXPORT extern void bu_heap_put(void *ptr, size_t sz);
167
168/**
169 * Convenience typedef for the printf()-style callback function used
170 * during application exit to print summary statistics.
171 */
172typedef int (*bu_heap_func_t)(const char *, ...);
173
174/**
175 * This function registers and returns the current printing function
176 * that will be used during application exit (via an atexit() handler)
177 * if the BU_HEAP_PRINT environment variable is set. Statistics on
178 * calls to bu_heap_get() and bu_heap_put() will be logged. If log is
179 * NULL, the currently set function will remain unchanged and will be
180 * returned.
181 */
183
184
185/**
186 * Memory pools. To be used when you need to dynamically allocate
187 * lots of small elements which will all be freed at the same time.
188 */
190{
193 uint8_t *block;
194};
195
196BU_EXPORT extern struct bu_pool *bu_pool_create(size_t block_size);
197
198BU_EXPORT extern void *bu_pool_alloc(struct bu_pool *pool, size_t nelem, size_t elsize);
199
200BU_EXPORT extern void bu_pool_delete(struct bu_pool *pool);
201
202
203/**
204 * Attempt to get shared memory - returns -1 if new memory was
205 * created, 0 if successfully returning existing memory, and 1
206 * if the attempt failed.
207 * */
208BU_EXPORT extern int bu_shmget(int *shmid, char **shared_memory, int key, size_t size);
209
210
211/**
212 * Fast dynamic memory allocation macro for small pointer allocations.
213 * Memory is automatically initialized to zero and, similar to
214 * bu_calloc(), is guaranteed to return non-NULL (or bu_bomb()).
215 *
216 * Memory acquired with BU_GET() should be returned with BU_PUT(), NOT
217 * with bu_free().
218 *
219 * Use BU_ALLOC() for dynamically allocating structures that are
220 * relatively large, infrequently allocated, or otherwise don't need
221 * to be fast.
222 */
223#if 0
224#define BU_GET(_ptr, _type) _ptr = (_type *)bu_heap_get(sizeof(_type))
225#else
226#define BU_GET(_ptr, _type) _ptr = (_type *)bu_calloc(1, sizeof(_type), #_type " (BU_GET) " CPP_FILELINE)
227#endif
228
229/**
230 * Handy dynamic memory deallocator macro. Deallocated memory has the
231 * first byte zero'd for sanity (and potential early detection of
232 * double-free crashing code) and the pointer is set to NULL.
233 *
234 * Memory acquired with bu_malloc()/bu_calloc() should be returned
235 * with bu_free(), NOT with BU_PUT().
236 */
237#if 0
238#define BU_PUT(_ptr, _type) *(uint8_t *)(_type *)(_ptr) = /*zap*/ 0; bu_heap_put(_ptr, sizeof(_type)); _ptr = NULL
239#else
240#define BU_PUT(_ptr, _type) do { *(uint8_t *)(_type *)(_ptr) = /*zap*/ 0; bu_free(_ptr, #_type " (BU_PUT) " CPP_FILELINE); _ptr = NULL; } while (0)
241#endif
242
243/**
244 * Convenience macro for allocating a single structure on the heap.
245 * Not intended for performance-critical code. Release memory
246 * acquired with bu_free() or BU_FREE() to dealloc and set NULL.
247 */
248#define BU_ALLOC(_ptr, _type) _ptr = (_type *)bu_calloc(1, sizeof(_type), #_type " (BU_ALLOC) " CPP_FILELINE)
249
250/**
251 * Convenience macro for deallocating a single structure allocated on
252 * the heap (with bu_malloc(), bu_calloc(), BU_ALLOC()).
253 */
254#define BU_FREE(_ptr, _type) do { bu_free(_ptr, #_type " (BU_FREE) " CPP_FILELINE); _ptr = (_type *)NULL; } while (0)
255
256/** @} */
257
258/* DEPRECATED */
259BU_EXPORT extern void bu_prmem(const char *str);
260
261/* DEPRECATED: use valgrind/memcheck, SGcheck */
262BU_EXPORT extern void bu_ck_malloc_ptr(void *ptr, const char *str);
263
264/* DEPRECATED: use valgrind/memcheck, SGcheck */
265BU_EXPORT extern int bu_mem_barriercheck(void);
266
267__END_DECLS
268
269#endif /* BU_MALLOC_H */
270
271/*
272 * Local Variables:
273 * mode: C
274 * tab-width: 8
275 * indent-tabs-mode: t
276 * c-file-style: "stroustrup"
277 * End:
278 * ex: shiftwidth=4 tabstop=8
279 */
Header file for the BRL-CAD common definitions.
void * bu_realloc(void *ptr, size_t siz, const char *str)
void * bu_malloc(size_t siz, const char *str)
int bu_malloc_len_roundup(int nbytes)
void bu_pool_delete(struct bu_pool *pool)
void * bu_heap_get(size_t sz)
void bu_heap_put(void *ptr, size_t sz)
int bu_shmget(int *shmid, char **shared_memory, int key, size_t size)
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
bu_heap_func_t bu_heap_log(bu_heap_func_t log)
int(* bu_heap_func_t)(const char *,...)
Definition: malloc.h:172
void * bu_pool_alloc(struct bu_pool *pool, size_t nelem, size_t elsize)
size_t bu_n_free
size_t bu_n_realloc
void bu_free(void *ptr, const char *str)
struct bu_pool * bu_pool_create(size_t block_size)
size_t bu_n_malloc
void float float int int int int float * size
Definition: tig.h:132
Global registry of recognized magic numbers.
void bu_prmem(const char *str)
void bu_ck_malloc_ptr(void *ptr, const char *str)
int bu_mem_barriercheck(void)
size_t block_pos
Definition: malloc.h:192
size_t alloc_size
Definition: malloc.h:192
uint8_t * block
Definition: malloc.h:193
size_t block_size
Definition: malloc.h:191