206 lines
7.5 KiB
C
206 lines
7.5 KiB
C
/*
|
|
* kmp_wrapper_malloc.h -- Wrappers for memory allocation routines
|
|
* (malloc(), free(), and others).
|
|
*/
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
|
// Source Licenses. See LICENSE.txt for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
#ifndef KMP_WRAPPER_MALLOC_H
|
|
#define KMP_WRAPPER_MALLOC_H
|
|
|
|
/*
|
|
This header serves for 3 purposes:
|
|
|
|
1. Declaring standard memory allocation rourines in OS-independent way.
|
|
2. Passing source location info through memory allocation wrappers.
|
|
3. Enabling native memory debugging capabilities.
|
|
|
|
|
|
1. Declaring standard memory allocation rourines 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 incluiding "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".
|
|
#define alloca _alloca // Allow to use alloca() with no underscore.
|
|
#elif KMP_OS_FREEBSD || KMP_OS_NETBSD
|
|
// 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 paramemters, to be used in function declaration.
|
|
KMP_SRC_LOC_PARM -- Source location paramemters, 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
|
|
macroses, 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 //
|