507 lines
17 KiB
Plaintext
Raw Normal View History

2016-07-09 12:58:13 -04:00
<?xml version="1.0" encoding="UTF-8"?>
2022-08-11 15:36:19 -04:00
<model version="5.2.0" links="1">
<documentation>Dining Philosopher Problem example with MSM state machines</documentation>
2019-12-31 15:56:23 -05:00
<!--${qpcpp}-->
2022-08-11 15:36:19 -04:00
<framework name="qpcpp" license="../../../LICENSES/QM-EVAL-QPCPP.qlc"/>
2019-12-31 15:56:23 -05:00
<!--${Events}-->
2016-07-09 12:58:13 -04:00
<package name="Events" stereotype="0x01" namespace="DPP::">
2019-12-31 15:56:23 -05:00
<!--${Events::TableEvt}-->
2016-07-09 12:58:13 -04:00
<class name="TableEvt" superclass="qpcpp::QEvt">
2019-12-31 15:56:23 -05:00
<!--${Events::TableEvt::philoNum}-->
2016-07-09 12:58:13 -04:00
<attribute name="philoNum" type="uint8_t" visibility="0x00" properties="0x00"/>
</class>
</package>
2019-12-31 15:56:23 -05:00
<!--${AOs}-->
2016-07-09 12:58:13 -04:00
<package name="AOs" stereotype="0x02" namespace="DPP::">
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo}-->
2016-07-09 12:58:13 -04:00
<class name="Philo" superclass="qpcpp::QMActive">
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::m_timeEvt}-->
2016-07-09 12:58:13 -04:00
<attribute name="m_timeEvt" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::Philo}-->
2016-07-09 12:58:13 -04:00
<operation name="Philo" type="" visibility="0x00" properties="0x00">
<code> : QMActive(Q_STATE_CAST(&amp;Philo::initial)),
m_timeEvt(this, TIMEOUT_SIG, 0U)</code>
</operation>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM}-->
2019-04-16 22:11:29 -04:00
<statechart properties="0x02">
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::initial}-->
2016-07-09 12:58:13 -04:00
<initial target="../1">
<action>static bool registered = false; // starts off with 0, per C-standard
(void)e; // suppress the compiler warning about unused parameter
if (!registered) {
registered = true;
QS_OBJ_DICTIONARY(&amp;l_philo[0]);
QS_OBJ_DICTIONARY(&amp;l_philo[0].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[1]);
QS_OBJ_DICTIONARY(&amp;l_philo[1].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[2]);
QS_OBJ_DICTIONARY(&amp;l_philo[2].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[3]);
QS_OBJ_DICTIONARY(&amp;l_philo[3].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[4]);
QS_OBJ_DICTIONARY(&amp;l_philo[4].m_timeEvt);
QS_FUN_DICTIONARY(&amp;Philo::initial);
QS_FUN_DICTIONARY(&amp;Philo::thinking);
QS_FUN_DICTIONARY(&amp;Philo::hungry);
QS_FUN_DICTIONARY(&amp;Philo::eating);
}
2019-04-16 22:11:29 -04:00
QS_SIG_DICTIONARY(HUNGRY_SIG, this); // signal for each Philos
QS_SIG_DICTIONARY(TIMEOUT_SIG, this); // signal for each Philos
2016-07-09 12:58:13 -04:00
2019-04-16 22:11:29 -04:00
subscribe(EAT_SIG);
subscribe(TEST_SIG);</action>
2016-07-09 12:58:13 -04:00
<initial_glyph conn="2,3,5,1,20,5,-3">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::thinking}-->
2016-07-09 12:58:13 -04:00
<state name="thinking">
2019-04-16 22:11:29 -04:00
<entry>m_timeEvt.armX(think_time(), 0U);</entry>
<exit>(void)m_timeEvt.disarm();</exit>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::thinking::TIMEOUT}-->
2016-07-09 12:58:13 -04:00
<tran trig="TIMEOUT" target="../../2">
2016-12-01 10:31:49 -05:00
<tran_glyph conn="2,13,3,1,20,12,-3">
2016-07-09 12:58:13 -04:00
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::thinking::EAT, DONE}-->
2016-07-09 12:58:13 -04:00
<tran trig="EAT, DONE">
<action>/* EAT or DONE must be for other Philos than this one */
2019-04-16 22:11:29 -04:00
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(this));</action>
2016-12-01 10:31:49 -05:00
<tran_glyph conn="2,16,3,-1,13">
2016-07-09 12:58:13 -04:00
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::thinking::TEST}-->
2016-12-01 10:31:49 -05:00
<tran trig="TEST">
<tran_glyph conn="2,19,3,-1,13">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
2016-07-09 12:58:13 -04:00
<state_glyph node="2,5,17,16">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::hungry}-->
2016-07-09 12:58:13 -04:00
<state name="hungry">
<entry>TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
2019-04-16 22:11:29 -04:00
pe-&gt;philoNum = PHILO_ID(this);
AO_Table-&gt;POST(pe, this);</entry>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::hungry::EAT}-->
2016-07-09 12:58:13 -04:00
<tran trig="EAT">
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~}-->
2016-07-09 12:58:13 -04:00
<choice target="../../../3">
2019-04-16 22:11:29 -04:00
<guard>Q_EVT_CAST(TableEvt)-&gt;philoNum == PHILO_ID(this)</guard>
2016-07-09 12:58:13 -04:00
<choice_glyph conn="15,30,5,1,7,13,-3">
<action box="1,0,19,4"/>
</choice_glyph>
</choice>
<tran_glyph conn="2,30,3,-1,13">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::hungry::DONE}-->
2016-07-09 12:58:13 -04:00
<tran trig="DONE">
<action>/* DONE must be for other Philos than this one */
2019-04-16 22:11:29 -04:00
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(this));</action>
2016-07-09 12:58:13 -04:00
<tran_glyph conn="2,36,3,-1,14">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,23,17,16">
<entry box="1,2,5,2"/>
</state_glyph>
</state>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::eating}-->
2016-07-09 12:58:13 -04:00
<state name="eating">
2019-04-16 22:11:29 -04:00
<entry>m_timeEvt.armX(eat_time(), 0U);</entry>
2016-07-09 12:58:13 -04:00
<exit>TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
2019-04-16 22:11:29 -04:00
pe-&gt;philoNum = PHILO_ID(this);
2022-08-11 15:36:19 -04:00
QP::QActive::PUBLISH(pe, this);
2019-04-16 22:11:29 -04:00
(void)m_timeEvt.disarm();</exit>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::eating::TIMEOUT}-->
2016-07-09 12:58:13 -04:00
<tran trig="TIMEOUT" target="../../1">
<tran_glyph conn="2,51,3,1,22,-41,-5">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Philo::SM::eating::EAT, DONE}-->
2016-07-09 12:58:13 -04:00
<tran trig="EAT, DONE">
<action>/* EAT or DONE must be for other Philos than this one */
2019-04-16 22:11:29 -04:00
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(this));</action>
2016-07-09 12:58:13 -04:00
<tran_glyph conn="2,55,3,-1,13">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,41,17,18">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
2016-12-01 10:31:49 -05:00
<state_diagram size="36,61"/>
2016-07-09 12:58:13 -04:00
</statechart>
</class>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table}-->
2016-07-09 12:58:13 -04:00
<class name="Table" superclass="qpcpp::QMActive">
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::m_fork[N_PHILO]}-->
2016-07-09 12:58:13 -04:00
<attribute name="m_fork[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::m_isHungry[N_PHILO]}-->
2016-07-09 12:58:13 -04:00
<attribute name="m_isHungry[N_PHILO]" type="bool" visibility="0x02" properties="0x00"/>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::Table}-->
2016-07-09 12:58:13 -04:00
<operation name="Table" type="" visibility="0x00" properties="0x00">
<code> : QMActive(Q_STATE_CAST(&amp;Table::initial))
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}</code>
</operation>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM}-->
2019-04-16 22:11:29 -04:00
<statechart properties="0x02">
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::initial}-->
2016-07-09 12:58:13 -04:00
<initial target="../1/2">
<action>(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&amp;l_table);
QS_FUN_DICTIONARY(&amp;QP::QHsm::top);
QS_FUN_DICTIONARY(&amp;Table::initial);
QS_FUN_DICTIONARY(&amp;Table::active);
QS_FUN_DICTIONARY(&amp;Table::serving);
QS_FUN_DICTIONARY(&amp;Table::paused);
2020-04-02 21:21:53 -04:00
QS_SIG_DICTIONARY(DONE_SIG, nullptr); // global signals
QS_SIG_DICTIONARY(EAT_SIG, nullptr);
QS_SIG_DICTIONARY(PAUSE_SIG, nullptr);
QS_SIG_DICTIONARY(SERVE_SIG, nullptr);
QS_SIG_DICTIONARY(TEST_SIG, nullptr);
2016-07-09 12:58:13 -04:00
2019-04-16 22:11:29 -04:00
QS_SIG_DICTIONARY(HUNGRY_SIG, this); // signal just for Table
2016-07-09 12:58:13 -04:00
2019-04-16 22:11:29 -04:00
subscribe(DONE_SIG);
subscribe(PAUSE_SIG);
subscribe(SERVE_SIG);
subscribe(TEST_SIG);
2016-07-09 12:58:13 -04:00
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
2019-04-16 22:11:29 -04:00
m_fork[n] = FREE;
m_isHungry[n] = false;
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, THINKING);
}</action>
2016-12-01 10:31:49 -05:00
<initial_glyph conn="3,3,5,1,45,18,-10">
2016-07-09 12:58:13 -04:00
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active}-->
2016-07-09 12:58:13 -04:00
<state name="active">
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::TEST}-->
2016-12-01 10:31:49 -05:00
<tran trig="TEST">
2016-07-09 12:58:13 -04:00
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::EAT}-->
2016-07-09 12:58:13 -04:00
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="2,15,3,-1,14">
<action box="0,-2,10,4"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving}-->
2016-07-09 12:58:13 -04:00
<state name="serving">
<entry brief="give pending permitions to eat">for (uint8_t n = 0U; n &lt; N_PHILO; ++n) { // give permissions to eat...
2019-04-16 22:11:29 -04:00
if (m_isHungry[n]
&amp;&amp; (m_fork[LEFT(n)] == FREE)
&amp;&amp; (m_fork[n] == FREE))
2016-07-09 12:58:13 -04:00
{
2019-04-16 22:11:29 -04:00
m_fork[LEFT(n)] = USED;
m_fork[n] = USED;
2016-07-09 12:58:13 -04:00
TableEvt *te = Q_NEW(TableEvt, EAT_SIG);
te-&gt;philoNum = n;
2022-08-11 15:36:19 -04:00
QP::QActive::PUBLISH(te, this);
2019-04-16 22:11:29 -04:00
m_isHungry[n] = false;
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, EATING);
}
}</entry>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving::HUNGRY}-->
2016-07-09 12:58:13 -04:00
<tran trig="HUNGRY">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// phil ID must be in range and he must be not hungry
2019-04-16 22:11:29 -04:00
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, HUNGRY);
uint8_t m = LEFT(n);</action>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving::HUNGRY::[bothfree]}-->
2016-07-09 12:58:13 -04:00
<choice>
2019-04-16 22:11:29 -04:00
<guard brief="both free">(m_fork[m] == FREE) &amp;&amp; (m_fork[n] == FREE)</guard>
<action>m_fork[m] = USED;
m_fork[n] = USED;
2016-07-09 12:58:13 -04:00
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoNum = n;
2022-08-11 15:36:19 -04:00
QP::QActive::PUBLISH(pe, this);
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, EATING);</action>
<choice_glyph conn="19,26,5,-1,10">
<action box="1,0,10,2"/>
</choice_glyph>
</choice>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving::HUNGRY::[else]}-->
2016-07-09 12:58:13 -04:00
<choice>
<guard>else</guard>
2019-04-16 22:11:29 -04:00
<action>m_isHungry[n] = true;</action>
2016-07-09 12:58:13 -04:00
<choice_glyph conn="19,26,4,-1,5,10">
<action box="1,5,6,2"/>
</choice_glyph>
</choice>
<tran_glyph conn="4,26,3,-1,15">
<action box="0,-2,8,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving::DONE}-->
2016-07-09 12:58:13 -04:00
<tran trig="DONE">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// phil ID must be in range and he must be not hungry
2019-04-16 22:11:29 -04:00
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
2019-04-16 22:11:29 -04:00
Q_ASSERT((m_fork[n] == USED) &amp;&amp; (m_fork[m] == USED));
2016-07-09 12:58:13 -04:00
2019-04-16 22:11:29 -04:00
m_fork[m] = FREE;
m_fork[n] = FREE;
2016-07-09 12:58:13 -04:00
m = RIGHT(n); // check the right neighbor
2019-04-16 22:11:29 -04:00
if (m_isHungry[m] &amp;&amp; (m_fork[m] == FREE)) {
m_fork[n] = USED;
m_fork[m] = USED;
m_isHungry[m] = false;
2016-07-09 12:58:13 -04:00
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoNum = m;
2022-08-11 15:36:19 -04:00
QP::QActive::PUBLISH(pe, this);
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(m, EATING);
}
m = LEFT(n); // check the left neighbor
n = LEFT(m); // left fork of the left neighbor
2019-04-16 22:11:29 -04:00
if (m_isHungry[m] &amp;&amp; (m_fork[n] == FREE)) {
m_fork[m] = USED;
m_fork[n] = USED;
m_isHungry[m] = false;
2016-07-09 12:58:13 -04:00
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoNum = m;
2022-08-11 15:36:19 -04:00
QP::QActive::PUBLISH(pe, this);
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(m, EATING);
}</action>
<tran_glyph conn="4,34,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving::EAT}-->
2016-07-09 12:58:13 -04:00
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="4,37,3,-1,15">
<action box="0,-2,12,4"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::serving::PAUSE}-->
2016-07-09 12:58:13 -04:00
<tran trig="PAUSE" target="../../3">
<tran_glyph conn="4,41,3,1,37,6,-3">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,19,34,24">
<entry box="1,2,27,2"/>
</state_glyph>
</state>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::paused}-->
2016-07-09 12:58:13 -04:00
<state name="paused">
<entry>BSP::displayPaused(1U);</entry>
<exit>BSP::displayPaused(0U);</exit>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::paused::SERVE}-->
2016-07-09 12:58:13 -04:00
<tran trig="SERVE" target="../../2">
<tran_glyph conn="4,57,3,1,39,-29,-5">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::paused::HUNGRY}-->
2016-07-09 12:58:13 -04:00
<tran trig="HUNGRY">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// philo ID must be in range and he must be not hungry
2019-04-16 22:11:29 -04:00
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
m_isHungry[n] = true;
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, HUNGRY);</action>
<tran_glyph conn="4,60,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
2019-12-31 15:56:23 -05:00
<!--${AOs::Table::SM::active::paused::DONE}-->
2016-07-09 12:58:13 -04:00
<tran trig="DONE">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// phil ID must be in range and he must be not hungry
2019-04-16 22:11:29 -04:00
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
2016-07-09 12:58:13 -04:00
BSP::displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
/* both forks of Phil[n] must be used */
2019-04-16 22:11:29 -04:00
Q_ASSERT((m_fork[n] == USED) &amp;&amp; (m_fork[m] == USED));
2016-07-09 12:58:13 -04:00
2019-04-16 22:11:29 -04:00
m_fork[m] = FREE;
m_fork[n] = FREE;</action>
2016-07-09 12:58:13 -04:00
<tran_glyph conn="4,63,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,45,34,20">
<entry box="1,2,18,4"/>
<exit box="1,6,18,4"/>
</state_glyph>
</state>
2016-12-01 10:31:49 -05:00
<state_glyph node="2,5,44,62"/>
2016-07-09 12:58:13 -04:00
</state>
2016-12-01 10:31:49 -05:00
<state_diagram size="50,69"/>
2016-07-09 12:58:13 -04:00
</statechart>
</class>
2019-12-31 15:56:23 -05:00
<!--${AOs::AO_Philo[N_PHILO]}-->
2016-12-01 10:31:49 -05:00
<attribute name="AO_Philo[N_PHILO]" type="QP::QActive * const" visibility="0x00" properties="0x00"/>
2019-12-31 15:56:23 -05:00
<!--${AOs::AO_Table}-->
2016-12-01 10:31:49 -05:00
<attribute name="AO_Table" type="QP::QActive * const" visibility="0x00" properties="0x00"/>
2019-12-31 15:56:23 -05:00
<!--${AOs::XT_Test1}-->
2016-12-01 10:31:49 -05:00
<attribute name="XT_Test1" type="QP::QXThread * const" visibility="0x00" properties="0x00"/>
2019-12-31 15:56:23 -05:00
<!--${AOs::XT_Test2}-->
2016-12-01 10:31:49 -05:00
<attribute name="XT_Test2" type="QP::QXThread * const" visibility="0x00" properties="0x00"/>
2016-07-09 12:58:13 -04:00
</package>
2019-12-31 15:56:23 -05:00
<!--${.}-->
2016-07-09 12:58:13 -04:00
<directory name=".">
2019-12-31 15:56:23 -05:00
<!--${.::dpp.hpp}-->
2019-10-27 12:26:31 -04:00
<file name="dpp.hpp">
<text>#ifndef DPP_HPP
#define DPP_HPP
2016-07-09 12:58:13 -04:00
namespace DPP {
enum DPPSignals {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a philosopher eat
DONE_SIG, // published by Philosopher when done eating
PAUSE_SIG, // published by BSP to pause the application
SERVE_SIG, // published by BSP to serve re-start serving forks
2016-12-01 10:31:49 -05:00
TEST_SIG, // published by BSP to test the application
2016-07-09 12:58:13 -04:00
MAX_PUB_SIG, // the last published signal
HUNGRY_SIG, // posted direclty to Table from hungry Philo
MAX_SIG // the last signal
};
} // namespace DPP
$declare(Events::TableEvt)
// number of philosophers
#define N_PHILO ((uint8_t)5)
$declare(AOs::AO_Philo[N_PHILO])
$declare(AOs::AO_Table)
2019-10-27 12:26:31 -04:00
#ifdef QXK_HPP
2016-12-01 10:31:49 -05:00
$declare(AOs::XT_Test1)
$declare(AOs::XT_Test2)
2019-10-27 12:26:31 -04:00
#endif // QXK_HPP
2016-12-01 10:31:49 -05:00
2019-10-27 12:26:31 -04:00
#endif // DPP_HPP</text>
2016-07-09 12:58:13 -04:00
</file>
2019-12-31 15:56:23 -05:00
<!--${.::philo.cpp}-->
2016-07-09 12:58:13 -04:00
<file name="philo.cpp">
2019-10-27 12:26:31 -04:00
<text>#include &quot;qpcpp.hpp&quot;
#include &quot;dpp.hpp&quot;
#include &quot;bsp.hpp&quot;
2016-07-09 12:58:13 -04:00
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
$declare(AOs::Philo)
namespace DPP {
// Local objects -------------------------------------------------------------
static Philo l_philo[N_PHILO]; // storage for all Philos
// helper function to provide a randomized think time for Philos
inline QP::QTimeEvtCtr think_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP::random() % BSP::TICKS_PER_SEC)
+ (BSP::TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
inline QP::QTimeEvtCtr eat_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP::random() % BSP::TICKS_PER_SEC)
+ BSP::TICKS_PER_SEC);
}
2019-04-16 22:11:29 -04:00
// helper function to provide the ID of Philo &quot;this&quot;
2016-07-09 12:58:13 -04:00
inline uint8_t PHILO_ID(Philo const * const me) {
return static_cast&lt;uint8_t&gt;(me - l_philo);
}
enum InternalSignals { // internal signals
TIMEOUT_SIG = MAX_SIG
};
// Global objects ------------------------------------------------------------
2016-12-01 10:31:49 -05:00
QP::QActive * const AO_Philo[N_PHILO] = { // &quot;opaque&quot; pointers to Philo AO
2016-07-09 12:58:13 -04:00
&amp;l_philo[0],
&amp;l_philo[1],
&amp;l_philo[2],
&amp;l_philo[3],
&amp;l_philo[4]
};
} // namespace DPP
// Philo definition ----------------------------------------------------------
$define(AOs::Philo)</text>
</file>
2019-12-31 15:56:23 -05:00
<!--${.::table.cpp}-->
2016-07-09 12:58:13 -04:00
<file name="table.cpp">
2019-10-27 12:26:31 -04:00
<text>#include &quot;qpcpp.hpp&quot;
#include &quot;dpp.hpp&quot;
#include &quot;bsp.hpp&quot;
2016-07-09 12:58:13 -04:00
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
$declare(AOs::Table)
namespace DPP {
// helper function to provide the RIGHT neighbour of a Philo[n]
inline uint8_t RIGHT(uint8_t const n) {
return static_cast&lt;uint8_t&gt;((n + (N_PHILO - 1U)) % N_PHILO);
}
// helper function to provide the LEFT neighbour of a Philo[n]
inline uint8_t LEFT(uint8_t const n) {
return static_cast&lt;uint8_t&gt;((n + 1U) % N_PHILO);
}
static uint8_t const FREE = static_cast&lt;uint8_t&gt;(0);
static uint8_t const USED = static_cast&lt;uint8_t&gt;(1);
2022-08-11 15:36:19 -04:00
static char const * const THINKING = &amp;&quot;thinking&quot;[0];
static char const * const HUNGRY = &amp;&quot;hungry &quot;[0];
static char const * const EATING = &amp;&quot;eating &quot;[0];
2016-07-09 12:58:13 -04:00
// Local objects -------------------------------------------------------------
static Table l_table; // the single instance of the Table active object
// Global-scope objects ------------------------------------------------------
2016-12-01 10:31:49 -05:00
QP::QActive * const AO_Table = &amp;l_table; // &quot;opaque&quot; AO pointer
2016-07-09 12:58:13 -04:00
} // namespace DPP
//............................................................................
$define(AOs::Table)</text>
</file>
</directory>
</model>