Main MRPT website > C++ reference for MRPT 1.4.0
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-2016, 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
15namespace 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.
A generic system for versatile memory pooling.
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...
POOLABLE_DATA * request_memory(const DATA_PARAMS &params)
Request a block of data which fulfils the size requirements stated in params.
void setMemoryPoolMaxSize(const size_t maxNumEntries)
CGenericMemoryPool(const size_t max_pool_entries, bool &was_destroyed)
bool & m_was_destroyed
With this trick we get rid of the "global destruction order fiasco" ;-)
void dump_to_pool(const DATA_PARAMS &params, POOLABLE_DATA *block)
Saves the passed data block (characterized by params) to the pool.
mrpt::synch::CCriticalSection m_pool_cs
std::list< std::pair< DATA_PARAMS, POOLABLE_DATA * > > TList
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.



Page generated by Doxygen 1.9.5 for MRPT 1.4.0 SVN: at Tue Dec 27 00:54:45 UTC 2022