Quantum Leaps / Mbed 2 deprecated qp_lwip

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers table.cpp Source File

table.cpp

00001 //////////////////////////////////////////////////////////////////////////////
00002 // Product: DPP example
00003 // Last Updated for Version: 4.0.00
00004 // Date of the Last Update:  Apr 06, 2008
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2008 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 Table : public QActive {
00036 private:
00037     uint8_t m_fork[N_PHILO];
00038     uint8_t m_isHungry[N_PHILO];
00039 
00040 public:
00041     Table();
00042 
00043 private:
00044     static QState initial(Table *me, QEvent const *e);
00045     static QState serving(Table *me, QEvent const *e);
00046 };
00047 
00048 #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1)) % N_PHILO))
00049 #define LEFT(n_)  ((uint8_t)(((n_) + 1) % N_PHILO))
00050 enum ForkState { FREE, USED };
00051 
00052 // Local objects -------------------------------------------------------------
00053 static Table l_table;                                    // local Table object
00054 
00055 // Public-scope objects ------------------------------------------------------
00056 QActive * const AO_Table = &l_table;                    // "opaque" AO pointer
00057 
00058 //............................................................................
00059 Table::Table() : QActive((QStateHandler)&Table::initial) {
00060     uint8_t n;
00061     for (n = 0; n < N_PHILO; ++n) {
00062         m_fork[n] = FREE;
00063         m_isHungry[n] = 0;
00064     }
00065 }
00066 //............................................................................
00067 QState Table::initial(Table *me, QEvent const *) {
00068 
00069     QS_OBJ_DICTIONARY(&l_table);
00070     QS_FUN_DICTIONARY(&QHsm::top);
00071     QS_FUN_DICTIONARY(&Table::initial);
00072     QS_FUN_DICTIONARY(&Table::serving);
00073 
00074     QS_SIG_DICTIONARY(DONE_SIG,      0);                     // global signals
00075     QS_SIG_DICTIONARY(EAT_SIG,       0);
00076     QS_SIG_DICTIONARY(TERMINATE_SIG, 0);
00077 
00078     QS_SIG_DICTIONARY(HUNGRY_SIG,    me);             // signal just for Table
00079 
00080     me->subscribe(DONE_SIG);
00081     me->subscribe(TERMINATE_SIG);
00082 
00083     return Q_TRAN(&Table::serving);
00084 }
00085 //............................................................................
00086 QState Table::serving(Table *me, QEvent const *e) {
00087     uint8_t n, m;
00088     TableEvt *pe;
00089 
00090     switch (e->sig) {
00091         case HUNGRY_SIG: {
00092             n = ((TableEvt const *)e)->philoNum;
00093                          // phil ID must be in range and he must be not hungry
00094             Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
00095 
00096             BSP_displyPhilStat(n, "hungry  ");
00097             m = LEFT(n);
00098             if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) {
00099                 me->m_fork[m] = me->m_fork[n] = USED;
00100                 pe = Q_NEW(TableEvt, EAT_SIG);
00101                 pe->philoNum = n;
00102                 QF::publish(pe);
00103                 BSP_displyPhilStat(n, "eating  ");
00104             }
00105             else {
00106                 me->m_isHungry[n] = 1;
00107             }
00108             return Q_HANDLED();
00109         }
00110         case DONE_SIG: {
00111             n = ((TableEvt const *)e)->philoNum;
00112                          // phil ID must be in range and he must be not hungry
00113             Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
00114 
00115             BSP_displyPhilStat(n, "thinking");
00116             m = LEFT(n);
00117                                          // both forks of Phil[n] must be used
00118             Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
00119 
00120             me->m_fork[m] = me->m_fork[n] = FREE;
00121             m = RIGHT(n);                          // check the right neighbor
00122             if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) {
00123                 me->m_fork[n] = me->m_fork[m] = USED;
00124                 me->m_isHungry[m] = 0;
00125                 pe = Q_NEW(TableEvt, EAT_SIG);
00126                 pe->philoNum = m;
00127                 QF::publish(pe);
00128                 BSP_displyPhilStat(m, "eating  ");
00129             }
00130             m = LEFT(n);                            // check the left neighbor
00131             n = LEFT(m);                     // left fork of the left neighbor
00132             if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) {
00133                 me->m_fork[m] = me->m_fork[n] = USED;
00134                 me->m_isHungry[m] = 0;
00135                 pe = Q_NEW(TableEvt, EAT_SIG);
00136                 pe->philoNum = m;
00137                 QF::publish(pe);
00138                 BSP_displyPhilStat(m, "eating  ");
00139             }
00140             return Q_HANDLED();
00141         }
00142     }
00143     return Q_SUPER(&QHsm::top);
00144 }