Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
philo.cpp
00001 ////////////////////////////////////////////////////////////////////////////// 00002 // Product: DPP example 00003 // Last Updated for Version: 4.0.03 00004 // Date of the Last Update: Mar 16, 2009 00005 // 00006 // Q u a n t u m L e a P s 00007 // --------------------------- 00008 // innovating embedded systems 00009 // 00010 // Copyright (C) 2002-2009 Quantum Leaps, LLC. All rights reserved. 00011 // 00012 // This software may be distributed and modified under the terms of the GNU 00013 // General Public License version 2 (GPL) as published by the Free Software 00014 // Foundation and appearing in the file GPL.TXT included in the packaging of 00015 // this file. Please note that GPL Section 2[b] requires that all works based 00016 // on this software must also be made publicly available under the terms of 00017 // the GPL ("Copyleft"). 00018 // 00019 // Alternatively, this software may be distributed and modified under the 00020 // terms of Quantum Leaps commercial licenses, which expressly supersede 00021 // the GPL and are specifically designed for licensees interested in 00022 // retaining the proprietary status of their code. 00023 // 00024 // Contact information: 00025 // Quantum Leaps Web site: http://www.quantum-leaps.com 00026 // e-mail: info@quantum-leaps.com 00027 ////////////////////////////////////////////////////////////////////////////// 00028 #include "qp_port.h" 00029 #include "dpp.h" 00030 #include "bsp.h" 00031 00032 Q_DEFINE_THIS_FILE 00033 00034 // Active object class ------------------------------------------------------- 00035 class Philo : public QActive { 00036 private: 00037 QTimeEvt m_timeEvt; // to timeout thinking or eating 00038 00039 public: 00040 Philo(); 00041 00042 private: 00043 static QState initial (Philo *me, QEvent const *e); 00044 static QState thinking(Philo *me, QEvent const *e); 00045 static QState hungry (Philo *me, QEvent const *e); 00046 static QState eating (Philo *me, QEvent const *e); 00047 }; 00048 00049 // Local objects ------------------------------------------------------------- 00050 static Philo l_philo[N_PHILO]; // storage for all Philos 00051 00052 #define THINK_TIME 17 00053 #define EAT_TIME 13 00054 // helper macro to provide the ID of Philo "me_" 00055 #define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) 00056 00057 enum InternalSignals { // internal signals 00058 TIMEOUT_SIG = MAX_SIG 00059 }; 00060 // Global objects ------------------------------------------------------------ 00061 QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AOs 00062 &l_philo[0], 00063 &l_philo[1], 00064 &l_philo[2], 00065 &l_philo[3], 00066 &l_philo[4] 00067 }; 00068 00069 //............................................................................ 00070 Philo::Philo() 00071 : QActive((QStateHandler)&Philo::initial), 00072 m_timeEvt(TIMEOUT_SIG) 00073 {} 00074 //............................................................................ 00075 QState Philo::initial(Philo *me, QEvent const *) { 00076 static uint8_t registered; // starts off with 0, per C-standard 00077 if (!registered) { 00078 QS_OBJ_DICTIONARY(&l_philo[0]); 00079 QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); 00080 QS_OBJ_DICTIONARY(&l_philo[1]); 00081 QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); 00082 QS_OBJ_DICTIONARY(&l_philo[2]); 00083 QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); 00084 QS_OBJ_DICTIONARY(&l_philo[3]); 00085 QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); 00086 QS_OBJ_DICTIONARY(&l_philo[4]); 00087 QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); 00088 00089 QS_FUN_DICTIONARY(&Philo::initial); 00090 QS_FUN_DICTIONARY(&Philo::thinking); 00091 QS_FUN_DICTIONARY(&Philo::hungry); 00092 QS_FUN_DICTIONARY(&Philo::eating); 00093 00094 registered = (uint8_t)1; 00095 } 00096 QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos 00097 QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos 00098 00099 me->subscribe(EAT_SIG); 00100 00101 return Q_TRAN(&Philo::thinking); 00102 } 00103 //............................................................................ 00104 QState Philo::thinking(Philo *me, QEvent const *e) { 00105 switch (e->sig) { 00106 case Q_ENTRY_SIG: { 00107 me->m_timeEvt.postIn(me, THINK_TIME); 00108 return Q_HANDLED(); 00109 } 00110 case TIMEOUT_SIG: { 00111 return Q_TRAN(&Philo::hungry); 00112 } 00113 case EAT_SIG: // intentionally fall-through 00114 case DONE_SIG: { 00115 // EAT or DONE must be for other Philos than this one 00116 Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me)); 00117 return Q_HANDLED(); 00118 } 00119 } 00120 return Q_SUPER(&QHsm::top); 00121 } 00122 //............................................................................ 00123 QState Philo::hungry(Philo *me, QEvent const *e) { 00124 switch (e->sig) { 00125 case Q_ENTRY_SIG: { 00126 TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); 00127 pe->philoNum = PHILO_ID(me); 00128 AO_Table->postFIFO(pe); 00129 return Q_HANDLED(); 00130 } 00131 case EAT_SIG: { 00132 if (((TableEvt *)e)->philoNum == PHILO_ID(me)) { 00133 return Q_TRAN(&Philo::eating); 00134 } 00135 break; 00136 } 00137 case DONE_SIG: { 00138 // DONE must be for other Philos than this one 00139 Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me)); 00140 return Q_HANDLED(); 00141 } 00142 } 00143 return Q_SUPER(&QHsm::top); 00144 } 00145 //............................................................................ 00146 QState Philo::eating(Philo *me, QEvent const *e) { 00147 switch (e->sig) { 00148 case Q_ENTRY_SIG: { 00149 me->m_timeEvt.postIn(me, EAT_TIME); 00150 return Q_HANDLED(); 00151 } 00152 case Q_EXIT_SIG: { 00153 TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); 00154 pe->philoNum = PHILO_ID(me); 00155 QF::publish(pe); 00156 return Q_HANDLED(); 00157 } 00158 case TIMEOUT_SIG: { 00159 return Q_TRAN(&Philo::thinking); 00160 } 00161 case EAT_SIG: // intentionally fall-through 00162 case DONE_SIG: { 00163 // EAT or DONE must be for other Philos than this one 00164 Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me)); 00165 return Q_HANDLED(); 00166 } 00167 } 00168 return Q_SUPER(&QHsm::top); 00169 } 00170
Generated on Tue Jul 19 2022 02:04:04 by
1.7.2