table.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2. /*
  3. * Model: dpp-comp.qm
  4. * File: ${.::table.c}
  5. *
  6. * This code has been generated by QM 5.2.4 <www.state-machine.com/qm>.
  7. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  8. *
  9. * SPDX-License-Identifier: GPL-3.0-or-later
  10. *
  11. * This generated code is open source software: you can redistribute it under
  12. * the terms of the GNU General Public License as published by the Free
  13. * Software Foundation.
  14. *
  15. * This code is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  18. * more details.
  19. *
  20. * NOTE:
  21. * Alternatively, this generated code may be distributed under the terms
  22. * of Quantum Leaps commercial licenses, which expressly supersede the GNU
  23. * General Public License and are specifically designed for licensees
  24. * interested in retaining the proprietary status of their code.
  25. *
  26. * Contact information:
  27. * <www.state-machine.com/licensing>
  28. * <info@state-machine.com>
  29. */
  30. /*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  31. #include "qpc.h"
  32. #include "dpp.h"
  33. #include "bsp.h"
  34. Q_DEFINE_THIS_FILE
  35. /*$declare${Cont::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  36. /*${Cont::Table} ...........................................................*/
  37. typedef struct Table {
  38. /* protected: */
  39. QActive super;
  40. /* public: */
  41. /* private: */
  42. uint8_t fork[N_PHILO];
  43. uint8_t isHungry[N_PHILO];
  44. } Table;
  45. extern Table Table_inst;
  46. /* protected: */
  47. static QState Table_initial(Table * const me, void const * const par);
  48. static QState Table_active(Table * const me, QEvt const * const e);
  49. static QState Table_serving(Table * const me, QEvt const * const e);
  50. static QState Table_paused(Table * const me, QEvt const * const e);
  51. /*$enddecl${Cont::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  52. #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO))
  53. #define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO))
  54. #define FREE ((uint8_t)0)
  55. #define USED ((uint8_t)1)
  56. /* definition of the whole "Cont" package */
  57. /*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  58. /* Check for the minimum required QP version */
  59. #if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U))
  60. #error qpc version 7.0.0 or higher required
  61. #endif
  62. /*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  63. /*$define${Cont} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  64. /*${Cont::Table} ...........................................................*/
  65. Table Table_inst;
  66. /*${Cont::Table::SM} .......................................................*/
  67. static QState Table_initial(Table * const me, void const * const par) {
  68. /*${Cont::Table::SM::initial} */
  69. (void)par; /* unused parameter */
  70. QS_OBJ_DICTIONARY(&Table_inst);
  71. QActive_subscribe(&me->super, PAUSE_SIG);
  72. QActive_subscribe(&me->super, SERVE_SIG);
  73. QActive_subscribe(&me->super, TEST_SIG);
  74. for (uint8_t n = 0U; n < N_PHILO; ++n) {
  75. me->fork[n] = FREE;
  76. me->isHungry[n] = 0U;
  77. QHSM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n);
  78. BSP_displayPhilStat(n, "thinking");
  79. }
  80. QS_FUN_DICTIONARY(&Table_active);
  81. QS_FUN_DICTIONARY(&Table_serving);
  82. QS_FUN_DICTIONARY(&Table_paused);
  83. return Q_TRAN(&Table_serving);
  84. }
  85. /*${Cont::Table::SM::active} ...............................................*/
  86. static QState Table_active(Table * const me, QEvt const * const e) {
  87. QState status_;
  88. switch (e->sig) {
  89. /*${Cont::Table::SM::active::TIMEOUT} */
  90. case TIMEOUT_SIG: {
  91. uint16_t n = Q_EVT_CAST(CompTimeEvt)->compNum;
  92. QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n);
  93. status_ = Q_HANDLED();
  94. break;
  95. }
  96. /*${Cont::Table::SM::active::EAT} */
  97. case EAT_SIG: {
  98. Q_ERROR();
  99. status_ = Q_HANDLED();
  100. break;
  101. }
  102. /*${Cont::Table::SM::active::TEST} */
  103. case TEST_SIG: {
  104. status_ = Q_HANDLED();
  105. break;
  106. }
  107. default: {
  108. status_ = Q_SUPER(&QHsm_top);
  109. break;
  110. }
  111. }
  112. return status_;
  113. }
  114. /*${Cont::Table::SM::active::serving} ......................................*/
  115. static QState Table_serving(Table * const me, QEvt const * const e) {
  116. QState status_;
  117. switch (e->sig) {
  118. /*${Cont::Table::SM::active::serving} */
  119. case Q_ENTRY_SIG: {
  120. for (uint8_t n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */
  121. if ((me->isHungry[n] != 0U)
  122. && (me->fork[LEFT(n)] == FREE)
  123. && (me->fork[n] == FREE))
  124. {
  125. me->fork[LEFT(n)] = USED;
  126. me->fork[n] = USED;
  127. /* synchronoulsy dispatch EAT event to the Philo component */
  128. TableEvt evt;
  129. evt.super.sig = EAT_SIG;
  130. evt.philoNum = n;
  131. QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n);
  132. me->isHungry[n] = 0U;
  133. BSP_displayPhilStat(n, "eating ");
  134. }
  135. }
  136. status_ = Q_HANDLED();
  137. break;
  138. }
  139. /*${Cont::Table::SM::active::serving::HUNGRY} */
  140. case HUNGRY_SIG: {
  141. /* find the index of the Philo from the event */
  142. uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
  143. /* philo ID must be in range and he must be not hungry */
  144. Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
  145. BSP_displayPhilStat(n, "hungry ");
  146. uint8_t m = LEFT(n);
  147. /*${Cont::Table::SM::active::serving::HUNGRY::[bothfree]} */
  148. if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) {
  149. me->fork[m] = USED;
  150. me->fork[n] = USED;
  151. /* synchronoulsy dispatch EAT event to the Philo component */
  152. TableEvt evt;
  153. evt.super.sig = EAT_SIG;
  154. evt.philoNum = n;
  155. QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n);
  156. BSP_displayPhilStat(n, "eating ");
  157. status_ = Q_HANDLED();
  158. }
  159. /*${Cont::Table::SM::active::serving::HUNGRY::[else]} */
  160. else {
  161. me->isHungry[n] = 1U;
  162. status_ = Q_HANDLED();
  163. }
  164. break;
  165. }
  166. /*${Cont::Table::SM::active::serving::DONE} */
  167. case DONE_SIG: {
  168. /* find the index of the Philo from the event */
  169. uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
  170. /* philo ID must be in range and he must be not hungry */
  171. Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
  172. BSP_displayPhilStat(n, "thinking");
  173. uint8_t m = LEFT(n);
  174. /* both forks of Phil[n] must be used */
  175. Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
  176. me->fork[m] = FREE;
  177. me->fork[n] = FREE;
  178. m = RIGHT(n); /* check the right neighbor */
  179. TableEvt evt;
  180. if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) {
  181. me->fork[n] = USED;
  182. me->fork[m] = USED;
  183. me->isHungry[m] = 0U;
  184. /* synchronoulsy dispatch EAT event to the Philo component */
  185. evt.super.sig = EAT_SIG;
  186. evt.philoNum = m;
  187. QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m);
  188. BSP_displayPhilStat(m, "eating ");
  189. }
  190. m = LEFT(n); /* check the left neighbor */
  191. n = LEFT(m); /* left fork of the left neighbor */
  192. if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) {
  193. me->fork[m] = USED;
  194. me->fork[n] = USED;
  195. me->isHungry[m] = 0U;
  196. /* synchronoulsy dispatch EAT event to the Philo component */
  197. evt.super.sig = EAT_SIG;
  198. evt.philoNum = m;
  199. QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m);
  200. BSP_displayPhilStat(m, "eating ");
  201. }
  202. status_ = Q_HANDLED();
  203. break;
  204. }
  205. /*${Cont::Table::SM::active::serving::EAT} */
  206. case EAT_SIG: {
  207. Q_ERROR();
  208. status_ = Q_HANDLED();
  209. break;
  210. }
  211. /*${Cont::Table::SM::active::serving::PAUSE} */
  212. case PAUSE_SIG: {
  213. status_ = Q_TRAN(&Table_paused);
  214. break;
  215. }
  216. default: {
  217. status_ = Q_SUPER(&Table_active);
  218. break;
  219. }
  220. }
  221. return status_;
  222. }
  223. /*${Cont::Table::SM::active::paused} .......................................*/
  224. static QState Table_paused(Table * const me, QEvt const * const e) {
  225. QState status_;
  226. switch (e->sig) {
  227. /*${Cont::Table::SM::active::paused} */
  228. case Q_ENTRY_SIG: {
  229. BSP_displayPaused(1U);
  230. status_ = Q_HANDLED();
  231. break;
  232. }
  233. /*${Cont::Table::SM::active::paused} */
  234. case Q_EXIT_SIG: {
  235. BSP_displayPaused(0U);
  236. status_ = Q_HANDLED();
  237. break;
  238. }
  239. /*${Cont::Table::SM::active::paused::SERVE} */
  240. case SERVE_SIG: {
  241. status_ = Q_TRAN(&Table_serving);
  242. break;
  243. }
  244. /*${Cont::Table::SM::active::paused::HUNGRY} */
  245. case HUNGRY_SIG: {
  246. /* find the index of the Philo from the event */
  247. uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
  248. /* philo ID must be in range and he must be not hungry */
  249. Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
  250. me->isHungry[n] = 1U;
  251. BSP_displayPhilStat(n, "hungry ");
  252. status_ = Q_HANDLED();
  253. break;
  254. }
  255. /*${Cont::Table::SM::active::paused::DONE} */
  256. case DONE_SIG: {
  257. /* find the index of the Philo from the event */
  258. uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
  259. /* philo ID must be in range and he must be not hungry */
  260. Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
  261. BSP_displayPhilStat(n, "thinking");
  262. uint8_t m = LEFT(n);
  263. /* both forks of Phil[n] must be used */
  264. Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
  265. me->fork[m] = FREE;
  266. me->fork[n] = FREE;
  267. status_ = Q_HANDLED();
  268. break;
  269. }
  270. default: {
  271. status_ = Q_SUPER(&Table_active);
  272. break;
  273. }
  274. }
  275. return status_;
  276. }
  277. /*${Cont::AO_Table} ........................................................*/
  278. QActive * const AO_Table = &Table_inst.super; /* opaque pointer */
  279. /*${Cont::Table_ctor} ......................................................*/
  280. void Table_ctor(void) {
  281. Table *me = &Table_inst;
  282. QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial));
  283. for (uint8_t n = 0U; n < N_PHILO; ++n) {
  284. me->fork[n] = FREE;
  285. me->isHungry[n] = 0U;
  286. Philo_ctor(n); /* create the Philo component */
  287. }
  288. }
  289. /*$enddef${Cont} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/