libMesh
Loading...
Searching...
No Matches
reference_counter.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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
35namespace libMesh
36{
37
47{
48protected:
49
57
58
62 ReferenceCounter(ReferenceCounter && other) noexcept;
63
64public:
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
96protected:
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
125
126#endif
127
133
138
144};
145
146
147
148// ------------------------------------------------------------
149// ReferenceCounter class inline methods
154
155
156
158{
159 ++_n_objects;
160}
161
162
163
165{
166 ++_n_objects;
167}
168
169
170
175
176
177
178
179
180
181#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
182inline
183void 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)
206inline
207void 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
void ErrorVector unsigned int
streamT * get()
Rather than implement every ostream/ios/ios_base function, we'll be lazy and make esoteric uses go th...
This is the base class for enabling reference counting.
static std::string get_info()
Gets a string containing the reference information.
static void print_info(std::ostream &out_stream=libMesh::out)
Prints the reference information, by default to libMesh::out.
static unsigned int n_objects()
Prints the number of outstanding (created, but not yet destroyed) objects.
static void disable_print_counter_info()
void increment_destructor_count(const std::string &name) noexcept
Increments the destruction counter.
static Counts _counts
Actually holds the data.
static void enable_print_counter_info()
Methods to enable/disable the reference counter output from print_info().
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called.
static Threads::spin_mutex _mutex
Mutual exclusion object to enable thread-safe reference counting.
static Threads::atomic< unsigned int > _n_objects
The number of objects.
std::map< std::string, std::pair< unsigned int, unsigned int > > Counts
Data structure to log the information.
void increment_constructor_count(const std::string &name) noexcept
Increments the construction counter.
Defines atomic operations which can only be executed on a single thread at a time.
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition threads.C:30
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
OStreamProxy out