This commit is contained in:
QL 2018-04-06 11:33:57 -04:00
parent 5ab79df2a0
commit 7bfce82cc9
4 changed files with 107 additions and 24 deletions

61
examples/qutest/dpp/.dpp Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<session version="4.1.2">
<item name="license"></item>
<group name="locked"/>
<group name="settings">
<item name="tabs">1</item>
<item name="windows">0</item>
<item name="grid">3</item>
<item name="backups">0</item>
</group>
<group name="windows">
<item id="AOs::Philo::SM">0,0,575,407,*</item>
</group>
<group name="search">
<item name="options">2032128</item>
<item name="replace">0</item>
</group>
<group name="vars"/>
<group name="tools">
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="dir"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="dir"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="dir"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="dir"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="dir"></item>
<item name="options">0</item>
</group>
</group>
</session>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<model version="4.1.1" links="0"> <model version="4.1.2" links="0">
<documentation>Dining Philosopher Problem example <documentation>Dining Philosopher Problem example
NOTE: Reduced number of Philosophers, because off the limitations of the ThreadX evaluation library.</documentation> NOTE: Reduced number of Philosophers, because off the limitations of the ThreadX evaluation library.</documentation>
<framework name="qpc"/> <framework name="qpc"/>
@ -44,9 +44,10 @@ QActive_subscribe(&amp;me-&gt;super, EAT_SIG);</action>
</initial> </initial>
<state name="thinking"> <state name="thinking">
<entry>QTimeEvt_armX(&amp;me-&gt;timeEvt, THINK_TIME, 0U);</entry> <entry>QTimeEvt_armX(&amp;me-&gt;timeEvt, THINK_TIME, 0U);</entry>
<exit>QTimeEvt_disarm(&amp;me-&gt;timeEvt);</exit>
<tran trig="TIMEOUT" target="../../2"> <tran trig="TIMEOUT" target="../../2">
<tran_glyph conn="2,12,3,1,20,13,-3"> <tran_glyph conn="2,14,3,1,20,11,-3">
<action box="0,-2,6,2"/> <action box="0,-2,10,2"/>
</tran_glyph> </tran_glyph>
</tran> </tran>
<tran trig="EAT, DONE"> <tran trig="EAT, DONE">
@ -58,6 +59,7 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
</tran> </tran>
<state_glyph node="2,5,17,16"> <state_glyph node="2,5,17,16">
<entry box="1,2,5,2"/> <entry box="1,2,5,2"/>
<exit box="1,4,6,2"/>
</state_glyph> </state_glyph>
</state> </state>
<state name="hungry"> <state name="hungry">
@ -90,7 +92,8 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<entry>QTimeEvt_armX(&amp;me-&gt;timeEvt, EAT_TIME, 0U);</entry> <entry>QTimeEvt_armX(&amp;me-&gt;timeEvt, EAT_TIME, 0U);</entry>
<exit>TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); <exit>TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe-&gt;philoNum = PHILO_ID(me); pe-&gt;philoNum = PHILO_ID(me);
QF_PUBLISH(&amp;pe-&gt;super, me);</exit> QF_PUBLISH(&amp;pe-&gt;super, me);
QTimeEvt_disarm(&amp;me-&gt;timeEvt);</exit>
<tran trig="TIMEOUT" target="../../1"> <tran trig="TIMEOUT" target="../../1">
<tran_glyph conn="2,51,3,1,22,-41,-5"> <tran_glyph conn="2,51,3,1,22,-41,-5">
<action box="0,-2,6,2"/> <action box="0,-2,6,2"/>

View File

@ -119,6 +119,12 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) {
status_ = Q_HANDLED(); status_ = Q_HANDLED();
break; break;
} }
/*${AOs::Philo::SM::thinking} */
case Q_EXIT_SIG: {
QTimeEvt_disarm(&me->timeEvt);
status_ = Q_HANDLED();
break;
}
/*${AOs::Philo::SM::thinking::TIMEOUT} */ /*${AOs::Philo::SM::thinking::TIMEOUT} */
case TIMEOUT_SIG: { case TIMEOUT_SIG: {
status_ = Q_TRAN(&Philo_hungry); status_ = Q_TRAN(&Philo_hungry);
@ -191,6 +197,7 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) {
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe->philoNum = PHILO_ID(me); pe->philoNum = PHILO_ID(me);
QF_PUBLISH(&pe->super, me); QF_PUBLISH(&pe->super, me);
QTimeEvt_disarm(&me->timeEvt);
status_ = Q_HANDLED(); status_ = Q_HANDLED();
break; break;
} }

View File

@ -4,14 +4,14 @@
* @ingroup ports * @ingroup ports
* @cond * @cond
****************************************************************************** ******************************************************************************
* Last updated for version 6.0.4 * Last updated for version 6.2.0
* Last updated on 2018-01-09 * Last updated on 2018-04-06
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* --------------------------- * ---------------------------
* innovating embedded systems * innovating embedded systems
* *
* Copyright (C) Quantum Leaps, LLC. All rights reserved. * Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
* *
* This program is open source software: you can redistribute it and/or * This program is open source software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published * modify it under the terms of the GNU General Public License as published
@ -32,7 +32,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* Contact information: * Contact information:
* https://state-machine.com * https://www.state-machine.com
* mailto:info@state-machine.com * mailto:info@state-machine.com
****************************************************************************** ******************************************************************************
* @endcond * @endcond
@ -75,9 +75,18 @@ static void thread_function(ULONG thread_input) { /* ThreadX signature */
QActive_unsubscribeAll(act); /* unsubscribe from all events */ QActive_unsubscribeAll(act); /* unsubscribe from all events */
QF_remove_(act); /* remove this active object from QF */ QF_remove_(act); /* remove this active object from QF */
/* cleanup of the queue and thread must succeed */ /* cleanup of the queue must succeed */
Q_ALLEGE_ID(110, tx_queue_delete(&act->eQueue) == TX_SUCCESS); Q_ALLEGE_ID(110, tx_queue_delete(&act->eQueue) == TX_SUCCESS);
Q_ALLEGE_ID(120, tx_thread_delete(&act->thread) == TX_SUCCESS);
/* NOTE:
* The internal resources allocated for the task by the ThreadX RTOS
* cannot be reclaimed at this point, because ThreadX prohibits calling
* tx_thread_delete() from the task itself. Therefore, the burden of
* cleaning up after the task is left to the application to call
* tx_thread_delete(&act->thread) before the application can reuse
* the stack allocated to this thread or create a new thread
* to replace this one.
*/
} }
/*..........................................................................*/ /*..........................................................................*/
void QActive_start_(QActive * const me, uint_fast8_t prio, void QActive_start_(QActive * const me, uint_fast8_t prio,
@ -120,6 +129,9 @@ void QActive_start_(QActive * const me, uint_fast8_t prio,
} }
/*..........................................................................*/ /*..........................................................................*/
void QActive_stop(QActive * const me) { void QActive_stop(QActive * const me) {
/* active object must stop itself and cannot be stopped by any other AO */
Q_REQUIRE_ID(300, &me->thread == tx_thread_identify());
me->osObject = (uint8_t)0; /* stop the thread loop */ me->osObject = (uint8_t)0; /* stop the thread loop */
} }
/*..........................................................................*/ /*..........................................................................*/
@ -158,10 +170,10 @@ bool QActive_post_(QActive * const me, QEvt const * const e,
QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO,
QS_priv_.locFilter[AO_OBJ], me) QS_priv_.locFilter[AO_OBJ], me)
QS_TIME_(); /* timestamp */ QS_TIME_(); /* timestamp */
QS_OBJ_(sender); /* the sender object */ QS_OBJ_(sender); /* the sender object */
QS_SIG_(e->sig); /* the signal of the event */ QS_SIG_(e->sig); /* the signal of the event */
QS_OBJ_(me); /* this active object (recipient) */ QS_OBJ_(me); /* this active object (recipient) */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
QS_EQC_((QEQueueCtr)nFree); /* # free entries available */ QS_EQC_((QEQueueCtr)nFree); /* # free entries available */
QS_EQC_((QEQueueCtr)0); /* min # free entries (unknown) */ QS_EQC_((QEQueueCtr)0); /* min # free entries (unknown) */
@ -182,10 +194,10 @@ bool QActive_post_(QActive * const me, QEvt const * const e,
QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_ATTEMPT, QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_ATTEMPT,
QS_priv_.locFilter[AO_OBJ], me) QS_priv_.locFilter[AO_OBJ], me)
QS_TIME_(); /* timestamp */ QS_TIME_(); /* timestamp */
QS_OBJ_(sender); /* the sender object */ QS_OBJ_(sender); /* the sender object */
QS_SIG_(e->sig); /* the signal of the event */ QS_SIG_(e->sig); /* the signal of the event */
QS_OBJ_(me); /* this active object (recipient) */ QS_OBJ_(me); /* this active object (recipient) */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
QS_EQC_((QEQueueCtr)nFree); /* # free entries available */ QS_EQC_((QEQueueCtr)nFree); /* # free entries available */
QS_EQC_((QEQueueCtr)0); /* min # free entries (unknown) */ QS_EQC_((QEQueueCtr)0); /* min # free entries (unknown) */
@ -203,9 +215,9 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) {
QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO,
QS_priv_.locFilter[AO_OBJ], me) QS_priv_.locFilter[AO_OBJ], me)
QS_TIME_(); /* timestamp */ QS_TIME_(); /* timestamp */
QS_SIG_(e->sig); /* the signal of this event */ QS_SIG_(e->sig); /* the signal of this event */
QS_OBJ_(me); /* this active object */ QS_OBJ_(me); /* this active object */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
/* # free entries */ /* # free entries */
QS_EQC_((QEQueueCtr)me->eQueue.tx_queue_available_storage); QS_EQC_((QEQueueCtr)me->eQueue.tx_queue_available_storage);
@ -233,9 +245,9 @@ QEvt const *QActive_get_(QActive * const me) {
== TX_SUCCESS); == TX_SUCCESS);
QS_BEGIN_(QS_QF_ACTIVE_GET, QS_priv_.locFilter[AO_OBJ], me) QS_BEGIN_(QS_QF_ACTIVE_GET, QS_priv_.locFilter[AO_OBJ], me)
QS_TIME_(); /* timestamp */ QS_TIME_(); /* timestamp */
QS_SIG_(e->sig); /* the signal of this event */ QS_SIG_(e->sig); /* the signal of this event */
QS_OBJ_(me); /* this active object */ QS_OBJ_(me); /* this active object */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
/* # free entries */ /* # free entries */
QS_EQC_((QEQueueCtr)me->eQueue.tx_queue_available_storage); QS_EQC_((QEQueueCtr)me->eQueue.tx_queue_available_storage);