blob: b2e3dbf9e903c55f49c007f11d121af4b65b870b [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001/*
2 * kmp_wrapper_malloc.h -- Wrappers for memory allocation routines
3 * (malloc(), free(), and others).
4 * $Revision: 42181 $
5 * $Date: 2013-03-26 15:04:45 -0500 (Tue, 26 Mar 2013) $
6 */
7
8
9//===----------------------------------------------------------------------===//
10//
11// The LLVM Compiler Infrastructure
12//
13// This file is dual licensed under the MIT and the University of Illinois Open
14// Source Licenses. See LICENSE.txt for details.
15//
16//===----------------------------------------------------------------------===//
17
18
19#ifndef KMP_WRAPPER_MALLOC_H
20#define KMP_WRAPPER_MALLOC_H
21
22/*
23 This header serves for 3 purposes:
24
25 1. Declaring standard memory allocation rourines in OS-independent way.
26 2. Passing source location info through memory allocation wrappers.
27 3. Enabling native memory debugging capabilities.
28
29
30 1. Declaring standard memory allocation rourines in OS-independent way.
31 -----------------------------------------------------------------------
32
33 On Linux* OS, alloca() function is declared in <alloca.h> header, while on Windows* OS there is no
34 <alloca.h> header, function _alloca() (note underscore!) is declared in <malloc.h>. This header
35 eliminates these differences, so client code incluiding "kmp_wrapper_malloc.h" can rely on
36 following routines:
37
38 malloc
39 calloc
40 realloc
41 free
42 alloca
43
44 in OS-independent way. It also enables memory tracking capabilities in debug build. (Currently
45 it is available only on Windows* OS.)
46
47
48 2. Passing source location info through memory allocation wrappers.
49 -------------------------------------------------------------------
50
51 Some tools may help debugging memory errors, for example, report memory leaks. However, memory
52 allocation wrappers may hinder source location.
53
54 For example:
55
56 void * aligned_malloc( int size ) {
57 void * ptr = malloc( size ); // All the memory leaks will be reported at this line.
58 // some adjustments...
59 return ptr;
60 };
61
62 ptr = aligned_malloc( size ); // Memory leak will *not* be detected here. :-(
63
64 To overcome the problem, information about original source location should be passed through all
65 the memory allocation wrappers, for example:
66
67 void * aligned_malloc( int size, char const * file, int line ) {
68 void * ptr = _malloc_dbg( size, file, line );
69 // some adjustments...
70 return ptr;
71 };
72
73 void * ptr = aligned_malloc( size, __FILE__, __LINE__ );
74
75 This is a good idea for debug, but passing additional arguments impacts performance. Disabling
76 extra arguments in release version of the software introduces too many conditional compilation,
77 which makes code unreadable. This header defines few macros and functions facilitating it:
78
79 void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
80 void * ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
81 // some adjustments...
82 return ptr;
83 };
84 #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
85 // Use macro instead of direct call to function.
86
87 void * ptr = aligned_malloc( size ); // Bingo! Memory leak will be reported at this line.
88
89
90 3. Enabling native memory debugging capabilities.
91 -------------------------------------------------
92
93 Some platforms may offer memory debugging capabilities. For example, debug version of Microsoft
94 RTL tracks all memory allocations and can report memory leaks. This header enables this, and
95 makes report more useful (see "Passing source location info through memory allocation
96 wrappers").
97
98*/
99
100#include <stdlib.h>
101
102#include "kmp_os.h"
103
104// Include alloca() declaration.
105#if KMP_OS_WINDOWS
106 #include <malloc.h> // Windows* OS: _alloca() declared in "malloc.h".
107 #define alloca _alloca // Allow to use alloca() with no underscore.
Alp Toker763b9392014-02-28 09:42:41 +0000108#elif KMP_OS_FREEBSD
109 // Declared in "stdlib.h".
Jim Cownie5e8470a2013-09-27 10:38:44 +0000110#elif KMP_OS_UNIX
111 #include <alloca.h> // Linux* OS and OS X*: alloc() declared in "alloca".
112#else
113 #error Unknown or unsupported OS.
114#endif
115
116/*
117 KMP_SRC_LOC_DECL -- Declaring source location paramemters, to be used in function declaration.
118 KMP_SRC_LOC_PARM -- Source location paramemters, to be used to pass parameters to underlying
119 levels.
120 KMP_SRC_LOC_CURR -- Source location arguments describing current location, to be used at
121 top-level.
122
123 Typical usage:
124
125 void * _aligned_malloc( int size KMP_SRC_LOC_DECL ) {
126 // Note: Comma is missed before KMP_SRC_LOC_DECL.
127 KE_TRACE( 25, ( "called from %s:%d\n", KMP_SRC_LOC_PARM ) );
128 ...
129 }
130 #define aligned_malloc( size ) _aligned_malloc( (size) KMP_SRC_LOC_CURR )
131 // Use macro instead of direct call to function -- macro passes info about current
132 // source location to the func.
133*/
134#if KMP_DEBUG
135 #define KMP_SRC_LOC_DECL , char const * _file_, int _line_
136 #define KMP_SRC_LOC_PARM , _file_, _line_
137 #define KMP_SRC_LOC_CURR , __FILE__, __LINE__
138#else
139 #define KMP_SRC_LOC_DECL
140 #define KMP_SRC_LOC_PARM
141 #define KMP_SRC_LOC_CURR
142#endif // KMP_DEBUG
143
144/*
145 malloc_src_loc() and free_src_loc() are pseudo-functions (really macros) with accepts extra
146 arguments (source location info) in debug mode. They should be used in place of malloc() and
147 free(), this allows enabling native memory debugging capabilities (if any).
148
149 Typical usage:
150
151 ptr = malloc_src_loc( size KMP_SRC_LOC_PARM );
152 // Inside memory allocation wrapper, or
153 ptr = malloc_src_loc( size KMP_SRC_LOC_CURR );
154 // Outside of memory allocation wrapper.
155
156
157*/
158#define malloc_src_loc( args ) _malloc_src_loc( args )
159#define free_src_loc( args ) _free_src_loc( args )
160 /*
161 Depending on build mode (debug or release), malloc_src_loc is declared with 1 or 3
162 parameters, but calls to malloc_src_loc() are always the same:
163
164 ... malloc_src_loc( size KMP_SRC_LOC_PARM ); // or KMP_SRC_LOC_CURR
165
166 Compiler issues warning/error "too few arguments in macro invocation". Declaring two
167 macroses, malloc_src_loc() and _malloc_src_loc() overcomes the problem.
168 */
169
170#if KMP_DEBUG
171
172 #if KMP_OS_WINDOWS && _DEBUG
173 // KMP_DEBUG != _DEBUG. MS debug RTL is available only if _DEBUG is defined.
174
175 // Windows* OS has native memory debugging capabilities. Enable them.
176
177 #include <crtdbg.h>
178
179 #define KMP_MEM_BLOCK _CLIENT_BLOCK
180 #define malloc( size ) _malloc_dbg( (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
181 #define calloc( num, size ) _calloc_dbg( (num), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
182 #define realloc( ptr, size ) _realloc_dbg( (ptr), (size), KMP_MEM_BLOCK, __FILE__, __LINE__ )
183 #define free( ptr ) _free_dbg( (ptr), KMP_MEM_BLOCK )
184
185 #define _malloc_src_loc( size, file, line ) _malloc_dbg( (size), KMP_MEM_BLOCK, (file), (line) )
186 #define _free_src_loc( ptr, file, line ) _free_dbg( (ptr), KMP_MEM_BLOCK )
187
188 #else
189
190 // Linux* OS, OS X*, or non-debug Windows* OS.
191
192 #define _malloc_src_loc( size, file, line ) malloc( (size) )
193 #define _free_src_loc( ptr, file, line ) free( (ptr) )
194
195 #endif
196
197#else
198
199 // In release build malloc_src_loc() and free_src_loc() do not have extra parameters.
200 #define _malloc_src_loc( size ) malloc( (size) )
201 #define _free_src_loc( ptr ) free( (ptr) )
202
203#endif // KMP_DEBUG
204
205#endif // KMP_WRAPPER_MALLOC_H
206
207// end of file //