QP/C  8.0.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qf_qact.c
Go to the documentation of this file.
1//============================================================================
2// QP/C Real-Time Embedded Framework (RTEF)
3// Version 8.0.2
4//
5// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
6//
7// Q u a n t u m L e a P s
8// ------------------------
9// Modern Embedded Software
10//
11// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
12//
13// This software is dual-licensed under the terms of the open-source GNU
14// General Public License (GPL) or under the terms of one of the closed-
15// source Quantum Leaps commercial licenses.
16//
17// Redistributions in source code must retain this top-level comment block.
18// Plagiarizing this software to sidestep the license obligations is illegal.
19//
20// NOTE:
21// The GPL does NOT permit the incorporation of this code into proprietary
22// programs. Please contact Quantum Leaps for commercial licensing options,
23// which expressly supersede the GPL and are designed explicitly for
24// closed-source distribution.
25//
26// Quantum Leaps contact information:
27// <www.state-machine.com/licensing>
28// <info@state-machine.com>
29//============================================================================
30#define QP_IMPL // this is QP implementation
31#include "qp_port.h" // QP port
32#include "qp_pkg.h" // QP package-scope interface
33#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
34#ifdef Q_SPY // QS software tracing enabled?
35 #include "qs_port.h" // QS port
36 #include "qs_pkg.h" // QS facilities for pre-defined trace records
37#else
38 #include "qs_dummy.h" // disable the QS software tracing
39#endif // Q_SPY
40
41Q_DEFINE_THIS_MODULE("qf_qact")
42
43//............................................................................
44//! @protected @memberof QActive
45void QActive_ctor(QActive * const me,
46 QStateHandler const initial)
47{
48 // clear the whole QActive object, so that the framework can start
49 // correctly even if the startup code fails to clear the uninitialized
50 // data (as is required by the C Standard).
51 QF_bzero_(me, sizeof(*me));
52
53 // NOTE: QActive inherits the abstract QAsm class, but it calls the
54 // constructor of the QHsm subclass. This is because QActive inherits
55 // the behavior from the QHsm subclass.
56 QHsm_ctor((QHsm *)(me), initial);
57
58 // NOTE: this vtable is identical as QHsm, but is provided
59 // for the QActive subclass to provide a UNIQUE vptr to distinguish
60 // subclasses of QActive (e.g., in the debugger).
61 static struct QAsmVtable const vtable = { // QActive virtual table
62 &QHsm_init_,
63 &QHsm_dispatch_,
64 &QHsm_isIn_
65#ifdef Q_SPY
66 ,&QHsm_getStateHandler_
67#endif
68 };
69 me->super.vptr = &vtable; // hook vptr to QActive vtable
70}
71
72//............................................................................
73//! @private @memberof QActive
74void QActive_register_(QActive * const me) {
77
78 if (me->pthre == 0U) { // preemption-threshold not defined?
79 me->pthre = me->prio; // apply the default
80 }
81
82#ifndef Q_UNSAFE
84 (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE)
85 && (QActive_registry_[me->prio] == (QActive *)0)
86 && (me->prio <= me->pthre));
87
88 uint8_t prev_thre = me->pthre;
89 uint8_t next_thre = me->pthre;
90
91 for (uint_fast8_t p = (uint_fast8_t)me->prio - 1U;
92 p > 0U;
93 --p)
94 {
95 if (QActive_registry_[p] != (QActive *)0) {
96 prev_thre = QActive_registry_[p]->pthre;
97 break;
98 }
99 }
100 for (uint_fast8_t p = (uint_fast8_t)me->prio + 1U;
101 p <= QF_MAX_ACTIVE;
102 ++p)
103 {
104 if (QActive_registry_[p] != (QActive *)0) {
105 next_thre = QActive_registry_[p]->pthre;
106 break;
107 }
108 }
109
110 Q_ASSERT_INCRIT(190,
111 (prev_thre <= me->pthre)
112 && (me->pthre <= next_thre));
113#endif // Q_UNSAFE
114
115 // register the AO at the QF-prio.
116 QActive_registry_[me->prio] = me;
117
118 QF_CRIT_EXIT();
119}
120
121//............................................................................
122//! @private @memberof QActive
123void QActive_unregister_(QActive * const me) {
124 uint_fast8_t const p = (uint_fast8_t)me->prio;
125
128
129 Q_REQUIRE_INCRIT(200, (0U < p) && (p <= QF_MAX_ACTIVE)
130 && (QActive_registry_[p] == me));
131 QActive_registry_[p] = (QActive *)0; // free-up the prio. level
132 me->super.state.fun = Q_STATE_CAST(0); // invalidate the state
133
134 QF_CRIT_EXIT();
135}
#define Q_STATE_CAST(handler_)
Perform cast to QStateHandler.
Definition qp.h:175
QState(* QStateHandler)(void *const me, QEvt const *const e)
Pointer to a state-handler function.
Definition qp.h:148
#define QF_MAX_ACTIVE
Maximum # Active Objects in the system (1..64)
Definition qp_config.h:123
Internal (package scope) QP/C interface.
Sample QP/C port.
#define QF_CRIT_ENTRY()
Definition qp_port.h:64
#define QF_CRIT_EXIT()
Definition qp_port.h:72
#define QF_CRIT_STAT
Definition qp_port.h:55
Sample QS/C port.
#define Q_ASSERT_INCRIT(id_, expr_)
Definition qsafe.h:50
#define Q_REQUIRE_INCRIT(id_, expr_)
Definition qsafe.h:87
Active object class (based on the QHsm implementation strategy)
Definition qp.h:507
QAsm super
Definition qp.h:508
void QActive_unregister_(QActive *const me)
Definition qf_qact.c:123
void QActive_register_(QActive *const me)
Definition qf_qact.c:74
QActive * QActive_registry_[QF_MAX_ACTIVE+1U]
Static (one per-class) array of registered active objects.
Definition qp.h:526
uint8_t prio
QF-priority [1..QF_MAX_ACTIVE] of this AO.
Definition qp.h:509
uint8_t pthre
Preemption-threshold [1..QF_MAX_ACTIVE] of this AO.
Definition qp.h:510
union QAsmAttr state
Current state (pointer to the current state-handler function)
Definition qp.h:183
Virtual table for the QAsm class.
Definition qp.h:224
Hierarchical State Machine class (QHsm-style state machine implementation strategy)
Definition qp.h:254
QStateHandler fun
Definition qp.h:168