123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /*
- * kmp_wrapper_malloc.h -- Wrappers for memory allocation routines
- * (malloc(), free(), and others).
- */
- //===----------------------------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef KMP_WRAPPER_MALLOC_H
- #define KMP_WRAPPER_MALLOC_H
- /* This header serves for 3 purposes:
- 1. Declaring standard memory allocation routines in OS-independent way.
- 2. Passing source location info through memory allocation wrappers.
- 3. Enabling native memory debugging capabilities.
- 1. Declaring standard memory allocation routines in OS-independent way.
- -----------------------------------------------------------------------
- On Linux* OS, alloca() function is declared in <alloca.h> header, while on
- Windows* OS there is no <alloca.h> header, function _alloca() (note
- underscore!) is declared in <malloc.h>. This header eliminates these
- differences, so client code including "kmp_wrapper_malloc.h" can rely on
- following routines:
- malloc
- calloc
- realloc
- free
- alloca
- in OS-independent way. It also enables memory tracking capabilities in debug
- build. (Currently it is available only on Windows* OS.)
- 2. Passing source location info through memory allocation wrappers.
- -------------------------------------------------------------------
- Some tools may help debugging memory errors, for example, report memory
- leaks. However, memory allocation wrappers may hinder source location.
- For example:
- void * aligned_malloc( int size ) {
- void * ptr = malloc( size ); // All the memory leaks will be reported at
- // this line.
- // some adjustments...
- return ptr;
- };
- ptr = aligned_malloc( size ); // Memory leak will *not* be detected here. :-(
- To overcome the problem, information about original source location should
- be passed through all the memory allocation wrappers, for example:
- void * aligned_malloc( int size, char const * file, int line ) {
- void * ptr = _malloc_dbg( size, file, line );
- // some adjustments...
- return ptr;
- };
- void * ptr = aligned_malloc( size, __FILE__, __LINE__ );
- This is a good idea for debug, but passing additional arguments impacts
- performance. Disabling extra arguments in release version of the software
- introduces too many conditional compilation, which makes code unreadable.
- This header defines few macros and functions facilitating it:
- void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
- void * ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
- // some adjustments...
- return ptr;
- };
- #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
- // Use macro instead of direct call to function.
- void * ptr = aligned_malloc( size ); // Bingo! Memory leak will be
- // reported at this line.
- 3. Enabling native memory debugging capabilities.
- -------------------------------------------------
- Some platforms may offer memory debugging capabilities. For example, debug
- version of Microsoft RTL tracks all memory allocations and can report memory
- leaks. This header enables this, and makes report more useful (see "Passing
- source location info through memory allocation wrappers").
- */
- #include <stdlib.h>
- #include "kmp_os.h"
- // Include alloca() declaration.
- #if KMP_OS_WINDOWS
- #include <malloc.h> // Windows* OS: _alloca() declared in "malloc.h".
- #if KMP_MSVC_COMPAT
- #define alloca _alloca // Allow to use alloca() with no underscore.
- #endif
- #elif KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || KMP_OS_OPENBSD
- // Declared in "stdlib.h".
- #elif KMP_OS_UNIX
- #include <alloca.h> // Linux* OS and OS X*: alloc() declared in "alloca".
- #else
- #error Unknown or unsupported OS.
- #endif
- /* KMP_SRC_LOC_DECL -- Declaring source location parameters, to be used in
- function declaration.
- KMP_SRC_LOC_PARM -- Source location parameters, to be used to pass
- parameters to underlying levels.
- KMP_SRC_LOC_CURR -- Source location arguments describing current location,
- to be used at top-level.
- Typical usage:
- void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
- // Note: Comma is missed before KMP_SRC_LOC_DECL.
- KE_TRACE( 25, ( "called from %s:%d\n", KMP_SRC_LOC_PARM ) );
- ...
- }
- #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
- // Use macro instead of direct call to function -- macro passes info
- // about current source location to the func.
- */
- #if KMP_DEBUG
- #define KMP_SRC_LOC_DECL , char const *_file_, int _line_
- #define KMP_SRC_LOC_PARM , _file_, _line_
- #define KMP_SRC_LOC_CURR , __FILE__, __LINE__
- #else
- #define KMP_SRC_LOC_DECL
- #define KMP_SRC_LOC_PARM
- #define KMP_SRC_LOC_CURR
- #endif // KMP_DEBUG
- /* malloc_src_loc() and free_src_loc() are pseudo-functions (really macros)
- with accepts extra arguments (source location info) in debug mode. They
- should be used in place of malloc() and free(), this allows enabling native
- memory debugging capabilities (if any).
- Typical usage:
- ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
- // Inside memory allocation wrapper, or
- ptr = malloc_src_loc( size KMP_SRC_LOC_CURR );
- // Outside of memory allocation wrapper.
- */
- #define malloc_src_loc(args) _malloc_src_loc(args)
- #define free_src_loc(args) _free_src_loc(args)
- /* Depending on build mode (debug or release), malloc_src_loc is declared with
- 1 or 3 parameters, but calls to malloc_src_loc() are always the same:
- ... malloc_src_loc( size KMP_SRC_LOC_PARM ); // or KMP_SRC_LOC_CURR
- Compiler issues warning/error "too few arguments in macro invocation".
- Declaring two macros, malloc_src_loc() and _malloc_src_loc(), overcomes the
- problem. */
- #if KMP_DEBUG
- #if KMP_OS_WINDOWS && _DEBUG
- // KMP_DEBUG != _DEBUG. MS debug RTL is available only if _DEBUG is defined.
- // Windows* OS has native memory debugging capabilities. Enable them.
- #include <crtdbg.h>
- #define KMP_MEM_BLOCK _CLIENT_BLOCK
- #define malloc(size) _malloc_dbg((size), KMP_MEM_BLOCK, __FILE__, __LINE__)
- #define calloc(num, size) \
- _calloc_dbg((num), (size), KMP_MEM_BLOCK, __FILE__, __LINE__)
- #define realloc(ptr, size) \
- _realloc_dbg((ptr), (size), KMP_MEM_BLOCK, __FILE__, __LINE__)
- #define free(ptr) _free_dbg((ptr), KMP_MEM_BLOCK)
- #define _malloc_src_loc(size, file, line) \
- _malloc_dbg((size), KMP_MEM_BLOCK, (file), (line))
- #define _free_src_loc(ptr, file, line) _free_dbg((ptr), KMP_MEM_BLOCK)
- #else
- // Linux* OS, OS X*, or non-debug Windows* OS.
- #define _malloc_src_loc(size, file, line) malloc((size))
- #define _free_src_loc(ptr, file, line) free((ptr))
- #endif
- #else
- // In release build malloc_src_loc() and free_src_loc() do not have extra
- // parameters.
- #define _malloc_src_loc(size) malloc((size))
- #define _free_src_loc(ptr) free((ptr))
- #endif // KMP_DEBUG
- #endif // KMP_WRAPPER_MALLOC_H
- // end of file //
|