CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
memory_leak.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_UTILITY_MEMORY_LEAK_HPP
2 # define CPPAD_UTILITY_MEMORY_LEAK_HPP
3 
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 /*
15 $begin memory_leak$$
16 $spell
17  cppad
18  num
19  alloc
20  hpp
21  bool
22  inuse
23 $$
24 
25 $section Memory Leak Detection$$
26 $mindex memory_leak check static$$
27 
28 $head Deprecated 2012-04-06$$
29 This routine has been deprecated.
30 You should instead use the routine $cref ta_free_all$$.
31 
32 $head Syntax$$
33 $codei%# include <cppad/utility/memory_leak.hpp>
34 %$$
35 $icode%flag% = %memory_leak()
36 %$$
37 $icode%flag% = %memory_leak%(%add_static%)%$$
38 
39 $head Purpose$$
40 This routine checks that the are no memory leaks
41 caused by improper use of $cref thread_alloc$$ memory allocator.
42 The deprecated memory allocator $cref TrackNewDel$$ is also checked.
43 Memory errors in the deprecated $cref omp_alloc$$ allocator are
44 reported as being in $code thread_alloc$$.
45 
46 $head thread$$
47 It is assumed that $cref/in_parallel()/ta_in_parallel/$$ is false
48 and $cref/thread_num/ta_thread_num/$$ is zero when
49 $code memory_leak$$ is called.
50 
51 $head add_static$$
52 This argument has prototype
53 $codei%
54  size_t %add_static%
55 %$$
56 and its default value is zero.
57 Static variables hold onto memory forever.
58 If the argument $icode add_static$$ is present (and non-zero),
59 $code memory_leak$$ adds this amount of memory to the
60 $cref/inuse/ta_inuse/$$ sum that corresponds to
61 static variables in the program.
62 A call with $icode add_static$$ should be make after
63 a routine that has static variables which
64 use $cref/get_memory/ta_get_memory/$$ to allocate memory.
65 The value of $icode add_static$$ should be the difference of
66 $codei%
67  thread_alloc::inuse(0)
68 %$$
69 before and after the call.
70 Since multiple statics may be allocated in different places in the program,
71 it is expected that there will be multiple calls
72 that use this option.
73 
74 $head flag$$
75 The return value $icode flag$$ has prototype
76 $codei%
77  bool %flag%
78 %$$
79 If $icode add_static$$ is non-zero,
80 the return value for $code memory_leak$$ is false.
81 Otherwise, the return value for $code memory_leak$$ should be false
82 (indicating that the only allocated memory corresponds to static variables).
83 
84 $head inuse$$
85 It is assumed that, when $code memory_leak$$ is called,
86 there should not be any memory
87 $cref/inuse/ta_inuse/$$ or $cref omp_inuse$$ for any thread
88 (except for inuse memory corresponding to static variables).
89 If there is, a message is printed and $code memory_leak$$ returns false.
90 
91 $head available$$
92 It is assumed that, when $code memory_leak$$ is called,
93 there should not be any memory
94 $cref/available/ta_available/$$ or $cref omp_available$$ for any thread;
95 i.e., it all has been returned to the system.
96 If there is memory still available for any thread,
97 $code memory_leak$$ returns false.
98 
99 $head TRACK_COUNT$$
100 It is assumed that, when $code memory_leak$$ is called,
101 $cref/TrackCount/TrackNewDel/TrackCount/$$ will return a zero value.
102 If it returns a non-zero value,
103 $code memory_leak$$ returns false.
104 
105 $head Error Message$$
106 If this is the first call to $code memory_leak$$, no message is printed.
107 Otherwise, if it returns true, an error message is printed
108 to standard output describing the memory leak that was detected.
109 
110 $end
111 */
112 # include <iostream>
113 # include <cppad/core/define.hpp>
114 # include <cppad/utility/omp_alloc.hpp>
117 
118 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
119 /*!
120 \file memory_leak.hpp
121 File that implements a memory check at end of a CppAD program
122 */
123 
124 /*!
125 Function that checks
126 allocator \c thread_alloc for misuse that results in memory leaks.
127 Deprecated routines in track_new_del.hpp and omp_alloc.hpp are also checked.
128 
129 \param add_static [in]
130 The amount specified by \c add_static is added to the amount
131 of memory that is expected to be used by thread zero for static variables.
132 
133 \return
134 If \c add_static is non-zero, the return value is \c false.
135 Otherwise, if one of the following errors is detected,
136 the return value is \c true:
137 
138 \li
139 Thread zero does not have the expected amount of inuse memory
140 (for static variables).
141 \li
142 A thread, other than thread zero, has any inuse memory.
143 \li
144 Any thread has available memory.
145 
146 \par
147 If an error is detected, diagnostic information is printed to standard
148 output.
149 */
150 inline bool memory_leak(size_t add_static = 0)
151 { // CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL not necessary given asserts below
152  static size_t thread_zero_static_inuse = 0;
153  using std::cout;
154  using std::endl;
155  using CppAD::thread_alloc;
156  using CppAD::omp_alloc;
157  // --------------------------------------------------------------------
160  "memory_leak: in_parallel() is true."
161  );
164  "memory_leak: thread_num() is not zero."
165  );
166  if( add_static != 0 )
167  { thread_zero_static_inuse += add_static;
168  return false;
169  }
170  bool leak = false;
171  size_t thread = 0;
172 
173  // check that memory in use for thread zero corresponds to statics
174  size_t num_bytes = thread_alloc::inuse(thread);
175  if( num_bytes != thread_zero_static_inuse )
176  { leak = true;
177  cout << "thread zero: static inuse = " << thread_zero_static_inuse;
178  cout << ", current inuse(0)= " << num_bytes << endl;
179  }
180  // check that no memory is currently available for this thread
181  num_bytes = thread_alloc::available(thread);
182  if( num_bytes != 0 )
183  { leak = true;
184  cout << "thread zero: available = ";
185  cout << num_bytes << endl;
186  }
187  for(thread = 1; thread < CPPAD_MAX_NUM_THREADS; thread++)
188  {
189  // check that no memory is currently in use for this thread
190  num_bytes = thread_alloc::inuse(thread);
191  if( num_bytes != 0 )
192  { leak = true;
193  cout << "thread " << thread << ": inuse(thread) = ";
194  cout << num_bytes << endl;
195  }
196  // check that no memory is currently available for this thread
197  num_bytes = thread_alloc::available(thread);
198  if( num_bytes != 0 )
199  { leak = true;
200  cout << "thread " << thread << ": available(thread) = ";
201  cout << num_bytes << endl;
202  }
203  }
204  // ----------------------------------------------------------------------
205  // check track_new_del
206  if( CPPAD_TRACK_COUNT() != 0 )
207  { leak = true;
209  }
210  return leak;
211 }
212 
213 } // END_CPPAD_NAMESPACE
214 # endif
static void Print(void)
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
Define processor symbols and macros that are used by CppAD.
bool memory_leak(size_t add_static=0)
Function that checks allocator thread_alloc for misuse that results in memory leaks.
static size_t available(size_t thread)
Determine the amount of memory that is currently available for use.
#define CPPAD_TRACK_COUNT()
static bool in_parallel(void)
Are we in a parallel execution state; i.e., is it possible that other threads are currently executing...
static size_t inuse(size_t thread)
Determine the amount of memory that is currently inuse.
Capacity vector for memory allocation block sizes.
static size_t thread_num(void)
Get current thread number.
File used to define the CppAD multi-threading allocator class.