QP/C  8.0.3
Real-Time Event Framework
Loading...
Searching...
No Matches
qf_defer.c
Go to the documentation of this file.
1//============================================================================
2// QP/C Real-Time Event Framework (RTEF)
3//
4// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
5//
6// Q u a n t u m L e a P s
7// ------------------------
8// Modern Embedded Software
9//
10// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
11//
12// This software is dual-licensed under the terms of the open-source GNU
13// General Public License (GPL) or under the terms of one of the closed-
14// source Quantum Leaps commercial licenses.
15//
16// Redistributions in source code must retain this top-level comment block.
17// Plagiarizing this software to sidestep the license obligations is illegal.
18//
19// NOTE:
20// The GPL does NOT permit the incorporation of this code into proprietary
21// programs. Please contact Quantum Leaps for commercial licensing options,
22// which expressly supersede the GPL and are designed explicitly for
23// closed-source distribution.
24//
25// Quantum Leaps contact information:
26// <www.state-machine.com/licensing>
27// <info@state-machine.com>
28//============================================================================
29#define QP_IMPL // this is QP implementation
30#include "qp_port.h" // QP port
31#include "qp_pkg.h" // QP package-scope interface
32#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
33#ifdef Q_SPY // QS software tracing enabled?
34 #include "qs_port.h" // QS port
35 #include "qs_pkg.h" // QS facilities for pre-defined trace records
36#else
37 #include "qs_dummy.h" // disable the QS software tracing
38#endif // Q_SPY
39
40Q_DEFINE_THIS_MODULE("qf_defer")
41
42//............................................................................
43//! @protected @memberof QActive
44bool QActive_defer(QActive const * const me,
45 struct QEQueue * const eq,
46 QEvt const * const e)
47{
48 bool const status = QEQueue_post(eq, e, 0U, me->prio);
49
52 QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, me->prio)
53 QS_TIME_PRE(); // time stamp
54 QS_OBJ_PRE(me); // this active object
55 QS_OBJ_PRE(eq); // the deferred queue
56 QS_SIG_PRE(e->sig); // the signal of the event
57 QS_2U8_PRE(e->poolNum_, e->refCtr_);
60
61 return status;
62}
63
64//............................................................................
65//! @protected @memberof QActive
66bool QActive_recall(QActive * const me,
67 struct QEQueue * const eq)
68{
69 QEvt const * const e = QEQueue_get(eq, me->prio);
71
72 bool recalled = false;
73 if (e != (QEvt *)0) { // event available?
74 QACTIVE_POST_LIFO(me, e); // post it to the front of the AO's queue
75
77
78 if (e->poolNum_ != 0U) { // is it a mutable event?
79
80 // after posting to the AO's queue the event must be referenced
81 // at least twice: once in the deferred event queue (eq->get()
82 // did NOT decrement the reference counter) and once in the
83 // AO's event queue.
84 Q_ASSERT_INCRIT(205, e->refCtr_ >= 2U);
85
86 // we need to decrement the reference counter once, to account
87 // for removing the event from the deferred event queue.
88 QEvt_refCtr_dec_(e); // decrement the reference counter
89 }
90
91 QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL, me->prio)
92 QS_TIME_PRE(); // time stamp
93 QS_OBJ_PRE(me); // this active object
94 QS_OBJ_PRE(eq); // the deferred queue
95 QS_SIG_PRE(e->sig); // the signal of the event
98
100
101 recalled = true;
102 }
103 else {
105
106 QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio)
107 QS_TIME_PRE(); // time stamp
108 QS_OBJ_PRE(me); // this active object
109 QS_OBJ_PRE(eq); // the deferred queue
110 QS_END_PRE()
111
112 QS_CRIT_EXIT();
113 }
114 return recalled;
115}
116
117//............................................................................
118//! @protected @memberof QActive
119uint_fast16_t QActive_flushDeferred(QActive const * const me,
120 struct QEQueue * const eq,
121 uint_fast16_t const num)
122{
123 uint_fast16_t n = 0U;
124 while (n < num) {
125 QEvt const * const e = QEQueue_get(eq, me->prio);
126 if (e != (QEvt *)0) {
127 ++n; // count one more flushed event
128#if (QF_MAX_EPOOL > 0U)
129 QF_gc(e); // garbage collect
130#endif
131 }
132 else {
133 break;
134 }
135 }
136
137 return n;
138}
#define QACTIVE_POST_LIFO(me_, e_)
Post an event to an active object using the Last-In-First-Out (LIFO) policy.
Definition qp.h:824
Internal (package scope) QP/C interface.
Sample QP/C port.
QS/C dummy public interface.
#define QS_OBJ_PRE(obj_)
Definition qs_dummy.h:149
#define QS_CRIT_STAT
Definition qs_dummy.h:156
#define QS_SIG_PRE(sig_)
Definition qs_dummy.h:147
#define QS_TIME_PRE()
Definition qs_dummy.h:146
#define QS_2U8_PRE(data1_, data2_)
Definition qs_dummy.h:143
#define QS_CRIT_EXIT()
Definition qs_dummy.h:158
#define QS_END_PRE()
Definition qs_dummy.h:141
#define QS_CRIT_ENTRY()
Definition qs_dummy.h:157
#define QS_BEGIN_PRE(rec_, qsId_)
Definition qs_dummy.h:140
Sample QS/C port.
QP Functional Safety (FuSa) Subsystem.
#define QF_CRIT_ENTRY()
Definition qsafe.h:39
#define Q_ASSERT_INCRIT(id_, expr_)
General-purpose assertion with user-specified ID number (in critical section)
Definition qsafe.h:49
#define QF_CRIT_EXIT()
Definition qsafe.h:43
#define QF_CRIT_STAT
Definition qsafe.h:35
Active object class (based on the QHsm implementation strategy)
Definition qp.h:504
bool QActive_recall(QActive *const me, struct QEQueue *const eq)
Recall a deferred event from a given event queue.
Definition qf_defer.c:66
uint8_t prio
QF-priority [1..QF_MAX_ACTIVE] of this AO.
Definition qp.h:506
uint_fast16_t QActive_flushDeferred(QActive const *const me, struct QEQueue *const eq, uint_fast16_t const num)
Flush the specified number of events from the deferred queue eq
Definition qf_defer.c:119
Native QF Event Queue.
Definition qequeue.h:48
Event class.
Definition qp.h:112
QSignal sig
Signal of the event (see Event Signal)
Definition qp.h:113
uint8_t volatile refCtr_
Event reference counter.
Definition qp.h:115
uint8_t poolNum_
Event pool number of this event.
Definition qp.h:114