00001 /* 00002 * kmp_wrapper_malloc.h -- Wrappers for memory allocation routines 00003 * (malloc(), free(), and others). 00004 * $Revision: 42181 $ 00005 * $Date: 2013-03-26 15:04:45 -0500 (Tue, 26 Mar 2013) $ 00006 */ 00007 00008 /* <copyright> 00009 Copyright (c) 1997-2013 Intel Corporation. All Rights Reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions 00013 are met: 00014 00015 * Redistributions of source code must retain the above copyright 00016 notice, this list of conditions and the following disclaimer. 00017 * Redistributions in binary form must reproduce the above copyright 00018 notice, this list of conditions and the following disclaimer in the 00019 documentation and/or other materials provided with the distribution. 00020 * Neither the name of Intel Corporation nor the names of its 00021 contributors may be used to endorse or promote products derived 00022 from this software without specific prior written permission. 00023 00024 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00025 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00026 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00027 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00028 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00029 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00030 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00031 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00032 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00033 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00034 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 00036 00037 ------------------------------------------------------------------------ 00038 00039 Portions of this software are protected under the following patents: 00040 U.S. Patent 5,812,852 00041 U.S. Patent 6,792,599 00042 U.S. Patent 7,069,556 00043 U.S. Patent 7,328,433 00044 U.S. Patent 7,500,242 00045 00046 </copyright> */ 00047 00048 #ifndef KMP_WRAPPER_MALLOC_H 00049 #define KMP_WRAPPER_MALLOC_H 00050 00051 /* 00052 This header serves for 3 purposes: 00053 00054 1. Declaring standard memory allocation rourines in OS-independent way. 00055 2. Passing source location info through memory allocation wrappers. 00056 3. Enabling native memory debugging capabilities. 00057 00058 00059 1. Declaring standard memory allocation rourines in OS-independent way. 00060 ----------------------------------------------------------------------- 00061 00062 On Linux* OS, alloca() function is declared in <alloca.h> header, while on Windows* OS there is no 00063 <alloca.h> header, function _alloca() (note underscore!) is declared in <malloc.h>. This header 00064 eliminates these differences, so client code incluiding "kmp_wrapper_malloc.h" can rely on 00065 following routines: 00066 00067 malloc 00068 calloc 00069 realloc 00070 free 00071 alloca 00072 00073 in OS-independent way. It also enables memory tracking capabilities in debug build. (Currently 00074 it is available only on Windows* OS.) 00075 00076 00077 2. Passing source location info through memory allocation wrappers. 00078 ------------------------------------------------------------------- 00079 00080 Some tools may help debugging memory errors, for example, report memory leaks. However, memory 00081 allocation wrappers may hinder source location. 00082 00083 For example: 00084 00085 void * aligned_malloc( int size ) { 00086 void * ptr = malloc( size ); // All the memory leaks will be reported at this line. 00087 // some adjustments... 00088 return ptr; 00089 }; 00090 00091 ptr = aligned_malloc( size ); // Memory leak will *not* be detected here. :-( 00092 00093 To overcome the problem, information about original source location should be passed through all 00094 the memory allocation wrappers, for example: 00095 00096 void * aligned_malloc( int size, char const * file, int line ) { 00097 void * ptr = _malloc_dbg( size, file, line ); 00098 // some adjustments... 00099 return ptr; 00100 }; 00101 00102 void * ptr = aligned_malloc( size, __FILE__, __LINE__ ); 00103 00104 This is a good idea for debug, but passing additional arguments impacts performance. Disabling 00105 extra arguments in release version of the software introduces too many conditional compilation, 00106 which makes code unreadable. This header defines few macros and functions facilitating it: 00107 00108 void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) { 00109 void * ptr = malloc_src_loc( size KMP_SRC_LOC_PARM ); 00110 // some adjustments... 00111 return ptr; 00112 }; 00113 #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR ) 00114 // Use macro instead of direct call to function. 00115 00116 void * ptr = aligned_malloc( size ); // Bingo! Memory leak will be reported at this line. 00117 00118 00119 3. Enabling native memory debugging capabilities. 00120 ------------------------------------------------- 00121 00122 Some platforms may offer memory debugging capabilities. For example, debug version of Microsoft 00123 RTL tracks all memory allocations and can report memory leaks. This header enables this, and 00124 makes report more useful (see "Passing source location info through memory allocation 00125 wrappers"). 00126 00127 */ 00128 00129 #include <stdlib.h> 00130 00131 #include "kmp_os.h" 00132 00133 // Include alloca() declaration. 00134 #if KMP_OS_WINDOWS 00135 #include <malloc.h> // Windows* OS: _alloca() declared in "malloc.h". 00136 #define alloca _alloca // Allow to use alloca() with no underscore. 00137 #elif KMP_OS_UNIX 00138 #include <alloca.h> // Linux* OS and OS X*: alloc() declared in "alloca". 00139 #else 00140 #error Unknown or unsupported OS. 00141 #endif 00142 00143 /* 00144 KMP_SRC_LOC_DECL -- Declaring source location paramemters, to be used in function declaration. 00145 KMP_SRC_LOC_PARM -- Source location paramemters, to be used to pass parameters to underlying 00146 levels. 00147 KMP_SRC_LOC_CURR -- Source location arguments describing current location, to be used at 00148 top-level. 00149 00150 Typical usage: 00151 00152 void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) { 00153 // Note: Comma is missed before KMP_SRC_LOC_DECL. 00154 KE_TRACE( 25, ( "called from %s:%d\n", KMP_SRC_LOC_PARM ) ); 00155 ... 00156 } 00157 #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR ) 00158 // Use macro instead of direct call to function -- macro passes info about current 00159 // source location to the func. 00160 */ 00161 #if KMP_DEBUG 00162 #define KMP_SRC_LOC_DECL , char const * _file_, int _line_ 00163 #define KMP_SRC_LOC_PARM , _file_, _line_ 00164 #define KMP_SRC_LOC_CURR , __FILE__, __LINE__ 00165 #else 00166 #define KMP_SRC_LOC_DECL 00167 #define KMP_SRC_LOC_PARM 00168 #define KMP_SRC_LOC_CURR 00169 #endif // KMP_DEBUG 00170 00171 /* 00172 malloc_src_loc() and free_src_loc() are pseudo-functions (really macros) with accepts extra 00173 arguments (source location info) in debug mode. They should be used in place of malloc() and 00174 free(), this allows enabling native memory debugging capabilities (if any). 00175 00176 Typical usage: 00177 00178 ptr = malloc_src_loc( size KMP_SRC_LOC_PARM ); 00179 // Inside memory allocation wrapper, or 00180 ptr = malloc_src_loc( size KMP_SRC_LOC_CURR ); 00181 // Outside of memory allocation wrapper. 00182 00183 00184 */ 00185 #define malloc_src_loc( args ) _malloc_src_loc( args ) 00186 #define free_src_loc( args ) _free_src_loc( args ) 00187 /* 00188 Depending on build mode (debug or release), malloc_src_loc is declared with 1 or 3 00189 parameters, but calls to malloc_src_loc() are always the same: 00190 00191 ... malloc_src_loc( size KMP_SRC_LOC_PARM ); // or KMP_SRC_LOC_CURR 00192 00193 Compiler issues warning/error "too few arguments in macro invocation". Declaring two 00194 macroses, malloc_src_loc() and _malloc_src_loc() overcomes the problem. 00195 */ 00196 00197 #if KMP_DEBUG 00198 00199 #if KMP_OS_WINDOWS && _DEBUG 00200 // KMP_DEBUG != _DEBUG. MS debug RTL is available only if _DEBUG is defined. 00201 00202 // Windows* OS has native memory debugging capabilities. Enable them. 00203 00204 #include <crtdbg.h> 00205 00206 #define KMP_MEM_BLOCK _CLIENT_BLOCK 00207 #define malloc( size ) _malloc_dbg( (size), KMP_MEM_BLOCK, __FILE__, __LINE__ ) 00208 #define calloc( num, size ) _calloc_dbg( (num), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ ) 00209 #define realloc( ptr, size ) _realloc_dbg( (ptr), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ ) 00210 #define free( ptr ) _free_dbg( (ptr), KMP_MEM_BLOCK ) 00211 00212 #define _malloc_src_loc( size, file, line ) _malloc_dbg( (size), KMP_MEM_BLOCK, (file), (line) ) 00213 #define _free_src_loc( ptr, file, line ) _free_dbg( (ptr), KMP_MEM_BLOCK ) 00214 00215 #else 00216 00217 // Linux* OS, OS X*, or non-debug Windows* OS. 00218 00219 #define _malloc_src_loc( size, file, line ) malloc( (size) ) 00220 #define _free_src_loc( ptr, file, line ) free( (ptr) ) 00221 00222 #endif 00223 00224 #else 00225 00226 // In release build malloc_src_loc() and free_src_loc() do not have extra parameters. 00227 #define _malloc_src_loc( size ) malloc( (size) ) 00228 #define _free_src_loc( ptr ) free( (ptr) ) 00229 00230 #endif // KMP_DEBUG 00231 00232 #endif // KMP_WRAPPER_MALLOC_H 00233 00234 // end of file //