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-2024 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 
48 BU_EXPORT extern size_t bu_n_malloc;
49 BU_EXPORT extern size_t bu_n_realloc;
50 BU_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  */
80 BU_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  */
88 BU_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  */
109 BU_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  */
124 BU_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  */
143 BU_EXPORT extern size_t bu_malloc_len_roundup(size_t 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  */
156 BU_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  */
166 BU_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  */
172 typedef 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  */
189 struct bu_pool
190 {
191  size_t block_size;
193  uint8_t *block;
194 };
195 
196 BU_EXPORT extern struct bu_pool *bu_pool_create(size_t block_size);
197 
198 BU_EXPORT extern void *bu_pool_alloc(struct bu_pool *pool, size_t nelem, size_t elsize);
199 
200 BU_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  * */
208 BU_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 */
259 BU_EXPORT extern void bu_prmem(const char *str);
260 
261 /* DEPRECATED: use valgrind/memcheck, SGcheck */
262 BU_EXPORT extern void bu_ck_malloc_ptr(void *ptr, const char *str);
263 
264 /* DEPRECATED: use valgrind/memcheck, SGcheck */
265 BU_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.
struct bu_pool * bu_pool_create(size_t block_size)
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
void bu_pool_delete(struct bu_pool *pool)
size_t bu_malloc_len_roundup(size_t nbytes)
void * bu_malloc(size_t siz, const char *str)
void * bu_realloc(void *ptr, size_t siz, const char *str)
void bu_heap_put(void *ptr, size_t sz)
int bu_shmget(int *shmid, char **shared_memory, int key, size_t size)
void * bu_pool_alloc(struct bu_pool *pool, size_t nelem, size_t elsize)
bu_heap_func_t bu_heap_log(bu_heap_func_t log)
int(* bu_heap_func_t)(const char *,...)
Definition: malloc.h:172
size_t bu_n_free
size_t bu_n_realloc
void bu_free(void *ptr, const char *str)
size_t bu_n_malloc
void * bu_heap_get(size_t sz)
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