1 #ifndef __BFT_MEM_H__
2 #define __BFT_MEM_H__
3 
4 /*============================================================================
5  * Base memory allocation wrappers with optional tracing
6  *============================================================================*/
7 
8 /*
9   This file is part of Code_Saturne, a general-purpose CFD tool.
10 
11   Copyright (C) 1998-2021 EDF S.A.
12 
13   This program is free software; you can redistribute it and/or modify it under
14   the terms of the GNU General Public License as published by the Free Software
15   Foundation; either version 2 of the License, or (at your option) any later
16   version.
17 
18   This program is distributed in the hope that it will be useful, but WITHOUT
19   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21   details.
22 
23   You should have received a copy of the GNU General Public License along with
24   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25   Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27 
28 /*----------------------------------------------------------------------------*/
29 
30 #include "cs_defs.h"
31 
32 /*----------------------------------------------------------------------------*/
33 
34 /* BFT headers */
35 
36 #include "bft_error.h"
37 
38 /*-----------------------------------------------------------------------------*/
39 
40 BEGIN_C_DECLS
41 
42 /*============================================================================
43  * Public types
44  *============================================================================*/
45 
46 /*============================================================================
47  * Public macros
48  *============================================================================*/
49 
50 /*
51  * Allocate memory for _ni items of type _type.
52  *
53  * This macro calls bft_mem_malloc(), automatically setting the
54  * allocated variable name and source file name and line arguments.
55  *
56  * parameters:
57  *   _ptr  --> pointer to allocated memory.
58  *   _ni   <-- number of items.
59  *   _type <-- element type.
60  */
61 
62 #define BFT_MALLOC(_ptr, _ni, _type) \
63 _ptr = (_type *) bft_mem_malloc(_ni, sizeof(_type), \
64                                 #_ptr, __FILE__, __LINE__)
65 
66 /*
67  * Reallocate memory for _ni items of type _type.
68  *
69  * This macro calls bft_mem_realloc(), automatically setting the
70  * allocated variable name and source file name and line arguments.
71  *
72  * parameters:
73  *   _ptr  <->  pointer to allocated memory.
74  *   _ni   <-- number of items.
75  *   _type <-- element type.
76  */
77 
78 #define BFT_REALLOC(_ptr, _ni, _type) \
79 _ptr = (_type *) bft_mem_realloc(_ptr, _ni, sizeof(_type), \
80                                  #_ptr, __FILE__, __LINE__)
81 
82 /*
83  * Free allocated memory.
84  *
85  * This macro calls bft_mem_free(), automatically setting the
86  * allocated variable name and source file name and line arguments.
87  *
88  * The freed pointer is set to NULL to avoid accidental reuse.
89  *
90  * parameters:
91  *   _ptr  <->  pointer to allocated memory.
92  */
93 
94 #ifdef __cplusplus /* avoid casting from void for C++ */
95 
96 #define BFT_FREE(_ptr) \
97 bft_mem_free(_ptr, #_ptr, __FILE__, __LINE__), _ptr = NULL
98 
99 #else
100 
101 #define BFT_FREE(_ptr) \
102 _ptr = bft_mem_free(_ptr, #_ptr, __FILE__, __LINE__)
103 
104 #endif /* __cplusplus */
105 
106 /*
107  * Allocate aligned memory for _ni items of type _type.
108  *
109  * This macro calls bft_mem_memalign(), automatically setting the
110  * allocated variable name and source file name and line arguments.
111  *
112  * parameters:
113  *   _ptr    --> pointer to allocated memory.
114  *   _align <-- alignment.
115  *   _ni    <-- number of items.
116  *   _type  <-- element type.
117  */
118 
119 #define BFT_MEMALIGN(_ptr, _align, _ni, _type) \
120 _ptr = (_type *) bft_mem_memalign(_align, _ni, sizeof(_type), \
121                                   #_ptr, __FILE__, __LINE__)
122 
123 /*----------------------------------------------------------------------------
124  * Function pointer types
125  *----------------------------------------------------------------------------*/
126 
127 typedef size_t
128 (bft_mem_get_size_t)(void  *ptr);
129 
130 typedef void *
131 (bft_mem_realloc_t)(void        *ptr,
132                     size_t       ni,
133                     size_t       size,
134                     const char  *var_name,
135                     const char  *file_name,
136                     int          line_num);
137 
138 typedef void
139 (bft_mem_free_t)(void        *ptr,
140                  const char  *var_name,
141                  const char  *file_name,
142                  int          line_num);
143 
144 /*============================================================================
145  * Public function prototypes
146  *============================================================================*/
147 
148 /*
149  * Initialize memory handling.
150  *
151  * This function should be called before any other bft_mem_...()
152  * function. To activate memory allocation logging, a logfile
153  * name should be given as an argument. The resulting file will
154  * be a regular, local file. If this file cannot be opened for
155  * some reason, logging is silently de-activated.
156  *
157  * parameter:
158  *   log_file_name <-- name of optional log_file (if NULL, no log).
159  */
160 
161 void
162 bft_mem_init(const char  *log_file_name);
163 
164 /*
165  * End memory handling.
166  *
167  * This function should be called after all other bft_mem_...()
168  * functions. In case of memory allocation logging, it
169  * writes final information to the log file and closes is.
170  */
171 
172 void
173 bft_mem_end(void);
174 
175 /*
176  * Initialize memory handling.
177  *
178  * This function should be called before any other bft_mem_...()
179  * function. To activate memory allocation logging, a logfile
180  * name should be given as an argument. The resulting file will
181  * be a regular, local file. If this file cannot be opened for
182  * some reason, logging is silently de-activated.
183  *
184  * parameter:
185  *   log_file_name <-- name of optional log_file (if NULL, no log).
186  */
187 
188 /*
189  * Indicates if bft_mem_...() functions are initialized.
190  *
191  * returns:
192  *   1 if bft_mem_init has been called, 0 otherwise.
193  */
194 
195 int
196 bft_mem_initialized(void);
197 
198 /*
199  * Allocate memory for ni items of size bytes.
200  *
201  * This function calls malloc(), but adds tracing capabilities, and
202  * automatically calls the bft_error() errorhandler if it fails to
203  * allocate the required memory.
204  *
205  * parameters:
206  *   ni        <-- number of items.
207  *   size      <-- element size.
208  *   var_name  <-- allocated variable name string.
209  *   file_name <-- name of calling source file.
210  *   line_num  <-- line number in calling source file.
211  *
212  * returns:
213  *   pointer to allocated memory.
214  */
215 
216 void *
217 bft_mem_malloc(size_t       ni,
218                size_t       size,
219                const char  *var_name,
220                const char  *file_name,
221                int          line_num);
222 
223 /*
224  * Reallocate memory for ni items of size bytes.
225  *
226  * This function calls realloc(), but adds tracing capabilities, and
227  * automatically calls the bft_error() errorhandler if it fails to
228  * allocate the required memory.
229  *
230  * parameters:
231  *   ptr       <-> pointer to previous memory location
232  *                 (if NULL, bft_alloc() called).
233  *   ni        <-- number of items.
234  *   size      <-- element size.
235  *   var_name  <-- allocated variable name string.
236  *   file_name <-- name of calling source file.
237  *   line_num   -> line number in calling source file
238  *
239  * returns:
240  *   pointer to allocated memory.
241  */
242 
243 void *
244 bft_mem_realloc(void        *ptr,
245                 size_t       ni,
246                 size_t       size,
247                 const char  *var_name,
248                 const char  *file_name,
249                 int          line_num);
250 
251 /*
252  * Free allocated memory.
253  *
254  * This function calls free(), but adds tracing capabilities, and
255  * automatically calls the bft_error() errorhandler if it fails to
256  * free the corresponding memory. In case of a NULL pointer argument,
257  * the function simply returns.
258  *
259  * parameters:
260  *   ptr       <-> pointer to previous memory location
261  *                 (if NULL, bft_alloc() called).
262  *   var_name  <-- allocated variable name string.
263  *   file_name <-- name of calling source file.
264  *   line_num  <-- line number in calling source file.
265  *
266  * returns:
267  *   NULL pointer.
268  */
269 
270 void *
271 bft_mem_free(void        *ptr,
272              const char  *var_name,
273              const char  *file_name,
274              int          line_num);
275 
276 /*
277  * Allocate aligned memory for ni elements of size bytes.
278  *
279  * This function calls posix_memalign() if available, but adds tracing
280  * capabilities, and automatically calls the bft_error() errorhandler if
281  * it fails to allocate the required memory.
282  *
283  * The associated function bft_mem_have_memalign() indicates if this
284  * type of allocation may be used on this system.
285  *
286  * parameters:
287  *   alignment <-- alignent.
288  *   ni        <-- number of items.
289  *   size      <-- element size.
290  *   var_name  <-- allocated variable name string.
291  *   file_name <-- name of calling source file.
292  *   line_num  <-- line number in calling source file.
293  *
294  * returns:
295  *   pointer to allocated memory.
296  */
297 
298 void *
299 bft_mem_memalign(size_t       alignment,
300                  size_t       ni,
301                  size_t       size,
302                  const char  *var_name,
303                  const char  *file_name,
304                  int          line_num);
305 
306 /*!
307  * \brief Return block size associated with a given pointer.
308  *
309  * bft_mem_init() must have beed called before this function can be used.
310  *
311  * \param [in] ptr  pointer to previous memory location
312  *
313  * \returns size of associated memory block.
314  */
315 
316 size_t
317 bft_mem_get_block_size(void  *ptr);
318 
319 /*!
320  * \brief Return current theoretical dynamic memory allocated.
321  *
322  * \return current memory handled through bft_mem_...() (in kB).
323  */
324 
325 size_t
326 bft_mem_size_current(void);
327 
328 /*!
329  * \brief Return maximum theoretical dynamic memory allocated.
330  *
331  * \return maximum memory handled through bft_mem_...() (in kB).
332  */
333 
334 size_t
335 bft_mem_size_max(void);
336 
337 /*
338  * Indicate if a memory aligned allocation variant is available.
339  *
340  * If no such function is available, bft_mem_memalign() will always fail.
341  *
342  * returns:
343  *   1 if memory aligned allocation is possible, 0 otherwise.
344  */
345 
346 int
347 bft_mem_have_memalign(void);
348 
349 /* Returns the error handler associated with the bft_mem_...() functions.
350  *
351  * returns:
352  *   pointer to the error handler function.
353  */
354 
355 bft_error_handler_t *
356 bft_mem_error_handler_get(void);
357 
358 /*
359  * Associates an error handler with the bft_mem_...() functions.
360  *
361  * With the default error handler, an error message is output to stderr,
362  * (after bft_print_flush() is called), and the general error handler used
363  * by bft_error() is then called (which results in the termination of the
364  * current process or process group).
365  *
366  * parameter:
367  *   handler <-- pointer to the error handler function.
368  */
369 
370 void
371 bft_mem_error_handler_set(bft_error_handler_t *handler);
372 
373 /*
374  * Associates alternative functions with the bft_mem_...() functions.
375  *
376  * When memory allocated with another mechanism is reallocated or
377  * freed using a bft_mem_... function, this allows trying the
378  * matching alternative function rather than throwing an error.
379  *
380  * Though using matching methods is recommended, this allows handling
381  * compatibility between methods which might be used in different parts
382  * of the code.
383  *
384  * parameter:
385  *   realloc_func <-- pointer to alternative reallocation function.
386  *   realloc_func <-- pointer to alternative reallocation function.
387  *   free_func    <-- pointer to alternative free function.
388  */
389 
390 void
391 bft_mem_alternative_set(bft_mem_get_size_t  *get_size_func,
392                         bft_mem_realloc_t   *realloc_func,
393                         bft_mem_free_t      *free_func);
394 
395 /*----------------------------------------------------------------------------*/
396 
397 END_C_DECLS
398 
399 #endif /* __BFT_MEM_H__ */
400