Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Modules Pages
kmp_wrapper_malloc.h
1 /*
2  * kmp_wrapper_malloc.h -- Wrappers for memory allocation routines
3  * (malloc(), free(), and others).
4  * $Revision: 43084 $
5  * $Date: 2014-04-15 09:15:14 -0500 (Tue, 15 Apr 2014) $
6  */
7 
8 /* <copyright>
9  Copyright (c) 1997-2014 Intel Corporation. All Rights Reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions
13  are met:
14 
15  * Redistributions of source code must retain the above copyright
16  notice, this list of conditions and the following disclaimer.
17  * Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20  * Neither the name of Intel Corporation nor the names of its
21  contributors may be used to endorse or promote products derived
22  from this software without specific prior written permission.
23 
24  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 
36 </copyright> */
37 
38 #ifndef KMP_WRAPPER_MALLOC_H
39 #define KMP_WRAPPER_MALLOC_H
40 
41 /*
42  This header serves for 3 purposes:
43 
44  1. Declaring standard memory allocation rourines in OS-independent way.
45  2. Passing source location info through memory allocation wrappers.
46  3. Enabling native memory debugging capabilities.
47 
48 
49  1. Declaring standard memory allocation rourines in OS-independent way.
50  -----------------------------------------------------------------------
51 
52  On Linux* OS, alloca() function is declared in <alloca.h> header, while on Windows* OS there is no
53  <alloca.h> header, function _alloca() (note underscore!) is declared in <malloc.h>. This header
54  eliminates these differences, so client code incluiding "kmp_wrapper_malloc.h" can rely on
55  following routines:
56 
57  malloc
58  calloc
59  realloc
60  free
61  alloca
62 
63  in OS-independent way. It also enables memory tracking capabilities in debug build. (Currently
64  it is available only on Windows* OS.)
65 
66 
67  2. Passing source location info through memory allocation wrappers.
68  -------------------------------------------------------------------
69 
70  Some tools may help debugging memory errors, for example, report memory leaks. However, memory
71  allocation wrappers may hinder source location.
72 
73  For example:
74 
75  void * aligned_malloc( int size ) {
76  void * ptr = malloc( size ); // All the memory leaks will be reported at this line.
77  // some adjustments...
78  return ptr;
79  };
80 
81  ptr = aligned_malloc( size ); // Memory leak will *not* be detected here. :-(
82 
83  To overcome the problem, information about original source location should be passed through all
84  the memory allocation wrappers, for example:
85 
86  void * aligned_malloc( int size, char const * file, int line ) {
87  void * ptr = _malloc_dbg( size, file, line );
88  // some adjustments...
89  return ptr;
90  };
91 
92  void * ptr = aligned_malloc( size, __FILE__, __LINE__ );
93 
94  This is a good idea for debug, but passing additional arguments impacts performance. Disabling
95  extra arguments in release version of the software introduces too many conditional compilation,
96  which makes code unreadable. This header defines few macros and functions facilitating it:
97 
98  void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
99  void * ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
100  // some adjustments...
101  return ptr;
102  };
103  #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
104  // Use macro instead of direct call to function.
105 
106  void * ptr = aligned_malloc( size ); // Bingo! Memory leak will be reported at this line.
107 
108 
109  3. Enabling native memory debugging capabilities.
110  -------------------------------------------------
111 
112  Some platforms may offer memory debugging capabilities. For example, debug version of Microsoft
113  RTL tracks all memory allocations and can report memory leaks. This header enables this, and
114  makes report more useful (see "Passing source location info through memory allocation
115  wrappers").
116 
117 */
118 
119 #include <stdlib.h>
120 
121 #include "kmp_os.h"
122 
123 // Include alloca() declaration.
124 #if KMP_OS_WINDOWS
125  #include <malloc.h> // Windows* OS: _alloca() declared in "malloc.h".
126  #define alloca _alloca // Allow to use alloca() with no underscore.
127 #elif KMP_OS_FREEBSD
128  // Declared in "stdlib.h".
129 #elif KMP_OS_UNIX
130  #include <alloca.h> // Linux* OS and OS X*: alloc() declared in "alloca".
131 #else
132  #error Unknown or unsupported OS.
133 #endif
134 
135 /*
136  KMP_SRC_LOC_DECL -- Declaring source location paramemters, to be used in function declaration.
137  KMP_SRC_LOC_PARM -- Source location paramemters, to be used to pass parameters to underlying
138  levels.
139  KMP_SRC_LOC_CURR -- Source location arguments describing current location, to be used at
140  top-level.
141 
142  Typical usage:
143 
144  void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
145  // Note: Comma is missed before KMP_SRC_LOC_DECL.
146  KE_TRACE( 25, ( "called from %s:%d\n", KMP_SRC_LOC_PARM ) );
147  ...
148  }
149  #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
150  // Use macro instead of direct call to function -- macro passes info about current
151  // source location to the func.
152 */
153 #if KMP_DEBUG
154  #define KMP_SRC_LOC_DECL , char const * _file_, int _line_
155  #define KMP_SRC_LOC_PARM , _file_, _line_
156  #define KMP_SRC_LOC_CURR , __FILE__, __LINE__
157 #else
158  #define KMP_SRC_LOC_DECL
159  #define KMP_SRC_LOC_PARM
160  #define KMP_SRC_LOC_CURR
161 #endif // KMP_DEBUG
162 
163 /*
164  malloc_src_loc() and free_src_loc() are pseudo-functions (really macros) with accepts extra
165  arguments (source location info) in debug mode. They should be used in place of malloc() and
166  free(), this allows enabling native memory debugging capabilities (if any).
167 
168  Typical usage:
169 
170  ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
171  // Inside memory allocation wrapper, or
172  ptr = malloc_src_loc( size KMP_SRC_LOC_CURR );
173  // Outside of memory allocation wrapper.
174 
175 
176 */
177 #define malloc_src_loc( args ) _malloc_src_loc( args )
178 #define free_src_loc( args ) _free_src_loc( args )
179  /*
180  Depending on build mode (debug or release), malloc_src_loc is declared with 1 or 3
181  parameters, but calls to malloc_src_loc() are always the same:
182 
183  ... malloc_src_loc( size KMP_SRC_LOC_PARM ); // or KMP_SRC_LOC_CURR
184 
185  Compiler issues warning/error "too few arguments in macro invocation". Declaring two
186  macroses, malloc_src_loc() and _malloc_src_loc() overcomes the problem.
187  */
188 
189 #if KMP_DEBUG
190 
191  #if KMP_OS_WINDOWS && _DEBUG
192  // KMP_DEBUG != _DEBUG. MS debug RTL is available only if _DEBUG is defined.
193 
194  // Windows* OS has native memory debugging capabilities. Enable them.
195 
196  #include <crtdbg.h>
197 
198  #define KMP_MEM_BLOCK _CLIENT_BLOCK
199  #define malloc( size ) _malloc_dbg( (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
200  #define calloc( num, size ) _calloc_dbg( (num), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
201  #define realloc( ptr, size ) _realloc_dbg( (ptr), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
202  #define free( ptr ) _free_dbg( (ptr), KMP_MEM_BLOCK )
203 
204  #define _malloc_src_loc( size, file, line ) _malloc_dbg( (size), KMP_MEM_BLOCK, (file), (line) )
205  #define _free_src_loc( ptr, file, line ) _free_dbg( (ptr), KMP_MEM_BLOCK )
206 
207  #else
208 
209  // Linux* OS, OS X*, or non-debug Windows* OS.
210 
211  #define _malloc_src_loc( size, file, line ) malloc( (size) )
212  #define _free_src_loc( ptr, file, line ) free( (ptr) )
213 
214  #endif
215 
216 #else
217 
218  // In release build malloc_src_loc() and free_src_loc() do not have extra parameters.
219  #define _malloc_src_loc( size ) malloc( (size) )
220  #define _free_src_loc( ptr ) free( (ptr) )
221 
222 #endif // KMP_DEBUG
223 
224 #endif // KMP_WRAPPER_MALLOC_H
225 
226 // end of file //