Documente Academic
Documente Profesional
Documente Cultură
Table o !ontents
1 "ntro#uction$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 1 2 Re%uirements$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 1 & Design an# "mplementation$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 2 3. !tep " !equence #iagrams...................................................................................................................... $ 3.$ !tep $" !ignals, %&ents, an' (cti&e )*+ects.............................................................................................. 3 3.3 !tep 3" !tate ,achines.............................................................................................................................. 3.. !tep ." /nitiali0ing an' !tarting the (pplication .......................................................................................... $ 3.- !tep -" 1racefully 2erminating the (pplication .......................................................................................... . ' Re erences$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 1( ( !ontact "n ormation$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 1)
"ntro#uction
2his (pplication 4ote 'escri*es the classic #ining Philosophers Pro*lem 5#PP6 as an example application for the QP state machine framework. #PP was pose' an' sol&e' *y %'sger #i+kstra *ack in 78 9#i+kstra 8 :. 2he #PP application is relati&ely simple an' can *e teste' only with a couple of L%#s on your target *oar'. !till, #PP contains six concurrent acti&e o*+ects that exchange e&ents &ia pu*lishsu*scri*e an' 'irect e&ent posting mechanisms. 2he application uses fi&e time e&ents 5timers6, as well as 'ynamic an' static e&ents. 2his (pplication 4ote 'escri*es step-*y-step how to 'esign an' implemente' of #PP with QP. N*TE+ 2his (pplication 4ote assumes the QP;C framework an' uses example co'e in C to explain implementation 'etails. <owe&er, the 'iscussion applies equally to QP;C== &ersion. 2he 'ifferences of the C== implementation with respect to the C implementation will *e 'iscusse' only when such 'ifferences *ecome non-tri&ial an' important.
Re%uirements
>irst, your always nee' to un'erstan' what your application is suppose' to accomplish. /n the case of a simple application, the requirements are con&eye' through the pro*lem specification, which for the #PP is as follows. >i&e philosophers are gathere' aroun' a ta*le with a *ig plate of spaghetti in the mi''le 5see >igure 6. ?etween each philosopher is a fork. 2he spaghetti is so slippery that a philosopher nee's two forks to eat it. 2he life of a philosopher consists of alternate perio's of thinking an' eating. @hen a philosopher wants to eat, he tries to acquire forks. /f successful in acquiring two forks, he eats for a while, then puts 'own the forks an' continues to think. 2he key issue is that a finite set of tasks 5philosophers6 is sharing a finite set of resources 5forks6, an' each resource can *e use' *y only one task at a time. 5(n alternati&e oriental &ersion replaces spaghetti with rice an' forks with chopsticks, which perhaps explains *etter why philosophers nee' two chopsticks to eat.6 (s an a''itional feature, the #ining Philosophers can *e pause' for an ar*itrary perio' of time. #uring this pause' perio', the Philosophers 'onAt get permissions to eat. (fter the pause perio', the Philosophers shoul' resume normal operation. ,igure 1 The Dining Philosophers Problem$
1 of 1)
&
&$1
2/,%)E2 5 H6 eating
5G6 thin1ing
#)4%5m6 %(25n6
576
%ach Philosopher acti&e o*+ect starts in the CthinkingD state. Epon the entry to this state, the Philosopher arms a one-shot time e&ent to terminate the thinking. 2he Q> framework posts the time e&ent 5timer6 to Philosopher9m:. Epon recei&ing the 2/,%)E2 e&ent, Philosopher9m: transitions to ChungryD state an' posts the <E413B5m6 e&ent to the 2a*le acti&e o*+ect. 2he parameter of the e&ent tells the 2a*le which Philosopher is getting hungry. 2he 2a*le acti&e o*+ect fin's out that the forks for Philosopher9m: are a&aila*le an' grants it the permission to eat *y pu*lishing the %(25m6 e&ent. 2he permission to eat triggers the transition to CeatingD in Philosopher9m:. (lso, upon the entry to CeatingD, the Philosopher arms its one-shot time e&ent to terminate the eating. 2 of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com 5F6 586 5G6 576 5 H6 2he Philosopher9n: recei&es the 2/,%)E2 e&ent, an' *eha&es exactly as Philosopher9m:, that is, transitions to ChungryD an' posts <E413B5n6 e&ent to the 2a*le acti&e o*+ect. 2his time, the 2a*le acti&e o*+ect fin's out that the forks for Philosopher9n: are not a&aila*le, an' so it 'oes not grant the permission to eat. Philosopher9n: remains in the ChungryD state. 2he Q> framework 'eli&ers the timeout for terminating the eating arri&es to Philosopher9m:. Epon the exit from CeatingD, Philosopher9m: pu*lishes e&ent #)4%5m6, to inform the application that it is no longer eating. 2he 2a*le acti&e o*+ect accounts for free forks an' checks whether any 'irect neigh*ors of Philosopher9m: are hungry. 2a*le posts e&ent %(25n6 to Philosopher9n:. 2he permission to eat triggers the transition to CeatingD in Philosopher9n:.
&$2
@A
(6!
t4pedef st5"ct *a3leEvt*a& ' QEvent s"pe5A "int8_t philo7"mA @ *a3leEvtA en"m ' 7_$=+B6 - ? @A
12 de5ives f5om QEvent 21 12 $hilosophe5 n"m3e5 21 12 n"m3e5 of $hilosophe5s 21 12 cto5 that instantiates all $hilosophe5s 21
(D! exte5n Q)ctive 2 const )6_$hiloE7_$=+B6FA 12 Gopaq"eG pointe5s to $hilo )6s 21 Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'. & of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com ( 0! exte5n Q)ctive 2 const )6_*a3leA #endif 5 6 5$6 536 5.6 12 Gopaq"eG pointe5 to *a3le )6 21 12 dpp_h 21
5-6 5F6
>or smaller applications, such as the #PP, all signals can *e 'efine' in one enumeration 5rather than in separate enumerations or, worse, as preprocessor #define macros6. (n enumeration automatically guarantees the uniqueness of signals. 4ote that the user signals must start with the offset Q_.%E/_%+, to a&oi' o&erlapping the reser&e' Q%P signals. 2he glo*ally pu*lishe' signals are groupe' at top of the enumeration. 2he 9);_$.8_%+, enumeration automatically keeps track of the maximum pu*lishe' signals in the application. 2he Philosophers post the =.7,/> e&ent 'irectly to the 2a*le o*+ect rather than pu*licly pu*lish the e&ent 5perhaps a Philosopher is Cem*arrasse'D to *e hungry, so it 'oes not want other Philosophers to know a*out it6. 2his 'emonstrates 'irect e&ent posting an' pu*lish-su*scri*e mechanism coexisting in a single application. 2he 9);_%+, enumeration automatically keeps track of the total num*er of signals use' in the application. %&ery e&ent with parameters, such as the *a3leEvt 'eri&es from the QEvent *ase structure.
2he listing shows how to keep the co'e an' 'ata structure of e&ery acti&e o*+ect strictly encapsulate' within its own C-file. >or example, all co'e an' 'ata for the acti&e o*+ect *a3le are encapsulate' in the file ta3leHc, with the external interface consisting of the function *a3le_cto5(! an' the pointer )6_*a3le. 58-G6 2hese functions perform an early initiali0ation of the acti&e o*+ects in the system. 2hey play the role of static CconstructorsD, which in C you nee' to call explicitly, typically at the *eginning of main(!. 57- H6 2hese glo*al pointers represent acti&e o*+ects in the application an' are use' for posting e&ents 'irectly to acti&e o*+ects. ?ecause the pointers can *e initiali0e' at compile time, they are 'eclare' const, sot that they can *e place' in 3),. 2he acti&e o*+ect pointers are CopaqueD, *ecause they cannot access the whole acti&e o*+ect, *ut only the part inherite' from the Q)ctive structure.
' of 1)
&$&
(a)
(b)
( of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com >igure 35*6 shows the state machine associate' with the 2a*le acti&e o*+ect. 2his state machine is tri&ial *ecause 2a*le keeps track of the forks an' hungry philosophers *y means of exten'e' state &aria*les, rather than *y its state machine. 2he state 'iagram in >igure 35*6 o*&iously 'oes not con&ey how the 2a*le acti&e o*+ect *eha&es, as the specification of actions is missing. 2he actions are omitte' from the 'iagram, howe&er, *ecause inclu'ing them require' cutting an' pasting most of the 2a*le co'e into the 'iagram, which woul' make the 'iagram too cluttere'. /n this case, the 'iagram simply 'oes not a'' much &alue o&er the co'e. ,igure ' Numbering o philosophers an# or1s (see the macros 5E,T() an# R"8:T() in 5isting 2)$
L%>25L%>25n66
3/1<25n6
L%>25n6 L%>25n6
n n
3/1<25n6
(s mentione' *efore, each acti&e o*+ect is strictly encapsulate' insi'e a 'e'icate' source file 5 HI file6. Listing $ shows the 'eclaration 5acti&e o*+ect structure6 an' complete 'efinition 5state han'ler functions6 of the 2a*le acti&e o*+ect in the file ta3leHc. 2he explanation section imme'iately following this listing 'escri*es the techniques of encapsulating acti&e o*+ects an' using Q> ser&ices. 2he recipes for co'ing state machine elements are not repeate' here, *ecause they are alrea'y 'escri*e' in the CQP 2utorialsD a&aila*le online. 5isting 2 Table active ob4ect ( ile table$c generate# b2 the .6 mo#eling tool)$ #incl"de Gqp_po5tHhG #incl"de GdppHhG #incl"de G3spHhG Q_#EJ+7E_*=+%_J+BE 12 )ctive o3Kect class -----------------------------------------------------21 12 L(1(1 ! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 ( ! t4pedef st5"ct *a3le*a& ' 12 p5otectedM 21 ((! Q)ctive s"pe5A (:! (<! 12 p5ivateM 21 "int8_t fo5NE7_$=+B6FA "int8_t is="n&54E7_$=+B6FA @ *a3leA 12 p5otectedM static Q%tate static Q%tate static Q%tate static Q%tate 21 *a3le_initial(*a3le 2 const me0 QEvt const 2 const e!A *a3le_active(*a3le 2 const me0 QEvt const 2 const e!A *a3le_se5vin&(*a3le 2 const me0 QEvt const 2 const e!A *a3le_pa"sed(*a3le 2 const me0 QEvt const 2 const e!A ) of 1)
(?! #define /+,=*(n_! (6! #define BEJ*(n_! #define J/EE #define .%E#
12 Bocal o3Kects -----------------------------------------------------------21 (C! static *a3le l_ta3leA 12 the sin&le instance of the *a3le active o3Kect 21 12 ,lo3al-scope o3Kects ----------------------------------------------------21 (8! Q)ctive 2 const )6_*a3le - Ql_ta3leHs"pe5A 12 Gopaq"eG )6 pointe5 21 12HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 12 L(1(1?! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 (D! void *a3le_cto5(void! ' "int8_t nA *a3le 2me - Ql_ta3leA ( 0! ( ! Q)ctive_cto5(Qme->s"pe50 Q_%*)*E_I)%*(Q*a3le_initial!!A fo5 (n - 0.A n < 7_$=+B6A OOn! ' me->fo5NEnF - J/EEA me->is="n&54EnF - 0.A @
@ 12 L(1(1 ! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 12 L(1(1 1(! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 12 L(1(1 1(10! 21 static Q%tate *a3le_initial(*a3le 2 const me0 QEvt const 2 const e! ' "int8_t nA (void!eA 12 s"pp5ess the compile5 wa5nin& a3o"t "n"sed pa5amete5 21 ( (! Q%_68R_#+I*+67)/>(Ql_ta3le!A Q%_J.7_#+I*+67)/>(QQ=sm_top!A Q%_J.7_#+I*+67)/>(Q*a3le_initial!A Q%_J.7_#+I*+67)/>(Q*a3le_se5vin&!A Q%_%+,_#+I*+67)/>(#67E_%+,0 Q%_%+,_#+I*+67)/>(E)*_%+,0 Q%_%+,_#+I*+67)/>($).%E_%+,0 Q%_%+,_#+I*+67)/>(*E/9+7)*E_%+,0 Q%_%+,_#+I*+67)/>(=.7,/>_%+,0 ( :! ( <! ( ?! (void (void (void (void 2!0!A 12 &lo3al si&nals 21 2!0!A 2!0!A 2!0!A
Q)ctive_s"3sc5i3e(Qme->s"pe50 #67E_%+,!A Q)ctive_s"3sc5i3e(Qme->s"pe50 $).%E_%+,!A Q)ctive_s"3sc5i3e(Qme->s"pe50 *E/9+7)*E_%+,!A fo5 (n - 0.A n < 7_$=+B6A OOn! ' me->fo5NEnF - J/EEA me->is="n&54EnF - 0.A 8%$_displa4$hil%tat(n0 GthinNin&G!A @ 5et"5n Q_*/)7(Q*a3le_se5vin&!A
( 6!
@ 12 L(1(1 1(1 ! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'. ; of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com static Q%tate *a3le_active(*a3le 2 const me0 QEvt const 2 const e! ' Q%tate stat"sA switch (e->si&! ' 12 L(1(1 1(1 10! 21 case *E/9+7)*E_%+,M ' ( C! 8%$_te5minate(0!A stat"s - Q_=)7#BE#(!A 35eaNA @ 12 L(1(1 1(1 1 ! 21 case E)*_%+,M ' ( C! Q_E//6/(!A stat"s - Q_=)7#BE#(!A 35eaNA @ defa"ltM ' stat"s - Q_%.$E/(QQ=sm_top!A 35eaNA @ @ 5et"5n stat"sA @ 12 L(1(1 1(1 1(! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 static Q%tate *a3le_se5vin&(*a3le 2 const me0 QEvt const 2 const e! ' Q%tate stat"sA switch (e->si&! ' 12 L(1(1 1(1 1(! 21 case Q_E7*/>_%+,M ' "int8_t nA fo5 (n - 0.A n < 7_$=+B6A OOn! ' 12 &ive pe5missions to eatHHH 21 if ((me->is="n&54EnF S- 0.! QQ (me->fo5NEBEJ*(n!F -- J/EE! QQ (me->fo5NEnF -- J/EE!! ' *a3leEvt 2teA me->fo5NEBEJ*(n!F - .%E#A me->fo5NEnF - .%E#A te - Q_7ET(*a3leEvt0 E)*_%+,!A te->philo7"m - nA QJ_$.8B+%=(Qte->s"pe50 me!A me->is="n&54EnF - 0.A 8%$_displa4$hil%tat(n0 Geatin&
G!A
n - Q_EU*_I)%*(*a3leEvt!->philo7"mA 12 phil +# m"st 3e in 5an&e and he m"st 3e not h"n&54 21 Q_)%%E/*((n < 7_$=+B6! QQ (me->is="n&54EnF -- 0.!!A 8%$_displa4$hil%tat(n0 Gh"n&54 Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'. G!A < of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com m - BEJ*(n!A 12 L(1(1 1(1 1(1010! 21 if ((me->fo5NEmF -- J/EE! QQ (me->fo5NEnF -- J/EE!! ' *a3leEvt 2peA me->fo5NEmF - .%E#A me->fo5NEnF - .%E#A pe - Q_7ET(*a3leEvt0 E)*_%+,!A pe->philo7"m - nA QJ_$.8B+%=(Qpe->s"pe50 me!A 8%$_displa4$hil%tat(n0 Geatin& G!A stat"s - Q_=)7#BE#(!A @ 12 L(1(1 1(1 1(101 ! 21 else ' me->is="n&54EnF - .A stat"s - Q_=)7#BE#(!A @ 35eaNA @ 12 L(1(1 1(1 1(1 ! 21 case #67E_%+,M ' "int8_t n0 mA *a3leEvt 2peA n - Q_EU*_I)%*(*a3leEvt!->philo7"mA 12 phil +# m"st 3e in 5an&e and he m"st 3e not h"n&54 21 Q_)%%E/*((n < 7_$=+B6! QQ (me->is="n&54EnF -- 0.!!A 8%$_displa4$hil%tat(n0 GthinNin&G!A m - BEJ*(n!A 12 3oth fo5Ns of $hilEnF m"st 3e "sed 21 Q_)%%E/*((me->fo5NEnF -- .%E#! QQ (me->fo5NEmF -- .%E#!!A me->fo5NEmF - J/EEA me->fo5NEnF - J/EEA m - /+,=*(n!A 12 checN the 5i&ht nei&h3o5 21 if ((me->is="n&54EmF S- 0.! QQ (me->fo5NEmF -- J/EE!! ' me->fo5NEnF - .%E#A me->fo5NEmF - .%E#A me->is="n&54EmF - 0.A pe - Q_7ET(*a3leEvt0 E)*_%+,!A pe->philo7"m - mA QJ_$.8B+%=(Qpe->s"pe50 me!A 8%$_displa4$hil%tat(m0 Geatin& G!A @ m - BEJ*(n!A 12 checN the left nei&h3o5 21 n - BEJ*(m!A 12 left fo5N of the left nei&h3o5 21 if ((me->is="n&54EmF S- 0.! QQ (me->fo5NEnF -- J/EE!! ' me->fo5NEmF - .%E#A me->fo5NEnF - .%E#A me->is="n&54EmF - 0.A pe - Q_7ET(*a3leEvt0 E)*_%+,!A pe->philo7"m - mA QJ_$.8B+%=(Qpe->s"pe50 me!A 8%$_displa4$hil%tat(m0 Geatin& G!A @ Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'. = of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com stat"s - Q_=)7#BE#(!A 35eaNA @ 12 L(1(1 1(1 1(1(! 21 case E)*_%+,M ' Q_E//6/(!A stat"s - Q_=)7#BE#(!A 35eaNA @ 12 L(1(1 1(1 1(1:! 21 case $).%E_%+,M ' stat"s - Q_*/)7(Q*a3le_pa"sed!A 35eaNA @ defa"ltM ' stat"s - Q_%.$E/(Q*a3le_active!A 35eaNA @ @ 5et"5n stat"sA @ 12 L(1(1 1(1 1:! HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 static Q%tate *a3le_pa"sed(*a3le 2 const me0 QEvt const 2 const e! ' Q%tate stat"sA switch (e->si&! ' H H H defa"ltM ' stat"s - Q_%.$E/(Q*a3le_active!A 35eaNA @ @ 5et"5n stat"sA @ 5 6 5$6 536 5.6 5--F6 586 5G6 2o achie&e true encapsulation, 2he 'eclaration of the acti&e o*+ect structure is place' in the source file 5.C file6. %ach acti&e o*+ect in the application 'eri&es from the Q)ctive *ase structure. 2he 2a*le acti&e o*+ect keeps track of the forks in the array fo5NEF. 2he forks are num*ere' as shown in >igure .. !imilarly, the 2a*le acti&e o*+ect nee's to remem*er which philosophers are hungry, in case the forks arenOt imme'iately a&aila*le. 2a*le keeps track of hungry philosophers in the array is="n&54EF. Philosophers are num*ere' as shown in >igure .. 2he helper macros BEJ*(! an' /+,=*(! access the left an' right philosopher or fork, respecti&ely, as shown in >igure .. 2he 2a*le acti&e o*+ect is allocate' statically, which makes it inaccessi*le outsi'e of the .C file. %xternally, the 2a*le acti&e o*+ect is known only through the CopaqueD pointer )6_*a3le. 2he pointer is 'eclare' PconstO 5with the const after the PQO6, which means that the pointer itself cannot change. 2his ensures that the acti&e o*+ect pointer cannot change acci'entally an' also allows the compiler to allocate the acti&e o*+ect pointer in 3),. 2he function *a3le_cto5(! performs the instantiation of the 2a*le acti&e o*+ect. /t plays the role of the static CconstructorD, which in C you nee' to call explicitly, typically at the *eginning of main(!.
576
10 of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com N*TE+ /n C==, static constructors are in&oke' automatically *efore main(!. 2his means that in the C== &ersion of #PP 5foun' in <qp>\qpcpp\examples\80x86\dos\watcom\l\dpp\6, you pro&i'e a regular constructor for the 2a*le class an' 'onOt *other with calling it explicitly. <owe&er, you must make sure that the startup co'e for your particular em*e''e' target inclu'es the a''itional steps require' *y the C== initiali0ation. 5 H6 5 6 5 $6 2he constructor must first instantiate the Q)ctive superclass. 2he constructor can then initiali0e the internal 'ata mem*ers of the acti&e o*+ect. 2he macros staring with Q!J pertain to the Q-!PB software tracing instrumentation an' are acti&e only in the !PB *uil' configuration. 5 3- -6 2he acti&e o*+ect su*scri*es to all interesting to it signals in the top-most initial transition. Please note that 2a*le 'oes not su*scri*e to the <E413B e&ent, *ecause this e&ent is poste' 'irectly. N*TE+ 4ew QP users often forget to su*scri*e to e&ents an' then the application appears C'ea'D when you first run it. 5 F6 5 86 5 G6 2he output to the screen is a ?!P 5*oar' support package6 operation. 2he 'ifferent ?!Ps implement this operation 'ifferently, *ut the co'e of the 2a*le state machine 'oes not nee' to change. Epon recei&ing the *E/9+7)*E e&ent, the 2a*le acti&e o*+ect calls 8%$_te5minate(! to stop Q> an' return to the un'erlying operating system. 2he 2a*le state machine extensi&ely uses assertions to monitor correct execution of the #PP application. >or example, in line 5 76 *oth forks of a philosopher that +ust finishe' eating must *e use'.
2he Philosopher acti&e o*+ects *ring no essentially new techniques, so the listing of the philoHc file is not repro'uce' here. )ne interesting aspect of philosophers is that all fi&e philosopher acti&e o*+ects are instances of the same acti&e o*+ect class. 2he philosopher state machine also uses a few assertions to monitor correct execution of the application accor'ing to the pro*lem specification.
11 of 1)
&$'
12HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH21 int_t main(void! ' "int8_t nA (?! (6! (C! (8! (D! $hilo_cto5(!A *a3le_cto5(!A QJ_init(!A 8%$_init(!A 12 instantiate all $hilosophe5 active o3Kects 21 12 instantiate the *a3le active o3Kect 21 12 initialiVe the f5amewo5N and the "nde5l4in& /* Ne5nel 21 12 initialiVe the 8%$ 21 12 o3Kect dictiona5iesHHH 21
Q%_68R_#+I*+67)/>(l_sml$ool%to!A Q%_68R_#+I*+67)/>(l_ta3leQ"e"e%to!A Q%_68R_#+I*+67)/>(l_philoQ"e"e%toE0F!A Q%_68R_#+I*+67)/>(l_philoQ"e"e%toE F!A Q%_68R_#+I*+67)/>(l_philoQ"e"e%toE(F!A Q%_68R_#+I*+67)/>(l_philoQ"e"e%toE:F!A Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.
12 of 1)
(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com Q%_68R_#+I*+67)/>(l_philoQ"e"e%toE<F!A ( 0! ( ! QJ_ps+nit(l_s"3sc5%to0 Q_#+9(l_s"3sc5%to!!A 12 init p"3lish-s"3sc5i3e 21
12 initialiVe event poolsHHH 21 QJ_pool+nit(l_sml$ool%to0 siVeof(l_sml$ool%to!0 siVeof(l_sml$ool%toE0F!!A fo5 (n - 0.A n < 7_$=+B6A OOn! ' 12 sta5t the active o3KectsHHH 21 Q)ctive_sta5t()6_$hiloEnF0 ("int8_t!(n O .!0 l_philoQ"e"e%toEnF0 Q_#+9(l_philoQ"e"e%toEnF!0 (void 2!00 0.0 (QEvt 2!0!A @ Q)ctive_sta5t()6_*a3le0 ("int8_t!(7_$=+B6 O .!0 l_ta3leQ"e"e%to0 Q_#+9(l_ta3leQ"e"e%to!0 (void 2!00 0.0 (QEvt 2!0!A @ 5et"5n (int_t!QJ_5"n(!A 12 5"n the QJ application 21
( (!
( :!
( <!
5 -$6 536
2he memory *uffers for all e&ent queues are statically allocate'. 2he memory space for su*scri*er lists is also statically allocate'. 2he 9);_$.8_%+, enumeration comes in han'y here. 5.6 2he macro QJ_9$66B_EB(*a3leEvt! pro&i'es correctly aligne' memory *lock of the si0e at least as *ig as the siVeof(*a3leEvt! for all e&ents that are ser&e' *y the CsmallD e&ent pool. 5--F6 2he main(! function starts with calling all static CconstructorsD 5see Listing 58-G66. 2his step is not necessary in C==. 586 Q> is initiali0e' together with the un'erlying )!;32)!. 5G6 2he target *oar' is initiali0e'. 576 2he macros staring with Q!J pertain to the Q-!PB software tracing instrumentation an' are acti&e only in the !PB *uil' configuration. 5 H6 2he pu*lish-su*scri*e mechanism is initiali0e'. Bou 'onOt nee' to call Q>Jps/nit56 if your application 'oes not use pu*lish-su*scri*e. 5 6 Ep to three e&ent pools can *e initiali0e' *y calling QJ_pool+nit(! up to three times. 2he su*sequent calls must *e ma'e in the or'er of increasing *lock-si0es of the e&ent pools. Bou 'onOt nee' to call QJ_pool+nit(! if your application 'oes not use 'ynamic e&ents. 5 $- 36 (ll acti&e o*+ects are starte' using the CopaqueD acti&e o*+ect pointers 5see Listing 57- H66. /n this particular example, the acti&e o*+ects are starte' without pri&ate stacks. <owe&er, some 32)!s, such as RC;)!-//, require pre-allocating stacks for all acti&e o*+ects. 5 .6 2he control is transferre' to Q> to run the application. QJ_5"n(! might ne&er actually return.
1& of 1)
&$(
1' of 1)
' Re erences
Document 9P!iCC$: CPractical E,L !tatecharts in C;C==, !econ' %'itionD, ,iro !amek, 4ewnes, $HHG, /!?4 H8-HFG8HF 9QP;C HG: CQP;C 3eference ,anualD, Quantum Leaps, LLC, $HHG 9QP;C== HG: CQP;C== 3eference ,anualD, Quantum Leaps, LLC, $HHG 9QP-nano HG: CQP-nano 3eference ,anualD, Quantum Leaps, LLC, $HHG 9QL (4-#irectory H8: C(pplication 4ote" QP #irectory !tructureD, Quantum Leaps, LLC, $HH8 5ocation (&aila*le from most online *ook retailers, such as ama0on.com. !ee also" http";;www.statemachine.com;psicc$ http";;www.state-machine.com;'oxygen;qpc; http";;www.state-machine.com;'oxygen;qpcpp; http";;www.state-machine.com;'oxygen;qpn; http";;www.state-machine.com;'oc; (4JQPJ#irectoryJ!tructure.p'f
1( of 1)
1) of 1)