//$file${include::qxk.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // // Model: qpcpp.qm // File: ${include::qxk.hpp} // // This code has been generated by QM 6.1.1 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // // This code is covered by the following QP license: // License # : LicenseRef-QL-dual // Issued to : Any user of the QP/C++ real-time embedded framework // Framework(s) : qpcpp // Support ends : 2024-12-31 // License scope: // // Copyright (C) 2005 Quantum Leaps, LLC . // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // // This software is dual-licensed under the terms of the open source GNU // General Public License version 3 (or any later version), or alternatively, // under the terms of one of the closed source Quantum Leaps commercial // licenses. // // The terms of the open source GNU General Public License version 3 // can be found at: // // The terms of the closed source Quantum Leaps commercial licenses // can be found at: // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // // Contact information: // // // //$endhead${include::qxk.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifndef QXK_HPP_ #define QXK_HPP_ //$declare${QXK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { //${QXK::QSchedStatus} ....................................................... using QSchedStatus = std::uint_fast16_t; } // namespace QP //$enddecl${QXK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$declare${QXK::QXTHREAD_NO_TIMEOUT} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { //${QXK::QXTHREAD_NO_TIMEOUT} ................................................ constexpr QTimeEvtCtr QXTHREAD_NO_TIMEOUT {0U}; } // namespace QP //$enddecl${QXK::QXTHREAD_NO_TIMEOUT} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$declare${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { namespace QXK { //${QXK::QXK-base::onIdle} ................................................... void onIdle(); //${QXK::QXK-base::schedLock} ................................................ QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept; //${QXK::QXK-base::schedUnlock} .............................................. void schedUnlock(QSchedStatus const stat) noexcept; //${QXK::QXK-base::current} .................................................. QP::QActive * current() noexcept; } // namespace QXK } // namespace QP //$enddecl${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$declare${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { //${QXK::QXThread} ........................................................... class QXThread : public QP::QActive { private: QTimeEvt m_timeEvt; public: friend class QActive; friend class QTimeEvt; friend class QXSemaphore; friend class QXMutex; public: static constexpr QTimeEvtCtr QXTHREAD_NO_TIMEOUT{0U}; public: QXThread( QXThreadHandler const handler, std::uint_fast8_t const tickRate = 0U) noexcept; void init( void const * const e, std::uint_fast8_t const qsId) override; void init(std::uint_fast8_t const qsId) override { this->init(nullptr, qsId); } void dispatch( QEvt const * const e, std::uint_fast8_t const qsId) override; QTimeEvt const * getTimeEvt() const noexcept { return &m_timeEvt; } static bool delay(QTimeEvtCtr const nTicks) noexcept; bool delayCancel() noexcept; static QEvt const * queueGet(QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT) noexcept; private: void block_() const noexcept; void unblock_() const noexcept; static void timeout_(QActive * const act); void teArm_( enum_t const sig, QTimeEvtCtr const nTicks) noexcept; bool teDisarm_() noexcept; void stackInit_( QP::QXThreadHandler const handler, void * const stkSto, std::uint_fast16_t const stkSize) noexcept; }; // class QXThread } // namespace QP //$enddecl${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$declare${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { //${QXK::QXSemaphore} ........................................................ class QXSemaphore { private: QPSet m_waitSet; std::uint8_t m_count; std::uint8_t m_max_count; public: void init( std::uint_fast8_t const count, std::uint_fast8_t const max_count = 0xFFU) noexcept; bool wait(QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT) noexcept; bool tryWait() noexcept; bool signal() noexcept; }; // class QXSemaphore } // namespace QP //$enddecl${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$declare${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { //${QXK::QXMutex} ............................................................ class QXMutex { private: QActive m_ao; QPSet m_waitSet; public: QXMutex(); void init(QPrioSpec const prioSpec) noexcept; bool lock(QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT) noexcept; bool tryLock() noexcept; void unlock() noexcept; }; // class QXMutex } // namespace QP //$enddecl${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ extern "C" { //$declare${QXK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QXK-extern-C::QXK_Attr} .................................................. class QXK_Attr { public: QP::QActive * volatile curr; QP::QActive * volatile next; QP::QActive * volatile prev; std::uint_fast8_t volatile actPrio; std::uint_fast8_t volatile lockCeil; std::uint_fast8_t volatile lockHolder; QP::QPSet readySet; #ifndef Q_UNSAFE QP::QPSet readySet_dis; #endif // ndef Q_UNSAFE }; // class QXK_Attr //${QXK-extern-C::QXK_priv_} ................................................. extern QXK_Attr QXK_priv_; //${QXK-extern-C::QXK_sched_} ................................................ std::uint_fast8_t QXK_sched_() noexcept; //${QXK-extern-C::QXK_activate_} ............................................. void QXK_activate_() noexcept; //${QXK-extern-C::QXK_contextSw_} ............................................ void QXK_contextSw_(QP::QActive * const next); //${QXK-extern-C::QXK_threadExit_} ........................................... void QXK_threadExit_(); //$enddecl${QXK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } // extern "C" //============================================================================ // interface used only for internal implementation, but not in applications #ifdef QP_IMPL //$declare${QXK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QXK-impl::QF_SCHED_STAT_} ................................................ #define QF_SCHED_STAT_ QSchedStatus lockStat_; //${QXK-impl::QF_SCHED_LOCK_} ................................................ #define QF_SCHED_LOCK_(ceil_) do { \ if (QXK_ISR_CONTEXT_()) { \ lockStat_ = 0xFFU; \ } else { \ lockStat_ = QXK::schedLock((ceil_)); \ } \ } while (false) //${QXK-impl::QF_SCHED_UNLOCK_} .............................................. #define QF_SCHED_UNLOCK_() do { \ if (lockStat_ != 0xFFU) { \ QXK::schedUnlock(lockStat_); \ } \ } while (false) //${QXK-impl::QACTIVE_EQUEUE_WAIT_} .......................................... // QXK native event queue waiting #define QACTIVE_EQUEUE_WAIT_(me_) \ Q_ASSERT_INCRIT(310, (me_)->m_eQueue.m_frontEvt != nullptr) //${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................ #ifndef Q_UNSAFE // QXK native event queue signalling #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ QXK_priv_.readySet.insert( \ static_cast((me_)->m_prio)); \ QXK_priv_.readySet.update_(&QXK_priv_.readySet_dis); \ if (!QXK_ISR_CONTEXT_()) { \ if (QXK_sched_() != 0U) { \ QXK_activate_(); \ } \ } \ } while (false) #endif // ndef Q_UNSAFE //${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................ #ifdef Q_UNSAFE // QXK native event queue signalling #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ QXK_priv_.readySet.insert( \ static_cast((me_)->m_prio)); \ if (!QXK_ISR_CONTEXT_()) { \ if (QXK_sched_() != 0U) { \ QXK_activate_(); \ } \ } \ } while (false) #endif // def Q_UNSAFE //${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} ....................................... #ifndef Q_UNSAFE #define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \ if ((me_)->m_temp.obj == QXK_PTR_CAST_(QMState*, &(me_)->m_eQueue)) { \ static_cast(QXTHREAD_CAST_(me_)->teDisarm_()); \ QXK_priv_.readySet.insert( \ static_cast((me_)->m_prio)); \ QXK_priv_.readySet.update_(&QXK_priv_.readySet_dis); \ if (!QXK_ISR_CONTEXT_()) { \ static_cast(QXK_sched_()); \ } \ } \ } while (false) #endif // ndef Q_UNSAFE //${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} ....................................... #ifdef Q_UNSAFE #define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \ if ((me_)->m_temp.obj == QXK_PTR_CAST_(QMState*, &(me_)->m_eQueue)) { \ static_cast(QXTHREAD_CAST_(me_)->teDisarm_()); \ QXK_priv_.readySet.insert( \ static_cast((me_)->m_prio)); \ if (!QXK_ISR_CONTEXT_()) { \ static_cast(QXK_sched_()); \ } \ } \ } while (false) #endif // def Q_UNSAFE //${QXK-impl::QXTHREAD_CAST_} ................................................ #define QXTHREAD_CAST_(ptr_) (static_cast(ptr_)) //${QXK-impl::QXK_PTR_CAST_} ................................................. #define QXK_PTR_CAST_(type_, ptr_) (reinterpret_cast(ptr_)) //$enddecl${QXK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... #define QF_EPOOL_TYPE_ QMPool //${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (p_).init((poolSto_), (poolSize_), (evtSize_)) //${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize()) //${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ ((e_) = static_cast((p_).get((m_), (qsId_)))) //${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ #define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_))) //$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ namespace QP { namespace QXK { enum TimeoutSigs : QSignal { DELAY_SIG = 1U, TIMEOUT_SIG }; } // namespace QXK } // namespace QP #endif // QP_IMPL #endif // QXK_HPP_