////////////////////////////////////////////////////////////////////////////// // Model: dpp.qm // File: ./philo.cpp // // This file has been generated automatically by QP Modeler (QM). // DO NOT EDIT THIS FILE MANUALLY. // // Please visit www.state-machine.com/qm for more information. ////////////////////////////////////////////////////////////////////////////// #include "qp_port.h" #include "dpp.h" #include "bsp.h" //Q_DEFINE_THIS_FILE /* Active object class -----------------------------------------------------*/ // @(/2/0) ................................................................... class Philo : public QP::QActive { private: QTimeEvt m_timeEvt; public: Philo(); protected: static QP::QState initial(Philo * const me, QP::QEvt const * const e); static QP::QState thinking(Philo * const me, QP::QEvt const * const e); static QP::QState hungry(Philo * const me, QP::QEvt const * const e); static QP::QState eating(Philo * const me, QP::QEvt const * const e); }; /* Local objects -----------------------------------------------------------*/ static Philo l_philo[N_PHILO]; /* storage for all Philos */ #define THINK_TIME ((BSP_TICKS_PER_SEC) / 2) #define EAT_TIME ((BSP_TICKS_PER_SEC) / 5) /* helper macro to provide the ID of Philo "me_" */ #define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) enum InternalSignals { /* internal signals */ TIMEOUT_SIG = MAX_SIG }; /* Global objects ----------------------------------------------------------*/ QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ (QActive *)&l_philo[0], (QActive *)&l_philo[1], (QActive *)&l_philo[2], (QActive *)&l_philo[3], (QActive *)&l_philo[4] }; /* Philo definition --------------------------------------------------------*/ // @(/2/0) ................................................................... // @(/2/0/1) ................................................................. Philo::Philo() : QActive((QStateHandler)&Philo::initial), m_timeEvt(TIMEOUT_SIG) { } // @(/2/0/2) ................................................................. // @(/2/0/2/0) QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) { static uint8_t registered; // starts off with 0, per C-standard (void)e; // suppress the compiler warning about unused parameter if (!registered) { QS_OBJ_DICTIONARY(&l_philo[0]); QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); QS_OBJ_DICTIONARY(&l_philo[1]); QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); QS_OBJ_DICTIONARY(&l_philo[2]); QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); QS_OBJ_DICTIONARY(&l_philo[3]); QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); QS_OBJ_DICTIONARY(&l_philo[4]); QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); QS_FUN_DICTIONARY(&Philo::initial); QS_FUN_DICTIONARY(&Philo::thinking); QS_FUN_DICTIONARY(&Philo::hungry); QS_FUN_DICTIONARY(&Philo::eating); registered = (uint8_t)1; } QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos //me->subscribe(EAT_SIG); return Q_TRAN(&Philo::thinking); } // @(/2/0/2/1) ............................................................... QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) { QP::QState status; switch (e->sig) { // @(/2/0/2/1) case Q_ENTRY_SIG: { me->m_timeEvt.postIn(me, THINK_TIME); status = Q_HANDLED(); break; } // @(/2/0/2/1/0) case TIMEOUT_SIG: { BSP_busyDelay(); status = Q_TRAN(&Philo::hungry); break; } default: { status = Q_SUPER(&QHsm::top); break; } } return status; } // @(/2/0/2/2) ............................................................... QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) { QP::QState status; switch (e->sig) { // @(/2/0/2/2) case Q_ENTRY_SIG: { TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); pe->philoNum = PHILO_ID(me); AO_Table->POST(pe, me); status = Q_HANDLED(); break; } // @(/2/0/2/2/0) case EAT_SIG: { // @(/2/0/2/2/0/0) if (((TableEvt const *)e)->philoNum == PHILO_ID(me)) { BSP_busyDelay(); status = Q_TRAN(&Philo::eating); } else { status = Q_UNHANDLED(); } break; } default: { status = Q_SUPER(&QHsm::top); break; } } return status; } // @(/2/0/2/3) ............................................................... QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) { QP::QState status; switch (e->sig) { // @(/2/0/2/3) case Q_ENTRY_SIG: { me->m_timeEvt.postIn(me, EAT_TIME); status = Q_HANDLED(); break; } // @(/2/0/2/3) case Q_EXIT_SIG: { TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); pe->philoNum = PHILO_ID(me); AO_Table->POST(pe, me); status = Q_HANDLED(); break; } // @(/2/0/2/3/0) case TIMEOUT_SIG: { BSP_busyDelay(); status = Q_TRAN(&Philo::thinking); break; } default: { status = Q_SUPER(&QHsm::top); break; } } return status; }