qpcpp/include/qmpool.h

167 lines
5.6 KiB
C
Raw Normal View History

2015-05-14 16:05:04 -04:00
/// @file
/// @brief platform-independent memory pool QP::QMPool interface.
/// @ingroup qf
/// @cond
2014-04-13 21:35:34 -04:00
///***************************************************************************
2015-05-14 16:05:04 -04:00
/// Last updated for version 5.4.0
/// Last updated on 2015-04-29
2014-04-13 21:35:34 -04:00
///
/// Q u a n t u m L e a P s
/// ---------------------------
/// innovating embedded systems
///
/// Copyright (C) Quantum Leaps, www.state-machine.com.
///
/// This program is open source software: you can redistribute it and/or
/// modify it under the terms of the GNU General Public License as published
/// by the Free Software Foundation, either version 3 of the License, or
/// (at your option) any later version.
2012-08-14 18:00:48 -04:00
///
2014-04-13 21:35:34 -04:00
/// Alternatively, this program may be distributed and modified under the
/// terms of Quantum Leaps commercial licenses, which expressly supersede
/// the GNU General Public License and are specifically designed for
/// licensees interested in retaining the proprietary status of their code.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with this program. If not, see <http://www.gnu.org/licenses/>.
///
/// Contact information:
/// Web: www.state-machine.com
/// Email: info@state-machine.com
///***************************************************************************
2015-05-14 16:05:04 -04:00
/// @endcond
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
#ifndef qmpool_h
#define qmpool_h
2013-10-10 20:01:51 -04:00
2012-08-14 18:00:48 -04:00
#ifndef QF_MPOOL_SIZ_SIZE
2014-04-13 21:35:34 -04:00
//! macro to override the default QP::QMPoolSize size.
2012-08-14 18:00:48 -04:00
/// Valid values 1, 2, or 4; default 2
#define QF_MPOOL_SIZ_SIZE 2
#endif
#ifndef QF_MPOOL_CTR_SIZE
2014-04-13 21:35:34 -04:00
//! macro to override the default QMPoolCtr size.
//! Valid values 1, 2, or 4; default 2
2012-08-14 18:00:48 -04:00
#define QF_MPOOL_CTR_SIZE 2
#endif
2013-10-10 20:01:51 -04:00
namespace QP {
2012-08-14 18:00:48 -04:00
#if (QF_MPOOL_SIZ_SIZE == 1)
2013-10-10 20:01:51 -04:00
typedef uint8_t QMPoolSize;
#elif (QF_MPOOL_SIZ_SIZE == 2)
2014-04-13 21:35:34 -04:00
//! The data type to store the block-size based on the macro
//! #QF_MPOOL_SIZ_SIZE.
2015-05-14 16:05:04 -04:00
/// @description
2012-08-14 18:00:48 -04:00
/// The dynamic range of this data type determines the maximum size
/// of blocks that can be managed by the native QF event pool.
typedef uint16_t QMPoolSize;
#elif (QF_MPOOL_SIZ_SIZE == 4)
typedef uint32_t QMPoolSize;
#else
#error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1, 2, or 4"
#endif
#if (QF_MPOOL_CTR_SIZE == 1)
2013-10-10 20:01:51 -04:00
typedef uint8_t QMPoolCtr;
#elif (QF_MPOOL_CTR_SIZE == 2)
2014-04-13 21:35:34 -04:00
//! The data type to store the block-counter based on the macro
//! #QF_MPOOL_CTR_SIZE.
2015-05-14 16:05:04 -04:00
/// @description
2012-08-14 18:00:48 -04:00
/// The dynamic range of this data type determines the maximum number
/// of blocks that can be stored in the pool.
typedef uint16_t QMPoolCtr;
#elif (QF_MPOOL_CTR_SIZE == 4)
typedef uint32_t QMPoolCtr;
#else
#error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
#endif
2013-10-10 20:01:51 -04:00
//****************************************************************************
2014-04-13 21:35:34 -04:00
//! Native QF memory pool class
2015-05-14 16:05:04 -04:00
/// @description
2014-04-13 21:35:34 -04:00
/// A fixed block-size memory pool is a very fast and efficient data
/// structure for dynamic allocation of fixed block-size chunks of memory.
/// A memory pool offers fast and deterministic allocation and recycling of
2015-05-14 16:05:04 -04:00
/// memory blocks and is not subject to fragmenation.@n
/// @n
2014-04-13 21:35:34 -04:00
/// The QP::QMPool class describes the native QF memory pool, which can be
/// used as the event pool for dynamic event allocation, or as a fast,
/// deterministic fixed block-size heap for any other objects in your
/// application.
2012-08-14 18:00:48 -04:00
///
2015-05-14 16:05:04 -04:00
/// @note
2014-04-13 21:35:34 -04:00
/// The QP::QMPool class contains only data members for managing a memory
2012-08-14 18:00:48 -04:00
/// pool, but does not contain the pool storage, which must be provided
/// externally during the pool initialization.
///
2015-05-14 16:05:04 -04:00
/// @note
2012-08-14 18:00:48 -04:00
/// The native QF event pool is configured by defining the macro
2014-04-13 21:35:34 -04:00
/// #QF_EPOOL_TYPE_ as QP::QMPool in the specific QF port header file.
2012-08-14 18:00:48 -04:00
class QMPool {
private:
2014-04-13 21:35:34 -04:00
//! start of the memory managed by this memory pool
2012-08-14 18:00:48 -04:00
void *m_start;
2014-04-13 21:35:34 -04:00
//! end of the memory managed by this memory pool
2012-08-14 18:00:48 -04:00
void *m_end;
2014-04-13 21:35:34 -04:00
//! head of linked list of free blocks
2013-10-10 20:01:51 -04:00
void * volatile m_free_head;
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! maximum block size (in bytes)
2012-08-14 18:00:48 -04:00
QMPoolSize m_blockSize;
2014-04-13 21:35:34 -04:00
//! total number of blocks
2012-08-14 18:00:48 -04:00
QMPoolCtr m_nTot;
2014-04-13 21:35:34 -04:00
//! number of free blocks remaining
2013-10-10 20:01:51 -04:00
QMPoolCtr volatile m_nFree;
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! minimum number of free blocks ever present in this pool
2015-05-14 16:05:04 -04:00
/// @note
2014-04-13 21:35:34 -04:00
/// This attribute remembers the low watermark of the pool,
2012-08-14 18:00:48 -04:00
/// which provides a valuable information for sizing event pools.
2014-04-13 21:35:34 -04:00
///
2015-05-14 16:05:04 -04:00
/// @sa QP::QF::getPoolMin().
2012-08-14 18:00:48 -04:00
QMPoolCtr m_nMin;
public:
2014-04-13 21:35:34 -04:00
QMPool(void); //!< public default constructor
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! Initializes the native QF event pool
2015-05-14 16:05:04 -04:00
void init(void * const poolSto, uint_fast32_t poolSize,
2014-04-13 21:35:34 -04:00
uint_fast16_t blockSize);
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! Obtains a memory block from a memory pool.
void *get(uint_fast16_t const margin);
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! Returns a memory block back to a memory pool.
2012-08-14 18:00:48 -04:00
void put(void * const b);
2014-04-13 21:35:34 -04:00
//! return the fixed block-size of the blocks managed by this pool
2012-08-14 18:00:48 -04:00
QMPoolSize getBlockSize(void) const {
return m_blockSize;
}
private:
2014-04-13 21:35:34 -04:00
QMPool(QMPool const &); //!< disallow copying of QMPools
QMPool &operator=(QMPool const &); //!< disallow assigning of QMPools
2013-12-30 17:41:15 -05:00
2012-08-14 18:00:48 -04:00
friend class QF;
};
2014-04-13 21:35:34 -04:00
} // namespace QP
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! Memory pool element to allocate correctly aligned storage for QP::QMPool
2012-08-14 18:00:48 -04:00
#define QF_MPOOL_EL(type_) \
struct { void *sto_[((sizeof(type_) - 1U)/sizeof(void*)) + 1U]; }
2014-04-13 21:35:34 -04:00
#endif // qmpool_h