Quantum Leaps / Mbed 2 deprecated qp_lwip

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers philo.cpp Source File

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