table.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*****************************************************************************
  2. * Model: dpp.qm
  3. * File: ./table.c
  4. *
  5. * This code has been generated by QM tool (see state-machine.com/qm).
  6. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  7. *
  8. * This program is open source software: you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as published
  10. * by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  15. * for more details.
  16. *****************************************************************************/
  17. /*${.::table.c} ............................................................*/
  18. #include "qpc.h"
  19. #include "dpp.h"
  20. #include "bsp.h"
  21. Q_DEFINE_THIS_FILE
  22. /* Active object class -----------------------------------------------------*/
  23. /*${AOs::Table} ............................................................*/
  24. typedef struct {
  25. /* protected: */
  26. QMActive super;
  27. /* private: */
  28. uint8_t fork[N_PHILO];
  29. uint8_t isHungry[N_PHILO];
  30. } Table;
  31. /* protected: */
  32. static QState Table_initial(Table * const me, QEvt const * const e);
  33. static QState Table_active (Table * const me, QEvt const * const e);
  34. static QMState const Table_active_s = {
  35. (QMState const *)0, /* superstate (top) */
  36. Q_STATE_CAST(&Table_active),
  37. Q_ACTION_CAST(0), /* no entry action */
  38. Q_ACTION_CAST(0), /* no exit action */
  39. Q_ACTION_CAST(0) /* no intitial tran. */
  40. };
  41. static QState Table_serving (Table * const me, QEvt const * const e);
  42. static QState Table_serving_e(Table * const me);
  43. static QMState const Table_serving_s = {
  44. &Table_active_s, /* superstate */
  45. Q_STATE_CAST(&Table_serving),
  46. Q_ACTION_CAST(&Table_serving_e),
  47. Q_ACTION_CAST(0), /* no exit action */
  48. Q_ACTION_CAST(0) /* no intitial tran. */
  49. };
  50. static QState Table_paused (Table * const me, QEvt const * const e);
  51. static QState Table_paused_e(Table * const me);
  52. static QState Table_paused_x(Table * const me);
  53. static QMState const Table_paused_s = {
  54. &Table_active_s, /* superstate */
  55. Q_STATE_CAST(&Table_paused),
  56. Q_ACTION_CAST(&Table_paused_e),
  57. Q_ACTION_CAST(&Table_paused_x),
  58. Q_ACTION_CAST(0) /* no intitial tran. */
  59. };
  60. #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO))
  61. #define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO))
  62. #define FREE ((uint8_t)0)
  63. #define USED ((uint8_t)1)
  64. /* Local objects -----------------------------------------------------------*/
  65. static Table l_table; /* the single instance of the Table active object */
  66. /* Global-scope objects ----------------------------------------------------*/
  67. QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */
  68. /*..........................................................................*/
  69. /*${AOs::Table_ctor} .......................................................*/
  70. void Table_ctor(void) {
  71. uint8_t n;
  72. Table *me = &l_table;
  73. QMActive_ctor(&me->super, Q_STATE_CAST(&Table_initial));
  74. for (n = 0U; n < N_PHILO; ++n) {
  75. me->fork[n] = FREE;
  76. me->isHungry[n] = 0U;
  77. }
  78. }
  79. /*${AOs::Table} ............................................................*/
  80. /*${AOs::Table::SM} ........................................................*/
  81. static QState Table_initial(Table * const me, QEvt const * const e) {
  82. static struct {
  83. QMState const *target;
  84. QActionHandler act[2];
  85. } const tatbl_ = { /* transition-action table */
  86. &Table_serving_s, /* target state */
  87. {
  88. Q_ACTION_CAST(&Table_serving_e), /* entry */
  89. Q_ACTION_CAST(0) /* zero terminator */
  90. }
  91. };
  92. /* ${AOs::Table::SM::initial} */
  93. uint8_t n;
  94. (void)e; /* suppress the compiler warning about unused parameter */
  95. QS_OBJ_DICTIONARY(&l_table);
  96. QS_FUN_DICTIONARY(&QHsm_top);
  97. QS_FUN_DICTIONARY(&Table_initial);
  98. QS_FUN_DICTIONARY(&Table_active);
  99. QS_FUN_DICTIONARY(&Table_serving);
  100. QS_FUN_DICTIONARY(&Table_paused);
  101. QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */
  102. QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
  103. QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
  104. QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
  105. QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0);
  106. QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
  107. QActive_subscribe(&me->super, DONE_SIG);
  108. QActive_subscribe(&me->super, PAUSE_SIG);
  109. QActive_subscribe(&me->super, SERVE_SIG);
  110. QActive_subscribe(&me->super, TERMINATE_SIG);
  111. for (n = 0U; n < N_PHILO; ++n) {
  112. me->fork[n] = FREE;
  113. me->isHungry[n] = 0U;
  114. BSP_displayPhilStat(n, "thinking");
  115. }
  116. return QM_TRAN_INIT(&tatbl_);
  117. }
  118. /*${AOs::Table::SM::active} ................................................*/
  119. /* ${AOs::Table::SM::active} */
  120. static QState Table_active(Table * const me, QEvt const * const e) {
  121. QState status_;
  122. switch (e->sig) {
  123. /* ${AOs::Table::SM::active::TERMINATE} */
  124. case TERMINATE_SIG: {
  125. BSP_terminate(0);
  126. status_ = QM_HANDLED();
  127. break;
  128. }
  129. /* ${AOs::Table::SM::active::EAT} */
  130. case EAT_SIG: {
  131. Q_ERROR();
  132. status_ = QM_HANDLED();
  133. break;
  134. }
  135. default: {
  136. status_ = QM_SUPER();
  137. break;
  138. }
  139. }
  140. (void)me; /* avoid compiler warning in case 'me' is not used */
  141. return status_;
  142. }
  143. /*${AOs::Table::SM::active::serving} .......................................*/
  144. /* ${AOs::Table::SM::active::serving} */
  145. static QState Table_serving_e(Table * const me) {
  146. uint8_t n;
  147. for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */
  148. if ((me->isHungry[n] != 0U)
  149. && (me->fork[LEFT(n)] == FREE)
  150. && (me->fork[n] == FREE))
  151. {
  152. TableEvt *te;
  153. me->fork[LEFT(n)] = USED;
  154. me->fork[n] = USED;
  155. te = Q_NEW(TableEvt, EAT_SIG);
  156. te->philoNum = n;
  157. QF_PUBLISH(&te->super, me);
  158. me->isHungry[n] = 0U;
  159. BSP_displayPhilStat(n, "eating ");
  160. }
  161. }
  162. return QM_ENTRY(&Table_serving_s);
  163. }
  164. /* ${AOs::Table::SM::active::serving} */
  165. static QState Table_serving(Table * const me, QEvt const * const e) {
  166. QState status_;
  167. switch (e->sig) {
  168. /* ${AOs::Table::SM::active::serving::HUNGRY} */
  169. case HUNGRY_SIG: {
  170. uint8_t n, m;
  171. n = Q_EVT_CAST(TableEvt)->philoNum;
  172. /* phil ID must be in range and he must be not hungry */
  173. Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
  174. BSP_displayPhilStat(n, "hungry ");
  175. m = LEFT(n);
  176. /* ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */
  177. if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) {
  178. TableEvt *pe;
  179. me->fork[m] = USED;
  180. me->fork[n] = USED;
  181. pe = Q_NEW(TableEvt, EAT_SIG);
  182. pe->philoNum = n;
  183. QF_PUBLISH(&pe->super, me);
  184. BSP_displayPhilStat(n, "eating ");
  185. status_ = QM_HANDLED();
  186. }
  187. /* ${AOs::Table::SM::active::serving::HUNGRY::[else]} */
  188. else {
  189. me->isHungry[n] = 1U;
  190. status_ = QM_HANDLED();
  191. }
  192. break;
  193. }
  194. /* ${AOs::Table::SM::active::serving::DONE} */
  195. case DONE_SIG: {
  196. uint8_t n, m;
  197. TableEvt *pe;
  198. n = Q_EVT_CAST(TableEvt)->philoNum;
  199. /* phil ID must be in range and he must be not hungry */
  200. Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
  201. BSP_displayPhilStat(n, "thinking");
  202. m = LEFT(n);
  203. /* both forks of Phil[n] must be used */
  204. Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
  205. me->fork[m] = FREE;
  206. me->fork[n] = FREE;
  207. m = RIGHT(n); /* check the right neighbor */
  208. if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) {
  209. me->fork[n] = USED;
  210. me->fork[m] = USED;
  211. me->isHungry[m] = 0U;
  212. pe = Q_NEW(TableEvt, EAT_SIG);
  213. pe->philoNum = m;
  214. QF_PUBLISH(&pe->super, me);
  215. BSP_displayPhilStat(m, "eating ");
  216. }
  217. m = LEFT(n); /* check the left neighbor */
  218. n = LEFT(m); /* left fork of the left neighbor */
  219. if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) {
  220. me->fork[m] = USED;
  221. me->fork[n] = USED;
  222. me->isHungry[m] = 0U;
  223. pe = Q_NEW(TableEvt, EAT_SIG);
  224. pe->philoNum = m;
  225. QF_PUBLISH(&pe->super, me);
  226. BSP_displayPhilStat(m, "eating ");
  227. }
  228. status_ = QM_HANDLED();
  229. break;
  230. }
  231. /* ${AOs::Table::SM::active::serving::EAT} */
  232. case EAT_SIG: {
  233. Q_ERROR();
  234. status_ = QM_HANDLED();
  235. break;
  236. }
  237. /* ${AOs::Table::SM::active::serving::PAUSE} */
  238. case PAUSE_SIG: {
  239. static struct {
  240. QMState const *target;
  241. QActionHandler act[2];
  242. } const tatbl_ = { /* transition-action table */
  243. &Table_paused_s, /* target state */
  244. {
  245. Q_ACTION_CAST(&Table_paused_e), /* entry */
  246. Q_ACTION_CAST(0) /* zero terminator */
  247. }
  248. };
  249. status_ = QM_TRAN(&tatbl_);
  250. break;
  251. }
  252. default: {
  253. status_ = QM_SUPER();
  254. break;
  255. }
  256. }
  257. return status_;
  258. }
  259. /*${AOs::Table::SM::active::paused} ........................................*/
  260. /* ${AOs::Table::SM::active::paused} */
  261. static QState Table_paused_e(Table * const me) {
  262. BSP_displayPaused(1U);
  263. (void)me; /* avoid compiler warning in case 'me' is not used */
  264. return QM_ENTRY(&Table_paused_s);
  265. }
  266. /* ${AOs::Table::SM::active::paused} */
  267. static QState Table_paused_x(Table * const me) {
  268. BSP_displayPaused(0U);
  269. (void)me; /* avoid compiler warning in case 'me' is not used */
  270. return QM_EXIT(&Table_paused_s);
  271. }
  272. /* ${AOs::Table::SM::active::paused} */
  273. static QState Table_paused(Table * const me, QEvt const * const e) {
  274. QState status_;
  275. switch (e->sig) {
  276. /* ${AOs::Table::SM::active::paused::SERVE} */
  277. case SERVE_SIG: {
  278. static struct {
  279. QMState const *target;
  280. QActionHandler act[3];
  281. } const tatbl_ = { /* transition-action table */
  282. &Table_serving_s, /* target state */
  283. {
  284. Q_ACTION_CAST(&Table_paused_x), /* exit */
  285. Q_ACTION_CAST(&Table_serving_e), /* entry */
  286. Q_ACTION_CAST(0) /* zero terminator */
  287. }
  288. };
  289. status_ = QM_TRAN(&tatbl_);
  290. break;
  291. }
  292. /* ${AOs::Table::SM::active::paused::HUNGRY} */
  293. case HUNGRY_SIG: {
  294. uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
  295. /* philo ID must be in range and he must be not hungry */
  296. Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
  297. me->isHungry[n] = 1U;
  298. BSP_displayPhilStat(n, "hungry ");
  299. status_ = QM_HANDLED();
  300. break;
  301. }
  302. /* ${AOs::Table::SM::active::paused::DONE} */
  303. case DONE_SIG: {
  304. uint8_t n, m;
  305. n = Q_EVT_CAST(TableEvt)->philoNum;
  306. /* phil ID must be in range and he must be not hungry */
  307. Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
  308. BSP_displayPhilStat(n, "thinking");
  309. m = LEFT(n);
  310. /* both forks of Phil[n] must be used */
  311. Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
  312. me->fork[m] = FREE;
  313. me->fork[n] = FREE;
  314. status_ = QM_HANDLED();
  315. break;
  316. }
  317. default: {
  318. status_ = QM_SUPER();
  319. break;
  320. }
  321. }
  322. return status_;
  323. }