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