LCOV - code coverage report
Current view: top level - include/base - reference_counter.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 21 35 60.0 %
Date: 2025-08-19 19:27:09 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 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             : 
      38             : /**
      39             :  * This is the base class for enabling reference counting.  It
      40             :  * should not be used by the user, thus it has a private constructor.
      41             :  *
      42             :  * \author Benjamin S. Kirk
      43             :  * \date 2002-2007
      44             :  * \brief Common base for all objects whose creations/destructions are counted.
      45             :  */
      46             : class ReferenceCounter
      47             : {
      48             : protected:
      49             : 
      50             :   /**
      51             :    * Constructors. Protected so that you cannot
      52             :    * instantiate a \p ReferenceCounter, only derive
      53             :    * from it.
      54             :    */
      55             :   ReferenceCounter ();
      56             :   ReferenceCounter (const ReferenceCounter &);
      57             : 
      58             : 
      59             :   /**
      60             :    * Move constructor, must be declared noexcept.
      61             :    */
      62             :   ReferenceCounter(ReferenceCounter && other) noexcept;
      63             : 
      64             : public:
      65             : 
      66             :   /**
      67             :    * Destructor.
      68             :    */
      69             :   ~ReferenceCounter ();
      70             : 
      71             :   /**
      72             :    * Gets a string containing the reference information.
      73             :    */
      74             :   static std::string get_info ();
      75             : 
      76             :   /**
      77             :    * Prints the reference information, by default to \p libMesh::out.
      78             :    */
      79             :   static void print_info (std::ostream & out_stream = libMesh::out);
      80             : 
      81             :   /**
      82             :    * Prints the number of outstanding (created, but not yet
      83             :    * destroyed) objects.
      84             :    */
      85         462 :   static unsigned int n_objects ()
      86         462 :   { return _n_objects; }
      87             : 
      88             :   /**
      89             :    * Methods to enable/disable the reference counter output
      90             :    * from print_info()
      91             :    */
      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             : 
     100             :   /**
     101             :    * Increments the construction counter. Should be called in
     102             :    * the constructor of any derived class that will be
     103             :    * reference counted.
     104             :    */
     105             :   void increment_constructor_count (const std::string & name) noexcept;
     106             : 
     107             :   /**
     108             :    * Increments the destruction counter. Should be called in
     109             :    * the destructor of any derived class that will be
     110             :    * reference counted.
     111             :    */
     112             :   void increment_destructor_count (const std::string & name) noexcept;
     113             : 
     114             :   /**
     115             :    * Data structure to log the information.  The log is
     116             :    * identified by the class name.
     117             :    */
     118             :   typedef std::map<std::string, std::pair<unsigned int,
     119             :                                           unsigned int>> Counts;
     120             : 
     121             :   /**
     122             :    * Actually holds the data.
     123             :    */
     124             :   static Counts _counts;
     125             : 
     126             : #endif
     127             : 
     128             :   /**
     129             :    * The number of objects.  Print the reference count
     130             :    * information when the number returns to 0.
     131             :    */
     132             :   static Threads::atomic<unsigned int> _n_objects;
     133             : 
     134             :   /**
     135             :    * Mutual exclusion object to enable thread-safe reference counting.
     136             :    */
     137             :   static Threads::spin_mutex _mutex;
     138             : 
     139             :   /**
     140             :    * Flag to control whether reference count information
     141             :    * is printed when print_info is called.
     142             :    */
     143             :   static bool _enable_print_counter;
     144             : };
     145             : 
     146             : 
     147             : 
     148             : // ------------------------------------------------------------
     149             : // ReferenceCounter class inline methods
     150   880360428 : inline ReferenceCounter::ReferenceCounter()
     151             : {
     152  1566996938 :   ++_n_objects;
     153   880360428 : }
     154             : 
     155             : 
     156             : 
     157        1024 : inline ReferenceCounter::ReferenceCounter(const ReferenceCounter & /*other*/)
     158             : {
     159       29944 :   ++_n_objects;
     160        1024 : }
     161             : 
     162             : 
     163             : 
     164             : inline ReferenceCounter::ReferenceCounter(ReferenceCounter && /*other*/) noexcept
     165             : {
     166             :   ++_n_objects;
     167             : }
     168             : 
     169             : 
     170             : 
     171   190901715 : inline ReferenceCounter::~ReferenceCounter()
     172             : {
     173  4632454354 :   --_n_objects;
     174   190901715 : }
     175             : 
     176             : 
     177             : 
     178             : 
     179             : 
     180             : 
     181             : #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
     182             : inline
     183    42729276 : void ReferenceCounter::increment_constructor_count (const std::string & name) noexcept
     184             : {
     185             :   libmesh_try
     186             :   {
     187    42729276 :     Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     188    42729276 :     std::pair<unsigned int, unsigned int> & p = _counts[name];
     189    42729276 :     p.first++;
     190             :   }
     191           0 :   libmesh_catch (...)
     192             :   {
     193           0 :     auto stream = libMesh::err.get();
     194           0 :     stream->exceptions(stream->goodbit); // stream must not throw
     195           0 :     libMesh::err << "Encountered unrecoverable error while calling "
     196           0 :                  << "ReferenceCounter::increment_constructor_count() "
     197           0 :                  << "for a(n) " << name << " object." << std::endl;
     198           0 :     std::terminate();
     199             :   }
     200    42729276 : }
     201             : #endif
     202             : 
     203             : 
     204             : 
     205             : #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
     206             : inline
     207    12207561 : void ReferenceCounter::increment_destructor_count (const std::string & name) noexcept
     208             : {
     209             :   libmesh_try
     210             :   {
     211    12207561 :     Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     212    12207561 :     std::pair<unsigned int, unsigned int> & p = _counts[name];
     213    12207561 :     p.second++;
     214             :   }
     215           0 :   libmesh_catch (...)
     216             :   {
     217           0 :     auto stream = libMesh::err.get();
     218           0 :     stream->exceptions(stream->goodbit); // stream must not throw
     219           0 :     libMesh::err << "Encountered unrecoverable error while calling "
     220           0 :                  << "ReferenceCounter::increment_destructor_count() "
     221           0 :                  << "for a(n) " << name << " object." << std::endl;
     222           0 :     std::terminate();
     223             :   }
     224    12207561 : }
     225             : #endif
     226             : 
     227             : 
     228             : } // namespace libMesh
     229             : 
     230             : 
     231             : #endif // LIBMESH_REFERENCE_COUNTER_H

Generated by: LCOV version 1.14