Sunteți pe pagina 1din 18

QP state machine framework example

Application Note Dining Philosophers Problem (DPP) Example


Document Revision D August 2012

Copyright Quantum Leaps, LLC www.quantum-leaps.com www.state-machine.com

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)

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

"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$

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

1 of 1)

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

&
&$1

Design an# "mplementation


-tep 1+ -e%uence Diagrams
( goo' starting point in 'esigning any e&ent-'ri&en system is to 'raw sequence 'iagrams for the main scenarios 5main use cases6 i'entifie' from the pro*lem specification. 2o 'raw such 'iagrams, you nee' to *reak up your pro*lem into acti&e o*+ects with the main goal of minimi0ing the coupling among acti&e o*+ects. Bou seek a partitioning of the pro*lem that a&oi's resource sharing an' requires minimal communication in terms of num*er an' si0e of exchange' e&ents. #PP has *een specifically concei&e' to make the philosophers conten' for the forks, which are the share' resources in this case. /n acti&e o*+ect systems, the generic 'esign strategy for han'ling such share' resources is to encapsulate them insi'e a 'e'icate' acti&e o*+ect an' to let that o*+ect manage the share' resources for the rest of the system 5i.e., instea' of sharing the resources 'irectly, the rest of the application shares the 'e'icate' acti&e o*+ect6. @hen you apply this strategy to #PP, you will naturally arri&e at a 'e'icate' acti&e o*+ect to manage the forks. 2his acti&e o*+ect has *een name' C2a*leD. 2he sequence 'iagram in >igure $ shows the most representati&e e&ent exchanges among any two a'+acent Philosophers an' the 2a*le acti&e o*+ects. ,igure 2 The se%uence #iagram o the DPP application$
., Philo/n0 thin1ing 5$6 2/,%)E2 5 6 Philo/m0 thin1ing 536 hungr2 eating 2/,%)E2 5F6 hungr2 <E413B5n6 586 <E413B5m6 %(25m6 5-6 5.6 Table serving

2/,%)E2 5 H6 eating

5G6 thin1ing

#)4%5m6 %(25n6

576

5 6 5$6 536 5.6 5-6

%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)

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

(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

-tep 2+ -ignals3 Events3 an# Active *b4ects


!equence 'iagrams, like >igure $, help you 'isco&er e&ents exchange' among acti&e o*+ects. 2he choice of signals an' e&ent parameters is perhaps the most important 'esign 'ecision in any e&ent-'ri&en system. 2he e&ents affect the other main application components" e&ents an' state machines of the acti&e o*+ects. /n QP, signals are typically enumerate' constants an' e&ents with parameters are structures 'eri&e' from the QEvent *ase structure. Listing shows signals an' e&ents use' in the #PP application. 2he #PP sample co'e for the #)! &ersion 5in C6 is locate' in the <qp>\qpc\examples\80x86\dos\watcom\l\dpp\ 'irectory, where <qp> stan's for the installation 'irectory you chose to install the accompanying software. N*TE+ 2his section 'escri*es the platform-in'epen'ent co'e of the #PP application. 2his co'e is actually identical in all #PP &ersions. 5isting 1 -ignals an# events use# in the DPP application ( ile dpp.h) #ifndef dpp_h #define dpp_h ( ! en"m #$$%i&nals ' ((! E)*_%+, - Q_.%E/_%+,0 #67E_%+,0 $).%E_%+,0 *E/9+7)*E_%+,0 (:! 9);_$.8_%+,0 (<! (?! =.7,/>_%+,0 9);_%+, 12 p"3lished 34 *a3le to let a philosophe5 eat 12 p"3lished 34 $hilosophe5 when done eatin& 12 p"3lished 34 8%$ to pa"se the application 12 p"3lished 34 8%$ to te5minate the application 12 the last p"3lished si&nal 21 21 21 21 21

@A

12 posted di5ectl4 f5om h"n&54 $hilosophe5 to *a3le 21 12 the last si&nal 21

(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

(C! void $hilo_cto5(void!A (8! void *a3le_cto5(void!A

(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.

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

' of 1)

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

&$&

-tep &+ -tate 6achines


(t the application le&el, you can mostly ignore such aspects of acti&e o*+ects as the separate task contexts, or pri&ate e&ent queues, an' &iew them pre'ominantly as state machines. /n fact, your main +o* in 'e&eloping QP application consists of ela*orating the state machines of your acti&e o*+ects. >igure 35a6 shows the state machines associate' with Philosopher acti&e o*+ect, which clearly shows the life cycle consisting of states CthinkingD, ChungryD, an' CeatingD. 2his state machine generates the <E413B e&ent on entry to the ChungryD state an' the #)4% e&ent on exit from the CeatingD state *ecause this exactly reflects the semantics of these e&ents. (n alternati&e approachIto generate these e&ents from the correspon'ing 2/,%)E2 transitionsIwoul' not guarantee the preser&ation of the semantics in potential future mo'ifications of the state machine. 2his actually is the general gui'eline in state machine 'esign. ,igure & -tate machines associate# 7ith the Philosopher active ob4ect (a)3 an# Table active ob4ect (b)$
; thinking entry ; exit ; 2/,%)E2 %(2, #)4% ; 2%3,/4(2% ; %(2 ; QJ%33)356N ser&ing entry ; gi&e pen'ing permitions to eat hungry entry ; %(2 9QJ%K2JC(!252a*le%&t6-Lp... MM P</L)J/#5me6: #)4% ; #)4% ; %(2 ; QJ%33)356N P(E!% eating entry ; exit ; 2/,%)E2 %(2, #)4% ; pause' entry ; ?!PJ'isplayPause'5 E6N exit ; ?!PJ'isplayPause'5HE6N P(E!% <E413B #)4% ; 9else: ; <E413B ; 9*oth free: ; ; acti&e

(a)

(b)

89"DE5"NE+ >a&or entry an' exit actions o&er actions on transitions.

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

( 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)

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

(?! #define /+,=*(n_! (6! #define BEJ*(n_! #define J/EE #define .%E#

(("int8_t!(((n_! O (7_$=+B6 - .!! P 7_$=+B6!! (("int8_t!(((n_! O .! P 7_$=+B6!! (("int8_t!0! (("int8_t! !

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

me!A 12 si&nal K"st fo5 *a3le 21

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

@ 12 L(1(1 1(1 1(10! 21 case =.7,/>_%+,M ' "int8_t n0 mA

@ stat"s - Q_=)7#BE#(!A 35eaNA

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

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

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.

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

11 of 1)

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

&$'

-tep '+ "nitiali>ing an# -tarting the Application


,ost of the system initiali0ation an' application startup can *e written in a platform-in'epen'ent way. /n other wor's, you can use essentially the same main(! function for the #PP application with many QP ports. 2ypically, you start all your acti&e o*+ects from main(!. 2he signature of the Q)ctive_sta5t(! function forces you to make se&eral important 'ecisions a*out each acti&e o*+ect upon startup. >irst, you nee' to 'eci'e the relati&e priorities of the acti&e o*+ects. !econ', you nee' to 'eci'e the si0e of the e&ent queues you pre-allocate for each acti&e o*+ect. 2he correct si0e of the queue is actually relate' to the priority, as 'escri*e' in Chapter 7 of P!iCC$. 2hir', in some Q> ports, you nee' to gi&e each acti&e o*+ect a separate stack, which also nee's to *e pre-allocate' a'equately. (n' finally, you nee' to 'eci'e the or'er in which you start your acti&e o*+ects. 2he or'er of starting acti&e o*+ects *ecomes important when you use an )! or 32)!, in which a spawne' threa' starts to run imme'iately, possi*ly preempting the main(! threa' from which you launch your application. 2his coul' cause pro*lems, if for example the newly create' acti&e o*+ect attempts to post an e&ent 'irectly to another acti&e o*+ect that has not *een yet create'. !uch situation 'oes not occur in #PP, *ut if it is an issue for you, you can try to lock the sche'uler until all acti&e o*+ects are starte'. Bou can then unlock the sche'uler in the QJ_on%ta5t"p(! call*ack, which is in&oke' right *efore Q> takes o&er control. !ome 32)!s 5e.g., RC;)!-//6 allow you to 'efer starting multitasking until after you start acti&e o*+ects. (nother alternati&e is to start acti&e o*+ects from within other acti&e o*+ects, *ut this 'esign increases coupling *ecause the acti&e o*+ect that ser&es as the launch pa' must know the priorities, queue si0es, an' stack si0es for all acti&e o*+ects to *e starte'. 5isting & "nitiali>ing an# -tarting the DPP Application ( ile main$c)$ #incl"de Gqp_po5tHhG #incl"de GdppHhG #incl"de G3spHhG 12 Bocal-scope o3Kects -----------------------------------------------------21 ( ! static QEvt const 2l_ta3leQ"e"e%toE7_$=+B6FA ((! static QEvt const 2l_philoQ"e"e%toE7_$=+B6FE7_$=+B6FA (:! static Q%"3sc5Bist l_s"3sc5%toE9);_$.8_%+,FA 12 sto5a&e fo5 event poolsHHH 21 (<! static QJ_9$66B_EB(*a3leEvt! l_sml$ool%toE(.27_$=+B6FA 12 small pool 21

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.

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

1& of 1)

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

&$(

-tep (+ 8race ull2 Terminating the Application


2erminating an application is not really a *ig concern in em*e''e' systems, *ecause em*e''e' programs almost ne&er ha&e a nee' to terminate gracefully. 2he +o* of a typical em*e''e' system is ne&er finishe' an' most em*e''e' software runs fore&er or until the power is remo&e', whiche&er comes first. N*TE+ Bou still nee' to carefully 'esign an' test the fail-safe mechanism triggere' *y a CPE exception or assertion &iolation in your em*e''e' system. <owe&er, such situation represents a catastrophic shut'own, followe' perhaps *y a reset. 2he su*+ect of this section is the graceful termination, which is part of the normal application life cycle. <owe&er, in 'esktop programs, or when em*e''e' applications run on top of a general-purpose operating system, such as Linux, @in'ows, or #)!, the shut'own of a QP application *ecomes important. 2he pro*lem is that in or'er to terminate gracefully, the application must cleanup all resources allocate' *y the application 'uring its lifetime. !uch a shut'own is always application-specific an' cannot *e pre-programme' generically at the framework le&el. 2he #PP application uses the following mechanism to shut 'own. @hen the user 'eci'es to terminate the application, the glo*al 2%3,/4(2% e&ent is pu*lishe'. /n #PP, only the 2a*le acti&e o*+ect su*scri*es to this e&ent 5Listing $5 366, *ut in general all acti&e o*+ects that nee' to cleanup anything *efore exiting shoul' su*scri*e to the 2%3,/4(2% e&ent. 2he last su*scri*er, which is typically the lowest-priority su*scri*er, calls the QJ_stop(! function. (s 'escri*e' in Chapter G of P!iCC$, QJ_stop(! is implemente' in the Q> port. )ften, QJ_stop(! causes the QJ_5"n(! function to return. 3ight *efore transferring control to the un'erlying operating system, Q> in&okes the QJ_onIlean"p(! call*ack. 2his call*ack gi&es the application the last chance to cleanup glo*ally 5e.g., the #)! &ersion restores the original #)! interrupt &ectors6. >inally, you can also stop in'i&i'ual acti&e o*+ects an' let the rest of the application continue execution. 2he cleanest way to en' an acti&e o*+ectOs threa' is to ha&e it stop itself *y calling Q)ctive_stop(me!, which shoul' cause a return from the acti&e o*+ectOs threa' routine. )f course to Ccommit a suici'eD &oluntarily, the acti&e o*+ect must *e running, an' cannot *e waiting for an e&ent. /n a''ition, *efore 'isappearing, the acti&e o*+ect shoul' release all the resources acquire' 'uring its lifetime. (''itionally, the acti&e o*+ect shoul' unsu*scri*e from recei&ing all signals, an' somehow shoul' make sure that no more e&ents will *e poste' to it 'irectly. Enfortunately, all these requirements cannot *e pre-programme' generically an' always require some work on the application programmerOs part.

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

1' of 1)

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

' 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

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

1( of 1)

(pplication 4ote" #ining Philosophers Pro*lem %xample www.state-machine.com

( !ontact "n ormation


.uantum 5eaps3 55! H3 Co**le 3i'ge #ri&e Chapel <ill, 4C $8- F E!( = GFF .-H L%(P 5toll free, E!( only6 = 7 7 GF7-$77G 5>(S6 e-mail" infoTquantum-leaps.com @%? " www.state-machine.com CPractical E,L !tatecharts in C;C==, !econ' %'itionD 5P-i!!26, *y ,iro !amek, 4ewnes, $HHG, /!?4 H8-HFG8HF

Copyright Quantum Leaps, LLC. (ll 3ights 3eser&e'.

1) of 1)

S-ar putea să vă placă și