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