libMesh
reference_counter.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_REFERENCE_COUNTER_H
21 #define LIBMESH_REFERENCE_COUNTER_H
22 
23 // Local includes
24 #include "libmesh/libmesh_config.h"
25 #include "libmesh/threads.h"
26 #include "libmesh/libmesh.h" // libMesh::on_command_line
27 #include "libmesh/libmesh_exceptions.h" // libmesh_try, libmesh_catch
28 
29 // C++ includes
30 #include <iostream>
31 #include <string>
32 #include <map>
33 #include <exception> // std::terminate
34 
35 namespace libMesh
36 {
37 
47 {
48 protected:
49 
57 
58 
62  ReferenceCounter(ReferenceCounter && other) noexcept;
63 
64 public:
65 
70 
74  static std::string get_info ();
75 
79  static void print_info (std::ostream & out_stream = libMesh::out);
80 
85  static unsigned int n_objects ()
86  { return _n_objects; }
87 
92  static void enable_print_counter_info();
93  static void disable_print_counter_info();
94 
95 
96 protected:
97 
98 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
99 
105  void increment_constructor_count (const std::string & name) noexcept;
106 
112  void increment_destructor_count (const std::string & name) noexcept;
113 
118  typedef std::map<std::string, std::pair<unsigned int,
119  unsigned int>> Counts;
120 
124  static Counts _counts;
125 
126 #endif
127 
133 
138 
144 };
145 
146 
147 
148 // ------------------------------------------------------------
149 // ReferenceCounter class inline methods
151 {
152  ++_n_objects;
153 }
154 
155 
156 
158 {
159  ++_n_objects;
160 }
161 
162 
163 
165 {
166  ++_n_objects;
167 }
168 
169 
170 
172 {
173  --_n_objects;
174 }
175 
176 
177 
178 
179 
180 
181 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
182 inline
183 void ReferenceCounter::increment_constructor_count (const std::string & name) noexcept
184 {
185  libmesh_try
186  {
187  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
188  std::pair<unsigned int, unsigned int> & p = _counts[name];
189  p.first++;
190  }
191  libmesh_catch (...)
192  {
193  auto stream = libMesh::err.get();
194  stream->exceptions(stream->goodbit); // stream must not throw
195  libMesh::err << "Encountered unrecoverable error while calling "
196  << "ReferenceCounter::increment_constructor_count() "
197  << "for a(n) " << name << " object." << std::endl;
198  std::terminate();
199  }
200 }
201 #endif
202 
203 
204 
205 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
206 inline
207 void ReferenceCounter::increment_destructor_count (const std::string & name) noexcept
208 {
209  libmesh_try
210  {
211  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
212  std::pair<unsigned int, unsigned int> & p = _counts[name];
213  p.second++;
214  }
215  libmesh_catch (...)
216  {
217  auto stream = libMesh::err.get();
218  stream->exceptions(stream->goodbit); // stream must not throw
219  libMesh::err << "Encountered unrecoverable error while calling "
220  << "ReferenceCounter::increment_destructor_count() "
221  << "for a(n) " << name << " object." << std::endl;
222  std::terminate();
223  }
224 }
225 #endif
226 
227 
228 } // namespace libMesh
229 
230 
231 #endif // LIBMESH_REFERENCE_COUNTER_H
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
OStreamProxy err
static Threads::atomic< unsigned int > _n_objects
The number of objects.
static unsigned int n_objects()
Prints the number of outstanding (created, but not yet destroyed) objects.
void increment_constructor_count(const std::string &name) noexcept
Increments the construction counter.
static void print_info(std::ostream &out_stream=libMesh::out)
Prints the reference information, by default to libMesh::out.
The libMesh namespace provides an interface to certain functionality in the library.
std::map< std::string, std::pair< unsigned int, unsigned int > > Counts
Data structure to log the information.
static std::string get_info()
Gets a string containing the reference information.
This is the base class for enabling reference counting.
static Threads::spin_mutex _mutex
Mutual exclusion object to enable thread-safe reference counting.
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called...
static void enable_print_counter_info()
Methods to enable/disable the reference counter output from print_info()
ReferenceCounter()
Constructors.
void increment_destructor_count(const std::string &name) noexcept
Increments the destruction counter.
static Counts _counts
Actually holds the data.
OStreamProxy out
streamT * get()
Rather than implement every ostream/ios/ios_base function, we&#39;ll be lazy and make esoteric uses go th...
static void disable_print_counter_info()
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition: threads.C:30