Main MRPT website > C++ reference for MRPT 1.5.7
CGenericMemoryPool.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef MRPT_MEMORY_POOL_H
10 #define MRPT_MEMORY_POOL_H
11 
13 #include <list>
14 
15 namespace mrpt
16 {
17  namespace system
18  {
19  /** A generic system for versatile memory pooling.
20  * This class implements the singleton pattern so a unique instance exists for each combination of template parameters.
21  * All methods are thread-safe.
22  *
23  * Basic usage:
24  * - When needed, call \a request_memory() to check the availability of memory in the pool.
25  * - At your class destructor, donate the memory to the pool with \a dump_to_pool().
26  *
27  * Notice that memory requests are checked against memory blocks in the pool via a user-defined function:
28  *
29  * bool POOLABLE_DATA::isSuitable(const POOLABLE_DATA & req) const { ... }
30  *
31  * For an example of how to handle a memory pool, see the class mrpt::obs::CObservation3DRangeScan
32  *
33  * \tparam POOLABLE_DATA A struct with user-defined objects which actually contain the memory blocks (e.g. one or more std::vector).
34  * \tparam DATA_PARAMS A struct with user information about each memory block (e.g. size of a std::vector)
35  * \ingroup mrpt_memory
36  */
37  template <class DATA_PARAMS,class POOLABLE_DATA>
39  {
40  private:
41  typedef std::list<std::pair<DATA_PARAMS,POOLABLE_DATA*> > TList;
45  bool & m_was_destroyed; //!< With this trick we get rid of the "global destruction order fiasco" ;-)
46 
47  CGenericMemoryPool(const size_t max_pool_entries, bool &was_destroyed ) : m_maxPoolEntries(max_pool_entries), m_was_destroyed(was_destroyed)
48  {
49  m_was_destroyed = false;
50  }
51 
52  public:
53  inline size_t getMemoryPoolMaxSize() const { return m_maxPoolEntries; }
54  inline void setMemoryPoolMaxSize(const size_t maxNumEntries) { m_maxPoolEntries = maxNumEntries; }
55 
56  /** Construct-on-first-use (~singleton) pattern: Return the unique instance of this class for a given template arguments,
57  * or NULL if it was once created but it's been destroyed (which means we're in the program global destruction phase).
58  */
59  static CGenericMemoryPool<DATA_PARAMS,POOLABLE_DATA> * getInstance(const size_t max_pool_entries = 5)
60  {
61  static bool was_destroyed = false;
62  static CGenericMemoryPool<DATA_PARAMS,POOLABLE_DATA> inst(max_pool_entries, was_destroyed);
63  return was_destroyed ? NULL : &inst;
64  }
65 
66  /** Request a block of data which fulfils the size requirements stated in \a params.
67  * Notice that the decision on the suitability of each pool'ed block is done by DATA_PARAMS::isSuitable().
68  * \return The block of data, or NULL if none suitable was found in the pool.
69  * \note It is a responsibility of the user to free with "delete" the "POOLABLE_DATA" object itself once the memory has been extracted from its elements.
70  */
71  POOLABLE_DATA * request_memory(const DATA_PARAMS &params)
72  {
73  // A quick check first:
74  if (m_pool.empty()) return NULL;
75 
77  for (typename TList::iterator it=m_pool.begin();it!=m_pool.end();++it) {
78  if (it->first.isSuitable(params))
79  {
80  POOLABLE_DATA * ret = it->second;
81  m_pool.erase(it);
82  return ret;
83  }
84  }
85  return NULL;
86  }
87 
88  /** Saves the passed data block (characterized by \a params) to the pool.
89  * If the overall size of the pool is above the limit, the oldest entry is removed.
90  * \note It is a responsibility of the user to allocate in dynamic memory the "POOLABLE_DATA" object with "new".
91  */
92  void dump_to_pool(const DATA_PARAMS &params, POOLABLE_DATA *block)
93  {
95 
96  while (m_pool.size()>=m_maxPoolEntries) // Free old data if needed
97  {
98  if (m_pool.begin()->second) delete m_pool.begin()->second;
99  m_pool.erase(m_pool.begin());
100  }
101 
102  m_pool.push_back( typename TList::value_type(params,block) );
103  }
104 
106  {
107  m_was_destroyed = true;
108  // Free remaining memory blocks:
110  for (typename TList::iterator it=m_pool.begin();it!=m_pool.end();++it)
111  delete it->second;
112  m_pool.clear();
113  }
114  };
115 
116  } // End of namespace
117 } // End of namespace
118 
119 #endif
This class provides simple critical sections functionality.
A class acquiring a CCriticalSection at its constructor, and releasing it at destructor.
mrpt::synch::CCriticalSection m_pool_cs
void dump_to_pool(const DATA_PARAMS &params, POOLABLE_DATA *block)
Saves the passed data block (characterized by params) to the pool.
Scalar * iterator
Definition: eigen_plugins.h:23
std::list< std::pair< DATA_PARAMS, POOLABLE_DATA * > > TList
POOLABLE_DATA * request_memory(const DATA_PARAMS &params)
Request a block of data which fulfils the size requirements stated in params.
A generic system for versatile memory pooling.
void setMemoryPoolMaxSize(const size_t maxNumEntries)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool & m_was_destroyed
With this trick we get rid of the "global destruction order fiasco" ;-)
static CGenericMemoryPool< DATA_PARAMS, POOLABLE_DATA > * getInstance(const size_t max_pool_entries=5)
Construct-on-first-use (~singleton) pattern: Return the unique instance of this class for a given tem...
CGenericMemoryPool(const size_t max_pool_entries, bool &was_destroyed)
GLenum const GLfloat * params
Definition: glext.h:3514



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019