qpcpp/include/qxk.hpp
MMS db53ac24c1 7.3.3
bug fix, codespell
2024-01-30 21:00:18 -05:00

343 lines
11 KiB
C++

//$file${include::qxk.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//
// Model: qpcpp.qm
// File: ${include::qxk.hpp}
//
// This code has been generated by QM 6.1.1 <www.state-machine.com/qm>.
// 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 <state-machine.com>.
//
// 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: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//
//$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<std::uint_fast8_t>((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<std::uint_fast8_t>((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<void>(QXTHREAD_CAST_(me_)->teDisarm_()); \
QXK_priv_.readySet.insert( \
static_cast<std::uint_fast8_t>((me_)->m_prio)); \
QXK_priv_.readySet.update_(&QXK_priv_.readySet_dis); \
if (!QXK_ISR_CONTEXT_()) { \
static_cast<void>(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<void>(QXTHREAD_CAST_(me_)->teDisarm_()); \
QXK_priv_.readySet.insert( \
static_cast<std::uint_fast8_t>((me_)->m_prio)); \
if (!QXK_ISR_CONTEXT_()) { \
static_cast<void>(QXK_sched_()); \
} \
} \
} while (false)
#endif // def Q_UNSAFE
//${QXK-impl::QXTHREAD_CAST_} ................................................
#define QXTHREAD_CAST_(ptr_) (static_cast<QP::QXThread *>(ptr_))
//${QXK-impl::QXK_PTR_CAST_} .................................................
#define QXK_PTR_CAST_(type_, ptr_) (reinterpret_cast<type_>(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<QEvt *>((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_