QP/C++  7.4.0-rc.1
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qxk.hpp
Go to the documentation of this file.
1//$file${include::qxk.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2//
3// Model: qpcpp.qm
4// File: ${include::qxk.hpp}
5//
6// This code has been generated by QM 6.1.1 <www.state-machine.com/qm>.
7// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
8//
9// This code is covered by the following QP license:
10// License # : LicenseRef-QL-dual
11// Issued to : Any user of the QP/C++ real-time embedded framework
12// Framework(s) : qpcpp
13// Support ends : 2024-12-31
14// License scope:
15//
16// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
17//
18// Q u a n t u m L e a P s
19// ------------------------
20// Modern Embedded Software
21//
22// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
23//
24// This software is dual-licensed under the terms of the open source GNU
25// General Public License version 3 (or any later version), or alternatively,
26// under the terms of one of the closed source Quantum Leaps commercial
27// licenses.
28//
29// The terms of the open source GNU General Public License version 3
30// can be found at: <www.gnu.org/licenses/gpl-3.0>
31//
32// The terms of the closed source Quantum Leaps commercial licenses
33// can be found at: <www.state-machine.com/licensing>
34//
35// Redistributions in source code must retain this top-level comment block.
36// Plagiarizing this software to sidestep the license obligations is illegal.
37//
38// Contact information:
39// <www.state-machine.com/licensing>
40// <info@state-machine.com>
41//
42//$endhead${include::qxk.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43#ifndef QXK_HPP_
44#define QXK_HPP_
45
46//$declare${QXK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
47namespace QP {
48
49//${QXK::QSchedStatus} .......................................................
50using QSchedStatus = std::uint_fast16_t;
51
52} // namespace QP
53//$enddecl${QXK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54
55//$declare${QXK::QXTHREAD_NO_TIMEOUT} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
56namespace QP {
57
58//${QXK::QXTHREAD_NO_TIMEOUT} ................................................
60
61} // namespace QP
62//$enddecl${QXK::QXTHREAD_NO_TIMEOUT} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
63
64//$declare${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
65namespace QP {
66namespace QXK {
67
68//${QXK::QXK-base::onIdle} ...................................................
69void onIdle();
70
71//${QXK::QXK-base::schedLock} ................................................
72QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept;
73
74//${QXK::QXK-base::schedUnlock} ..............................................
75void schedUnlock(QSchedStatus const stat) noexcept;
76
77//${QXK::QXK-base::current} ..................................................
78QP::QActive * current() noexcept;
79
80} // namespace QXK
81} // namespace QP
82//$enddecl${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83
84//$declare${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
85namespace QP {
86
87//${QXK::QXThread} ...........................................................
88class QXThread : public QP::QActive {
89private:
91
92public:
93 friend class QActive;
94 friend class QTimeEvt;
95 friend class QXSemaphore;
96 friend class QXMutex;
97
98public:
99 static constexpr QTimeEvtCtr QXTHREAD_NO_TIMEOUT{0U};
100
101public:
102 QXThread(
103 QXThreadHandler const handler,
104 std::uint_fast8_t const tickRate = 0U) noexcept;
105 void init(
106 void const * const e,
107 std::uint_fast8_t const qsId) override;
108 void init(std::uint_fast8_t const qsId) override {
109 this->init(nullptr, qsId);
110 }
111 void dispatch(
112 QEvt const * const e,
113 std::uint_fast8_t const qsId) override;
114 QTimeEvt const * getTimeEvt() const noexcept {
115 return &m_timeEvt;
116 }
117 static bool delay(QTimeEvtCtr const nTicks) noexcept;
118 bool delayCancel() noexcept;
119 static QEvt const * queueGet(QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT) noexcept;
120
121private:
122 void block_() const noexcept;
123 void unblock_() const noexcept;
124 static void timeout_(QActive * const act);
125 void teArm_(
126 enum_t const sig,
127 QTimeEvtCtr const nTicks) noexcept;
128 bool teDisarm_() noexcept;
129 void stackInit_(
130 QP::QXThreadHandler const handler,
131 void * const stkSto,
132 std::uint_fast16_t const stkSize) noexcept;
133}; // class QXThread
134
135} // namespace QP
136//$enddecl${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
137
138//$declare${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
139namespace QP {
140
141//${QXK::QXSemaphore} ........................................................
143private:
145 std::uint8_t m_count;
146 std::uint8_t m_max_count;
147
148public:
149 void init(
150 std::uint_fast8_t const count,
151 std::uint_fast8_t const max_count = 0xFFU) noexcept;
152 bool wait(QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT) noexcept;
153 bool tryWait() noexcept;
154 bool signal() noexcept;
155}; // class QXSemaphore
156
157} // namespace QP
158//$enddecl${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
159
160//$declare${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
161namespace QP {
162
163//${QXK::QXMutex} ............................................................
164class QXMutex {
165private:
168
169public:
170 QXMutex();
171 void init(QPrioSpec const prioSpec) noexcept;
172 bool lock(QTimeEvtCtr const nTicks = QXTHREAD_NO_TIMEOUT) noexcept;
173 bool tryLock() noexcept;
174 void unlock() noexcept;
175}; // class QXMutex
176
177} // namespace QP
178//$enddecl${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
179
180extern "C" {
181//$declare${QXK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
182
183//${QXK-extern-C::QXK_Attr} ..................................................
184class QXK_Attr {
185public:
186 QP::QActive * volatile curr;
187 QP::QActive * volatile next;
188 QP::QActive * volatile prev;
189 std::uint_fast8_t volatile actPrio;
190 std::uint_fast8_t volatile lockCeil;
191 std::uint_fast8_t volatile lockHolder;
193
194#ifndef Q_UNSAFE
196#endif // ndef Q_UNSAFE
197}; // class QXK_Attr
198
199//${QXK-extern-C::QXK_priv_} .................................................
200extern QXK_Attr QXK_priv_;
201
202//${QXK-extern-C::QXK_sched_} ................................................
203std::uint_fast8_t QXK_sched_() noexcept;
204
205//${QXK-extern-C::QXK_activate_} .............................................
206void QXK_activate_() noexcept;
207
208//${QXK-extern-C::QXK_contextSw_} ............................................
209void QXK_contextSw_(QP::QActive * const next);
210
211//${QXK-extern-C::QXK_threadExit_} ...........................................
212void QXK_threadExit_();
213//$enddecl${QXK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
214} // extern "C"
215
216//============================================================================
217// interface used only for internal implementation, but not in applications
218#ifdef QP_IMPL
219
220//$declare${QXK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
221
222//${QXK-impl::QF_SCHED_STAT_} ................................................
223#define QF_SCHED_STAT_ QSchedStatus lockStat_;
224
225//${QXK-impl::QF_SCHED_LOCK_} ................................................
226#define QF_SCHED_LOCK_(ceil_) do { \
227 if (QXK_ISR_CONTEXT_()) { \
228 lockStat_ = 0xFFU; \
229 } else { \
230 lockStat_ = QXK::schedLock((ceil_)); \
231 } \
232} while (false)
233
234//${QXK-impl::QF_SCHED_UNLOCK_} ..............................................
235#define QF_SCHED_UNLOCK_() do { \
236 if (lockStat_ != 0xFFU) { \
237 QXK::schedUnlock(lockStat_); \
238 } \
239} while (false)
240
241//${QXK-impl::QACTIVE_EQUEUE_WAIT_} ..........................................
242// QXK native event queue waiting
243#define QACTIVE_EQUEUE_WAIT_(me_) \
244 Q_ASSERT_INCRIT(310, (me_)->m_eQueue.m_frontEvt != nullptr)
245
246//${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................
247#ifndef Q_UNSAFE
248// QXK native event queue signalling
249#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
250 QXK_priv_.readySet.insert( \
251 static_cast<std::uint_fast8_t>((me_)->m_prio)); \
252 QXK_priv_.readySet.update_(&QXK_priv_.readySet_dis); \
253 if (!QXK_ISR_CONTEXT_()) { \
254 if (QXK_sched_() != 0U) { \
255 QXK_activate_(); \
256 } \
257 } \
258} while (false)
259#endif // ndef Q_UNSAFE
260
261//${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................
262#ifdef Q_UNSAFE
263// QXK native event queue signalling
264#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
265 QXK_priv_.readySet.insert( \
266 static_cast<std::uint_fast8_t>((me_)->m_prio)); \
267 if (!QXK_ISR_CONTEXT_()) { \
268 if (QXK_sched_() != 0U) { \
269 QXK_activate_(); \
270 } \
271 } \
272} while (false)
273#endif // def Q_UNSAFE
274
275//${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} .......................................
276#ifndef Q_UNSAFE
277#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \
278 if ((me_)->m_temp.obj == QXK_PTR_CAST_(QMState*, &(me_)->m_eQueue)) { \
279 static_cast<void>(QXTHREAD_CAST_(me_)->teDisarm_()); \
280 QXK_priv_.readySet.insert( \
281 static_cast<std::uint_fast8_t>((me_)->m_prio)); \
282 QXK_priv_.readySet.update_(&QXK_priv_.readySet_dis); \
283 if (!QXK_ISR_CONTEXT_()) { \
284 static_cast<void>(QXK_sched_()); \
285 } \
286 } \
287} while (false)
288#endif // ndef Q_UNSAFE
289
290//${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} .......................................
291#ifdef Q_UNSAFE
292#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \
293 if ((me_)->m_temp.obj == QXK_PTR_CAST_(QMState*, &(me_)->m_eQueue)) { \
294 static_cast<void>(QXTHREAD_CAST_(me_)->teDisarm_()); \
295 QXK_priv_.readySet.insert( \
296 static_cast<std::uint_fast8_t>((me_)->m_prio)); \
297 if (!QXK_ISR_CONTEXT_()) { \
298 static_cast<void>(QXK_sched_()); \
299 } \
300 } \
301} while (false)
302#endif // def Q_UNSAFE
303
304//${QXK-impl::QXTHREAD_CAST_} ................................................
305#define QXTHREAD_CAST_(ptr_) (static_cast<QP::QXThread *>(ptr_))
306
307//${QXK-impl::QXK_PTR_CAST_} .................................................
308#define QXK_PTR_CAST_(type_, ptr_) (reinterpret_cast<type_>(ptr_))
309//$enddecl${QXK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
310
311//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
312
313//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ...........................................
314#define QF_EPOOL_TYPE_ QMPool
315
316//${QF_EPOOL-impl::QF_EPOOL_INIT_} ...........................................
317#define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
318 (p_).init((poolSto_), (poolSize_), (evtSize_))
319
320//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} .....................................
321#define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize())
322
323//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................
324#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \
325 ((e_) = static_cast<QEvt *>((p_).get((m_), (qsId_))))
326
327//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................
328#define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_)))
329//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
330
331namespace QP {
332namespace QXK {
337} // namespace QXK
338} // namespace QP
339
340#endif // QP_IMPL
341
342#endif // QXK_HPP_
Active object class (based on the QHsm implementation strategy)
Definition qp.hpp:722
Event class.
Definition qp.hpp:137
Set of Active Objects of up to QF_MAX_ACTIVE elements.
Definition qp.hpp:610
Time Event class.
Definition qp.hpp:953
Blocking Mutex of the QXK preemptive kernel.
Definition qxk.hpp:164
QActive m_ao
Definition qxk.hpp:166
QPSet m_waitSet
Definition qxk.hpp:167
Counting Semaphore of the QXK preemptive kernel.
Definition qxk.hpp:142
std::uint8_t m_count
Definition qxk.hpp:145
std::uint8_t m_max_count
Definition qxk.hpp:146
QPSet m_waitSet
Definition qxk.hpp:144
eXtended (blocking) thread of the QXK preemptive kernel
Definition qxk.hpp:88
void init(std::uint_fast8_t const qsId) override
Definition qxk.hpp:108
QTimeEvt m_timeEvt
Definition qxk.hpp:90
QTimeEvt const * getTimeEvt() const noexcept
Definition qxk.hpp:114
Private attributes of the QXK kernel.
Definition qxk.hpp:184
QP::QActive *volatile next
Definition qxk.hpp:187
QP::QActive *volatile prev
Definition qxk.hpp:188
std::uint_fast8_t volatile lockCeil
Definition qxk.hpp:190
QP::QActive *volatile curr
Definition qxk.hpp:186
std::uint_fast8_t volatile actPrio
Definition qxk.hpp:189
std::uint_fast8_t volatile lockHolder
Definition qxk.hpp:191
QP::QPSet readySet
Definition qxk.hpp:192
QP::QPSet readySet_dis
Definition qxk.hpp:195
QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept
Definition qxk.cpp:76
QP::QActive * current() noexcept
Definition qxk.cpp:146
TimeoutSigs
Definition qxk.hpp:333
@ TIMEOUT_SIG
Definition qxk.hpp:335
@ DELAY_SIG
Definition qxk.hpp:334
void schedUnlock(QSchedStatus const stat) noexcept
Definition qxk.cpp:114
void onIdle()
QP/C++ framework.
Definition qequeue.hpp:50
std::uint32_t QTimeEvtCtr
Definition qp.hpp:586
constexpr QTimeEvtCtr QXTHREAD_NO_TIMEOUT
Definition qxk.hpp:59
std::uint_fast8_t QSchedStatus
Definition qk.hpp:50
std::uint16_t QSignal
Definition qp.hpp:128
void(*)(QXThread *const me) QXThreadHandler
Definition qp.hpp:184
std::uint16_t QPrioSpec
Definition qp.hpp:572
int enum_t
Definition qp.hpp:106
void QXK_threadExit_()
Definition qxk.cpp:367
std::uint_fast8_t QXK_sched_() noexcept
Definition qxk.cpp:177
void QXK_activate_() noexcept
Definition qxk.cpp:236
QXK_Attr QXK_priv_
Definition qxk.cpp:174
void QXK_contextSw_(QP::QActive *const next)
Definition qxk.cpp:339