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-2014 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 /** @file malloc.h
22  *
23  */
24 #ifndef BU_MALLOC_H
25 #define BU_MALLOC_H
26 
27 #include "common.h"
28 #include <stddef.h> /* for size_t */
29 
30 #include "bu/defines.h"
31 #include "bu/magic.h"
32 
34 
35 /** @addtogroup malloc */
36 /** @{ */
37 /** @file libbu/malloc.c
38  *
39  * @brief
40  * Parallel-protected debugging-enhanced wrapper around system malloc().
41  *
42  * Provides a parallel-safe interface to the system memory allocator
43  * with standardized error checking, optional memory-use logging, and
44  * optional run-time pointer and memory corruption testing.
45  *
46  * The bu_*alloc() routines can't use bu_log() because that uses the
47  * bu_vls() routines which depend on bu_malloc(). So it goes direct
48  * to stderr, semaphore protected.
49  *
50  */
51 
52 BU_EXPORT extern long bu_n_malloc;
53 BU_EXPORT extern long bu_n_realloc;
54 
55 /**
56  * This routine only returns on successful allocation. We promise
57  * never to return a NULL pointer; caller doesn't have to check.
58  * Allocation failure results in bu_bomb() being called.
59  */
60 BU_EXPORT extern void *bu_malloc(size_t siz,
61  const char *str);
62 
63 /**
64  * This routine only returns on successful allocation.
65  * We promise never to return a NULL pointer; caller doesn't have to check.
66  * Failure results in bu_bomb() being called.
67  */
68 BU_EXPORT extern void *bu_calloc(size_t nelem,
69  size_t elsize,
70  const char *str);
71 
72 BU_EXPORT extern void bu_free(void *ptr,
73  const char *str);
74 
75 /**
76  * bu_malloc()/bu_free() compatible wrapper for realloc().
77  *
78  * this routine mimics the C99 standard behavior of realloc() except
79  * that NULL will never be returned. it will bomb if siz is zero and
80  * ptr is NULL. it will return a minimum allocation suitable for
81  * bu_free() if siz is zero and ptr is non-NULL.
82  *
83  * While the string 'str' is provided for the log messages, don't
84  * disturb the str value, so that this storage allocation can be
85  * tracked back to its original creator.
86  */
87 BU_EXPORT extern void *bu_realloc(void *ptr,
88  size_t siz,
89  const char *str);
90 
91 /**
92  * Print map of memory currently in use.
93  */
94 BU_EXPORT extern void bu_prmem(const char *str);
95 
96 /**
97  * On systems with the CalTech malloc(), the amount of storage
98  * ACTUALLY ALLOCATED is the amount requested rounded UP to the
99  * nearest power of two. For structures which are acquired and
100  * released often, this works well, but for structures which will
101  * remain unchanged for the duration of the program, this wastes as
102  * much as 50% of the address space (and usually memory as well).
103  * Here, we round up a byte size to the nearest power of two, leaving
104  * off the malloc header, so as to ask for storage without wasting
105  * any.
106  *
107  * On systems with the traditional malloc(), this strategy will just
108  * consume the memory in somewhat larger chunks, but overall little
109  * unused memory will be consumed.
110  */
111 BU_EXPORT extern int bu_malloc_len_roundup(int nbytes);
112 
113 /**
114  * For a given pointer allocated by bu_malloc(), bu_calloc(), or
115  * BU_ALLOC() check the magic number stored after the allocation area
116  * when BU_DEBUG_MEM_CHECK is set.
117  *
118  * This is the individual version of bu_mem_barriercheck().
119  *
120  * returns if pointer good or BU_DEBUG_MEM_CHECK not set, bombs if
121  * memory is corrupted.
122  */
123 BU_EXPORT extern void bu_ck_malloc_ptr(void *ptr, const char *str);
124 
125 /**
126  * Check *all* entries in the memory debug table for barrier word
127  * corruption. Intended to be called periodically through an
128  * application during debugging. Has to run single-threaded, to
129  * prevent table mutation.
130  *
131  * This is the bulk version of bu_ck_malloc_ptr()
132  *
133  * Returns -
134  * -1 something is wrong
135  * 0 all is OK;
136  */
137 BU_EXPORT extern int bu_mem_barriercheck(void);
138 
139 /**
140  * really fast heap-based memory allocation intended for "small"
141  * allocation sizes (e.g., single structs).
142  *
143  * the implementation allocates chunks of memory ('pages') in order to
144  * substantially reduce calls to system malloc. it has a nice
145  * property of having O(1) constant time complexity and profiles
146  * significantly faster than system malloc().
147  *
148  * release memory with bu_heap_put() only.
149  */
150 BU_EXPORT extern void *bu_heap_get(size_t sz);
151 
152 /**
153  * counterpart to bu_heap_get() for releasing fast heap-based memory
154  * allocations.
155  *
156  * the implementation may do nothing, relying on free-on-exit, or may
157  * mark deallocations for reuse. pass a NULL pointer and zero size to
158  * force compaction of any unused memory.
159  */
160 BU_EXPORT extern void bu_heap_put(void *ptr, size_t sz);
161 
162 /**
163  * Convenience typedef for the printf()-style callback function used
164  * during application exit to print summary statistics.
165  */
166 typedef int (*bu_heap_func_t)(const char *, ...);
167 
168 /**
169  * This function registers and returns the current printing function
170  * that will be used during application exit (via an atexit() handler)
171  * if the BU_HEAP_PRINT environment variable is set. Statistics on
172  * calls to bu_heap_get() and bu_heap_put() will be logged. If log is
173  * NULL, the currently set function will remain unchanged and will be
174  * returned.
175  */
176 BU_EXPORT extern bu_heap_func_t bu_heap_log(bu_heap_func_t log);
177 
178 /**
179  * Attempt to get shared memory - returns -1 if new memory was
180  * created, 0 if successfully returning existing memory, and 1
181  * if the attempt failed.
182  * */
183 BU_EXPORT extern int bu_shmget(int *shmid, char **shared_memory, int key, size_t size);
184 
185 
186 /**
187  * Fast dynamic memory allocation macro for small pointer allocations.
188  * Memory is automatically initialized to zero and, similar to
189  * bu_calloc(), is guaranteed to return non-NULL (or bu_bomb()).
190  *
191  * Memory acquired with BU_GET() should be returned with BU_PUT(), NOT
192  * with bu_free().
193  *
194  * Use BU_ALLOC() for dynamically allocating structures that are
195  * relatively large, infrequently allocated, or otherwise don't need
196  * to be fast.
197  */
198 #if 0
199 #define BU_GET(_ptr, _type) _ptr = (_type *)bu_heap_get(sizeof(_type))
200 #else
201 #define BU_GET(_ptr, _type) _ptr = (_type *)bu_calloc(1, sizeof(_type), #_type " (BU_GET) " BU_FLSTR)
202 #endif
203 
204 /**
205  * Handy dynamic memory deallocator macro. Deallocated memory has the
206  * first byte zero'd for sanity (and potential early detection of
207  * double-free crashing code) and the pointer is set to NULL.
208  *
209  * Memory acquired with bu_malloc()/bu_calloc() should be returned
210  * with bu_free(), NOT with BU_PUT().
211  */
212 #if 0
213 #define BU_PUT(_ptr, _type) *(uint8_t *)(_type *)(_ptr) = /*zap*/ 0; bu_heap_put(_ptr, sizeof(_type)); _ptr = NULL
214 #else
215 #define BU_PUT(_ptr, _type) do { *(uint8_t *)(_type *)(_ptr) = /*zap*/ 0; bu_free(_ptr, #_type " (BU_PUT) " BU_FLSTR); _ptr = NULL; } while (0)
216 #endif
217 
218 /**
219  * Convenience macro for allocating a single structure on the heap.
220  * Not intended for performance-critical code. Release memory
221  * acquired with bu_free() or BU_FREE() to dealloc and set NULL.
222  */
223 #define BU_ALLOC(_ptr, _type) _ptr = (_type *)bu_calloc(1, sizeof(_type), #_type " (BU_ALLOC) " BU_FLSTR)
224 
225 /**
226  * Convenience macro for deallocating a single structure allocated on
227  * the heap (with bu_malloc(), bu_calloc(), BU_ALLOC()).
228  */
229 #define BU_FREE(_ptr, _type) do { bu_free(_ptr, #_type " (BU_FREE) " BU_FLSTR); _ptr = (_type *)NULL; } while (0)
230 
231 
232 /** @} */
233 
235 
236 #endif /* BU_MALLOC_H */
237 
238 /*
239  * Local Variables:
240  * mode: C
241  * tab-width: 8
242  * indent-tabs-mode: t
243  * c-file-style: "stroustrup"
244  * End:
245  * ex: shiftwidth=4 tabstop=8
246  */
void bu_prmem(const char *str)
Definition: malloc.c:516
Header file for the BRL-CAD common definitions.
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
void bu_heap_put(void *ptr, size_t sz)
Definition: heap.c:232
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define __BEGIN_DECLS
Definition: common.h:73
void * bu_realloc(void *ptr, size_t siz, const char *str)
long bu_n_realloc
Definition: globals.c:50
void bu_ck_malloc_ptr(void *ptr, const char *str)
Definition: malloc.c:614
int bu_mem_barriercheck(void)
Definition: malloc.c:660
bu_heap_func_t bu_heap_log(bu_heap_func_t log)
Definition: heap.c:97
int(* bu_heap_func_t)(const char *,...)
Definition: malloc.h:166
int bu_shmget(int *shmid, char **shared_memory, int key, size_t size)
Definition: malloc.c:692
int bu_malloc_len_roundup(int nbytes)
#define __END_DECLS
Definition: common.h:74
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
void * bu_heap_get(size_t sz)
Definition: heap.c:171
long bu_n_malloc
Definition: globals.c:42