QP/C  7.0.0
Real-Time Embedded Framework
qf_defer.c
Go to the documentation of this file.
1/*============================================================================
2* QP/C Real-Time Embedded Framework (RTEF)
3* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
4*
5* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
6*
7* This software is dual-licensed under the terms of the open source GNU
8* General Public License version 3 (or any later version), or alternatively,
9* under the terms of one of the closed source Quantum Leaps commercial
10* licenses.
11*
12* The terms of the open source GNU General Public License version 3
13* can be found at: <www.gnu.org/licenses/gpl-3.0>
14*
15* The terms of the closed source Quantum Leaps commercial licenses
16* can be found at: <www.state-machine.com/licensing>
17*
18* Redistributions in source code must retain this top-level comment block.
19* Plagiarizing this software to sidestep the license obligations is illegal.
20*
21* Contact information:
22* <www.state-machine.com>
23* <info@state-machine.com>
24============================================================================*/
32#define QP_IMPL /* this is QP implementation */
33#include "qf_port.h" /* QF port */
34#include "qf_pkg.h" /* QF package-scope interface */
35#include "qassert.h" /* QP embedded systems-friendly assertions */
36#ifdef Q_SPY /* QS software tracing enabled? */
37 #include "qs_port.h" /* QS port */
38 #include "qs_pkg.h" /* QS facilities for pre-defined trace records */
39#else
40 #include "qs_dummy.h" /* disable the QS software tracing */
41#endif /* Q_SPY */
42
43Q_DEFINE_THIS_MODULE("qf_defer")
44
45/*==========================================================================*/
71bool QActive_defer(QActive const * const me, QEQueue * const eq,
72 QEvt const * const e)
73{
74 bool const status = QEQueue_post(eq, e, 0U, me->prio);
76
78 QS_TIME_PRE_(); /* time stamp */
79 QS_OBJ_PRE_(me); /* this active object */
80 QS_OBJ_PRE_(eq); /* the deferred queue */
81 QS_SIG_PRE_(e->sig); /* the signal of the event */
82 QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
84
85 return status;
86}
87
88/*==========================================================================*/
111bool QActive_recall(QActive * const me, QEQueue * const eq) {
112 QEvt const * const e = QEQueue_get(eq, me->prio);
113 bool recalled;
114
115 /* event available? */
116 if (e != (QEvt *)0) {
118
119 QACTIVE_POST_LIFO(me, e); /* post it to the front of the AO's queue */
120
121 QF_CRIT_E_();
122
123 /* is it a dynamic event? */
124 if (e->poolId_ != 0U) {
125
126 /* after posting to the AO's queue the event must be referenced
127 * at least twice: once in the deferred event queue (eq->get()
128 * did NOT decrement the reference counter) and once in the
129 * AO's event queue.
130 */
131 Q_ASSERT_CRIT_(210, e->refCtr_ >= 2U);
132
133 /* we need to decrement the reference counter once, to account
134 * for removing the event from the deferred event queue.
135 */
136 QF_EVT_REF_CTR_DEC_(e); /* decrement the reference counter */
137 }
138
140 QS_TIME_PRE_(); /* time stamp */
141 QS_OBJ_PRE_(me); /* this active object */
142 QS_OBJ_PRE_(eq); /* the deferred queue */
143 QS_SIG_PRE_(e->sig); /* the signal of the event */
144 QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
146
147 QF_CRIT_X_();
148 recalled = true;
149 }
150 else {
152
154 QS_TIME_PRE_(); /* time stamp */
155 QS_OBJ_PRE_(me); /* this active object */
156 QS_OBJ_PRE_(eq); /* the deferred queue */
158
159 recalled = false;
160 }
161 return recalled;
162}
163
164/*==========================================================================*/
181uint_fast16_t QActive_flushDeferred(QActive const * const me,
182 QEQueue * const eq)
183{
184 uint_fast16_t n = 0U;
185 for (QEvt const *e = QEQueue_get(eq, me->prio);
186 e != (QEvt *)0;
187 e = QEQueue_get(eq, me->prio))
188 {
189 QF_gc(e); /* garbage collect */
190 ++n; /* count the flushed event */
191 }
192 return n;
193}
Customizable and memory-efficient assertions for embedded systems.
#define Q_DEFINE_THIS_MODULE(name_)
Definition: qassert.h:102
#define QACTIVE_POST_LIFO(me_, e_)
Definition: qf.h:295
Internal (package scope) QF/C interface.
#define QF_CRIT_STAT_
Definition: qf_pkg.h:54
#define QF_EVT_REF_CTR_DEC_(e_)
Definition: qf_pkg.h:180
#define Q_ASSERT_CRIT_(id_, test_)
Definition: qf_pkg.h:97
#define QF_CRIT_X_()
Definition: qf_pkg.h:78
#define QF_CRIT_E_()
Definition: qf_pkg.h:66
#define QS_CRIT_STAT_
Definition: qs.h:509
#define QS_TIME_PRE_()
Definition: qs.h:220
@ QS_QF_ACTIVE_RECALL
Definition: qs.h:70
@ QS_QF_ACTIVE_RECALL_ATTEMPT
Definition: qs.h:77
@ QS_QF_ACTIVE_DEFER
Definition: qs.h:69
Internal (package scope) QS/C interface.
#define QS_BEGIN_PRE_(rec_, qs_id_)
Definition: qs_pkg.h:114
#define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_)
Definition: qs_pkg.h:138
#define QS_OBJ_PRE_(obj_)
Definition: qs_pkg.h:179
#define QS_END_NOCRIT_PRE_()
Definition: qs_pkg.h:148
#define QS_2U8_PRE_(data1_, data2_)
Definition: qs_pkg.h:154
#define QS_SIG_PRE_(sig_)
Definition: qs_pkg.h:172
#define QS_END_PRE_()
Definition: qs_pkg.h:126
Definition: qf.h:107
bool QActive_recall(QActive *const me, QEQueue *const eq)
Definition: qf_defer.c:111
bool QActive_defer(QActive const *const me, QEQueue *const eq, QEvt const *const e)
Definition: qf_defer.c:71
uint8_t prio
Definition: qf.h:152
uint_fast16_t QActive_flushDeferred(QActive const *const me, QEQueue *const eq)
Definition: qf_defer.c:181
QEvt const * QEQueue_get(QEQueue *const me, uint_fast8_t const qs_id)
Definition: qf_qeq.c:268
bool QEQueue_post(QEQueue *const me, QEvt const *const e, uint_fast16_t const margin, uint_fast8_t const qs_id)
Definition: qf_qeq.c:103
Definition: qep.h:119
QSignal sig
Definition: qep.h:123
uint8_t poolId_
Definition: qep.h:128
uint8_t volatile refCtr_
Definition: qep.h:133
void QF_gc(QEvt const *const e)
Definition: qf_dyn.c:241