LCOV - code coverage report
Current view: top level - atermpp/include/mcrl2/atermpp/detail - aterm_pool.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 21 21 100.0 %
Date: 2024-04-19 03:43:27 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Maurice Laveaux.
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : 
      10             : #ifndef ATERMPP_DETAIL_ATERM_POOL_H
      11             : #define ATERMPP_DETAIL_ATERM_POOL_H
      12             : 
      13             : #include "mcrl2/atermpp/detail/aterm_pool_storage.h"
      14             : #include "mcrl2/atermpp/detail/function_symbol_pool.h"
      15             : 
      16             : #include "mcrl2/utilities/shared_mutex.h"
      17             : 
      18             : namespace atermpp
      19             : {
      20             : namespace detail
      21             : {
      22             : 
      23             : /// Define several specializations of the term pool storage objects.
      24             : using integer_term_storage = aterm_pool_storage<_aterm_int, aterm_int_hasher, aterm_int_equals, 0>;
      25             : using term_storage = aterm_pool_storage<_aterm, aterm_hasher_finite<0>, aterm_equals_finite<0>, 0>;
      26             : using arbitrary_function_application_storage = aterm_pool_storage<_aterm_appl<1>,
      27             :   aterm_hasher<DynamicNumberOfArguments>,
      28             :   aterm_equals<DynamicNumberOfArguments>,
      29             :   DynamicNumberOfArguments>;
      30             : 
      31             : template<std::size_t N>
      32             : using function_application_storage = aterm_pool_storage<_aterm_appl<N>, aterm_hasher_finite<N>, aterm_equals_finite<N>, N>;
      33             : 
      34             : // There are some annoying circular dependencies between a aterm_pool and the contained thread_aterm_pool_interfaces
      35             : class aterm_pool;
      36             : 
      37             : /// \brief A thread specific aterm pool that provides a local interface to the global term pool.
      38             : ///        Ensures that terms created by this thread are protected during garbage collection.
      39             : class thread_aterm_pool_interface final
      40             : {
      41             : public:
      42             :   thread_aterm_pool_interface(aterm_pool& pool, std::function<void()> mark_function, std::function<void()> print_function, std::function<std::size_t()> protection_set_size_function);
      43             :   ~thread_aterm_pool_interface();
      44             : 
      45             :   /// \brief Mark the terms created by this thread to prevent them being garbage collected.
      46        1917 :   void mark()
      47             :   {
      48        1917 :     m_mark_function();
      49        1917 :   }
      50             : 
      51             :   /// \brief Print performance statistics for data stored for this thread.
      52        1917 :   void print_local_performance_statistics() const
      53             :   {
      54        1917 :     m_print_function();
      55        1917 :   }
      56             : 
      57             :   /// \returns The total number of terms residing in the pool.
      58        1917 :   std::size_t protection_set_size() const 
      59             :   {
      60        1917 :     return m_protection_set_size_function();
      61             :   }
      62             : 
      63             : private:
      64             :   aterm_pool& m_pool;
      65             :   std::function<void()> m_mark_function;
      66             :   std::function<void()> m_print_function;
      67             :   std::function<std::size_t()> m_protection_set_size_function;
      68             : };
      69             : 
      70             : class thread_aterm_pool;
      71             : 
      72             : /// \brief The interface for the term library. Provides the storage of
      73             : ///        of all classes of terms.
      74             : /// \details Internally uses different storage objects to store specific
      75             : ///          classes of terms. For a given term creation it can decide what
      76             : ///          storage to use at run-time using its function symbol.
      77             : class aterm_pool : public mcrl2::utilities::noncopyable
      78             : {
      79             : public:
      80             :   inline aterm_pool();
      81             :   inline ~aterm_pool();
      82             : 
      83             :   friend class thread_aterm_pool;
      84             : 
      85             :   /// \brief Creates a function symbol pair (name, arity).
      86             :   /// \see function_symbol_pool.
      87             :   inline function_symbol create_function_symbol(const std::string& name, const std::size_t arity, const bool check_for_registered_functions = false);
      88             : 
      89             :   /// \brief Creates a function symbol pair (name, arity).
      90             :   /// \see function_symbol_pool.
      91             :   inline function_symbol create_function_symbol(std::string&& name, const std::size_t arity, const bool check_for_registered_functions = false);
      92             : 
      93             :   /// \brief Register a thread specific aterm pool.
      94             :   /// \details threadsafe
      95             :   inline void register_thread_aterm_pool(thread_aterm_pool_interface& pool);
      96             : 
      97             :   /// \brief Remove thread specific aterm pool.
      98             :   /// \details threadsafe
      99             :   inline void remove_thread_aterm_pool(thread_aterm_pool_interface& pool);
     100             : 
     101             :   /// \brief The number of terms that can be stored without resizing.
     102             :   inline std::size_t capacity() const noexcept;
     103             : 
     104             :   /// \returns The total number of terms residing in the pool.
     105             :   inline std::size_t size() const;
     106             : 
     107             :   /// \brief Prints various performance statistics for the term pool.
     108             :   inline void print_performance_statistics() const;
     109             : 
     110             :   /// \returns A global term that indicates the empty list.
     111  2382669211 :   aterm& empty_list() noexcept { return m_empty_list; }
     112             : 
     113             :   /// \returns The function symbol used by integral terms.
     114         143 :   const function_symbol& as_int() noexcept { return m_function_symbol_pool.as_int(); }
     115             : 
     116             :   /// \returns The function symbol used by the list constructor.
     117  6927179666 :   const function_symbol& as_list() noexcept { return m_function_symbol_pool.as_list(); }
     118             : 
     119             :   /// \returns The function symbol used by the term indicating the empty list.
     120  2379951465 :   const function_symbol& as_empty_list() noexcept { return m_function_symbol_pool.as_empty_list(); }
     121             : 
     122             :   /// \brief Add a callback that is triggered whenever a term with the given function symbol is destroyed.
     123             :   inline void add_deletion_hook(function_symbol sym, term_callback callback);
     124             : 
     125             :   /// \brief Enable garbage collection when passing true and disable otherwise.
     126             :   inline void enable_garbage_collection(bool enable) { m_enable_garbage_collection = enable; };
     127             : 
     128        5223 :   inline function_symbol_pool& get_symbol_pool() { return m_function_symbol_pool; }
     129             : 
     130             :   // These functions of the aterm pool should be called through a thread_aterm_pool.
     131             : private:
     132             :   /// \brief Force garbage collection on all storages.
     133             :   /// \details threadsafe
     134             :   inline void collect(mcrl2::utilities::shared_mutex& mutex);
     135             : 
     136             :   /// \brief Triggers garbage collection and resizing when conditions are met.
     137             :   /// \param allow_collect Actually perform the garbage collection instead of only updating the counters.
     138             :   /// \param mutex The shared mutex that should be used for locking if necessary.
     139             :   /// \details threadsafe
     140             :   inline void created_term(bool allow_collect, mcrl2::utilities::shared_mutex& mutex);
     141             : 
     142             :   /// \brief Collect garbage on all storages.
     143             :   /// \details threadsafe
     144             :   inline void collect_impl(mcrl2::utilities::shared_mutex& mutex);
     145             : 
     146             :   /// \brief Creates a integral term with the given value.
     147             :   inline bool create_int(aterm& term, std::size_t val);
     148             : 
     149             :   /// \brief Creates a term with the given function symbol.
     150             :   inline bool create_term(aterm& term, const function_symbol& sym);
     151             : 
     152             :   /// \brief Creates a function application with the given function symbol and arguments.
     153             :   template<class ...Terms>
     154             :   inline bool create_appl(aterm& term, const function_symbol& sym, const Terms&... arguments);
     155             : 
     156             :   /// \brief Creates a function application with the given function symbol and the arguments
     157             :   ///       as provided by the given iterator. This function assumes that the arity of the
     158             :   ///       function symbol is equal to the number of elements in the iterator.
     159             :   template<typename ForwardIterator>
     160             :   bool create_appl_dynamic(aterm& term,
     161             :       const function_symbol& sym,
     162             :       ForwardIterator begin,
     163             :       ForwardIterator end);
     164             : 
     165             :   /// \brief Creates a function application with the given function symbol and the arguments
     166             :   ///       as provided by the given iterator. This function assumes that the arity of the
     167             :   ///       function symbol is equal to the number of elements in the iterator.
     168             :   template<typename InputIterator, typename ATermConverter>
     169             :   bool create_appl_dynamic(aterm& term,
     170             :       const function_symbol& sym,
     171             :       ATermConverter convert_to_aterm,
     172             :       InputIterator begin,
     173             :       InputIterator end);
     174             : 
     175             :   /// \brief Resizes all storages if necessary.
     176             :   /// \details threadsafe
     177             :   inline void resize_if_needed(mcrl2::utilities::shared_mutex& shared);
     178             : 
     179         144 :   mcrl2::utilities::shared_mutex& shared_mutex() { return m_shared_mutex; }
     180             : 
     181             :   /// \returns The total number of term variables residing in the protection sets.
     182             :   inline std::size_t protection_set_size() const;
     183             : 
     184             :   /// \brief The set of local aterm pools.
     185             :   std::vector<thread_aterm_pool_interface* > m_thread_pools;
     186             : 
     187             :   /// \brief Storage for the function symbols.
     188             :   function_symbol_pool m_function_symbol_pool;
     189             : 
     190             :   /// \brief Storage for integral terms.
     191             :   integer_term_storage m_int_storage;
     192             : 
     193             :   /// Storage for function applications with a fixed number of arguments.
     194             :   std::tuple<
     195             :     term_storage,
     196             :     function_application_storage<1>,
     197             :     function_application_storage<2>,
     198             :     function_application_storage<3>,
     199             :     function_application_storage<4>,
     200             :     function_application_storage<5>,
     201             :     function_application_storage<6>,
     202             :     function_application_storage<7>
     203             :   > m_appl_storage;
     204             : 
     205             :   /// Storage for term_appl with a dynamic number of arguments larger than 7.
     206             :   arbitrary_function_application_storage m_appl_dynamic_storage;
     207             : 
     208             :   /// Track the number of terms destroyed and reduce the freelist.
     209             :   std::atomic<long> m_count_until_collection = 0;
     210             :   std::atomic<long> m_count_until_resize = 0;
     211             : 
     212             :   std::atomic<bool> m_enable_garbage_collection = EnableGarbageCollection; /// Garbage collection is enabled.
     213             : 
     214             :   /// All the shared mutexes.
     215             :   mcrl2::utilities::shared_mutex m_shared_mutex;
     216             : 
     217             :   /// Represents an empty list.
     218             :   aterm m_empty_list;
     219             : };
     220             : 
     221             : inline
     222         144 : thread_aterm_pool_interface::thread_aterm_pool_interface(aterm_pool& pool, std::function<void()> mark_function, std::function<void()> print_function, std::function<std::size_t()> protection_set_size_function)
     223         144 :   : m_pool(pool), m_mark_function(mark_function), m_print_function(print_function), m_protection_set_size_function(protection_set_size_function)
     224             : {
     225         144 :   m_pool.register_thread_aterm_pool(*this);
     226         144 : }
     227             : 
     228             : inline
     229         144 : thread_aterm_pool_interface::~thread_aterm_pool_interface()
     230             : {
     231         144 :   m_pool.remove_thread_aterm_pool(*this);
     232         144 : }
     233             : 
     234             : } // namespace detail
     235             : } // namespace atermpp
     236             : 
     237             : #include "aterm_pool_implementation.h"
     238             : #include "aterm_pool_storage_implementation.h"
     239             : 
     240             : #endif // ATERMPP_DETAIL_ATERM_POOL_H

Generated by: LCOV version 1.14