qpcpp/include/qmpool.hpp

181 lines
6.1 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
///***************************************************************************
2020-10-01 12:50:17 -04:00
/// Last updated for version 6.9.1
/// Last updated on 2020-09-14
2014-04-13 21:35:34 -04:00
///
2018-10-25 11:13:01 -04:00
/// Q u a n t u m L e a P s
/// ------------------------
/// Modern Embedded Software
2014-04-13 21:35:34 -04:00
///
2020-08-24 16:42:48 -04:00
/// Copyright (C) 2005-2020 Quantum Leaps. All rights reserved.
2014-04-13 21:35:34 -04:00
///
/// 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
2019-10-27 12:26:31 -04:00
/// along with this program. If not, see <www.gnu.org/licenses>.
2014-04-13 21:35:34 -04:00
///
/// Contact information:
2019-12-31 15:56:23 -05:00
/// <www.state-machine.com/licensing>
2019-10-27 12:26:31 -04:00
/// <info@state-machine.com>
2014-04-13 21:35:34 -04:00
///***************************************************************************
2015-05-14 16:05:04 -04:00
/// @endcond
2012-08-14 18:00:48 -04:00
2019-10-27 12:26:31 -04:00
#ifndef QMPOOL_HPP
#define QMPOOL_HPP
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.
2020-03-17 21:33:58 -04:00
/// Valid values 1U, 2U, or 4U; default 2U
#define QF_MPOOL_SIZ_SIZE 2U
2012-08-14 18:00:48 -04:00
#endif
#ifndef QF_MPOOL_CTR_SIZE
2014-04-13 21:35:34 -04:00
//! macro to override the default QMPoolCtr size.
2020-03-17 21:33:58 -04:00
//! Valid values 1U, 2U, or 4U; default 2U
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 {
2020-03-17 21:33:58 -04:00
#if (QF_MPOOL_SIZ_SIZE == 1U)
using QMPoolSize = std::uint8_t;
#elif (QF_MPOOL_SIZ_SIZE == 2U)
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.
2020-03-17 21:33:58 -04:00
using QMPoolSize = std::uint16_t;
#elif (QF_MPOOL_SIZ_SIZE == 4U)
using QMPoolSize = std::uint32_t;
2012-08-14 18:00:48 -04:00
#else
2020-03-17 21:33:58 -04:00
#error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U"
2012-08-14 18:00:48 -04:00
#endif
2020-03-17 21:33:58 -04:00
#if (QF_MPOOL_CTR_SIZE == 1U)
using QMPoolCtr = std::uint8_t;
#elif (QF_MPOOL_CTR_SIZE == 2U)
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.
2020-03-17 21:33:58 -04:00
using QMPoolCtr = std::uint16_t;
#elif (QF_MPOOL_CTR_SIZE == 4U)
using QMPoolCtr = std::uint32_t;
2012-08-14 18:00:48 -04:00
#else
2020-03-17 21:33:58 -04:00
#error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U"
2012-08-14 18:00:48 -04:00
#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
2020-03-17 21:33:58 -04:00
void init(void * const poolSto, std::uint_fast32_t poolSize,
std::uint_fast16_t blockSize) noexcept;
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! Obtains a memory block from a memory pool.
2020-10-01 12:50:17 -04:00
void *get(std::uint_fast16_t const margin,
std::uint_fast8_t const qs_id) noexcept;
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.
2020-10-01 12:50:17 -04:00
void put(void * const b, std::uint_fast8_t const qs_id) noexcept;
2012-08-14 18:00:48 -04:00
2014-04-13 21:35:34 -04:00
//! return the fixed block-size of the blocks managed by this pool
2020-03-17 21:33:58 -04:00
QMPoolSize getBlockSize(void) const noexcept {
2012-08-14 18:00:48 -04:00
return m_blockSize;
}
2018-01-10 18:26:05 -05:00
// duplicated API to be used exclusively inside ISRs (useful in some QP ports)
#ifdef QF_ISR_API
2020-10-01 12:50:17 -04:00
void *getFromISR(std::uint_fast16_t const margin,
std::uint_fast8_t const qs_id) noexcept;
void putFromISR(void * const b,
std::uint_fast8_t const qs_id) noexcept;
2018-01-10 18:26:05 -05:00
#endif // QF_ISR_API
2012-08-14 18:00:48 -04:00
private:
2020-03-17 21:33:58 -04:00
//! disallow copying of QMPools
QMPool(QMPool const &) = delete;
//!< disallow assigning of QMPools
QMPool &operator=(QMPool const &) = delete;
2013-12-30 17:41:15 -05:00
2012-08-14 18:00:48 -04:00
friend class QF;
2018-10-25 11:13:01 -04:00
friend class QS;
2012-08-14 18:00:48 -04:00
};
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]; }
2019-10-27 12:26:31 -04:00
#endif // QMPOOL_HPP
2018-03-19 14:51:26 -04:00