ELFp4x 4 ($!444444ЖЖ  /  / T   /  / HHH QtdRtd  /  / /lib/ld-linux.so.2GNU%/')"- $%.* !#&  , +( ++"+,)K8gUa<a +[J:\ )My03&2ch SDC7 t` d __gmon_start__libc.so.6_IO_stdin_usedfflushstrcpyexitsprintf_IO_putcfopenstrncmpstrncpytime__stack_chk_failunlinkputcharstdinfgetsstrlenungetcmemsetgetcharstrstrstdoutfputcfputsmemcpyfclosemallocstrcat__ctype_b_locsscanfstderrsystemfscanf__sysv_signalfwriteatoistrchrfprintf_IO_getcstrcmp__libc_start_mainfree__xstatGLIBC_2.4GLIBC_2.1GLIBC_2.3GLIBC_2.0ii iii sii }ii / ` -d . +0 0 0  0 0 0 0 0  0  $0  (0  ,0  00  40 80 <0 @0 D0 H0 L0 P0 T0 X0 \0 `0 d0 h0 l0 p0 t0 x0 |0  0 !0 "0 #0 $0 %0 &0 '0 (0 )0 *US[Xt^ItX[5/ %/ %0 h%0 h%0 h% 0 h%0 h %0 h(%0 h0%0 h8p% 0 h@`%$0 hHP%(0 hP@%,0 hX0%00 h` %40 hh%80 hp%<0 hx%@0 h%D0 h%H0 h%L0 h%P0 h%T0 h%X0 h%\0 hp%`0 h`%d0 hP%h0 h@%l0 h0%p0 h %t0 h%x0 h%|0 h%0 h%0 h%0 h%0 h%0 h %0 h(%0 h0%0 h8p%0 h@`%0 hHP1^PTRhshsQVh,US= u@ / -/ X9sB /  9r []Ív'U/ tt $/ ÐU}uE]UVS@EEEEEEEEE܋E؉EEE‹Ef+EE;E"U܋E)Eā}'0eЁ}'vE'EEUЉ$E}l0EUD$ED$$EEEEEEEUD$E؉D$$EE؋EEEE9Et E$ +EEEܸ+EE؉EԸ+EE;E/E zE}u fEE䣰6=Mwt DžEEE}}E;EurE ~E}}-}X-][}).}tmt EEEEԉEwE}?-EvEȸ+EEԋÉ}i,EO,EԋD$D$$$?qEԋ$Eԋ@DDEԃB4   +   +D$$Ò+EԃEԃ$pEԋPEԃEԃ @\$t$ T$L$$EEԃ(Eԃ(@EJEԃtEԃ@ DžD$T$E$ EEԃ(@;E$tLtEԃ PEԃ(B4}t uE@D*D$ D$D$/$rE̋E@b*D$ D$D$/$<E̋E@,*E *D$ D$D$/$E̋E@)D$ D$D$/$ħE̋EԃPẺPEԃ@=)D$$)D$ D$D$/$]E̋E@Eԃ@@fu"Eԃ@D$$觤)Eԃ@@4f=/t"Eԃ@D$$n(Eԃ@@4PẺP(Eԋ@D(Eԋ@DD$D$ D$D$$'EEԃtEԃ@ DžD$L$E$J$D(Eԋ@D t D$$>zEԋ@ 'EԋPEԃ@D$D$ T$D$$MD'Eԋ@D t D$$QEԋ@   N'EԋPEԃ@D$D$ T$D$$D  &DtEԋ@D$$d9Eԋ@<&Eԃ$Z<&EԋE&EԋE̡ &Eԋ@D$$~̢f&  T&EԃEԃ@T$$oQ  #&EԋPEԃ@D$T$$%0f6L6Lf~L%EԋPEԃ@D$T$$(0f6L6Lf~L%EԋPEԃHEԃ@T$L$$/f6L6Lf~LV%EԋPEԃHEԃ@T$L$$/f6L6Lf~L %  D$$&PE  D$ D$D$$趢E̋ŰEBf~L$  D$$OE  Ef@D$ D$D$$>E̋ŰEBf~L&$  D$$?OE  D$ D$D$$ϡE̋ŰEBE$oIf~L#$#D$ D$D$@$s$h#$‹ẺPO#EԋB#Eԋ$0#Eԋ##Eԋ$#E#EԃPEԋT$$XlE"D$$*"D$$"EԋE"EԋEԃT$$E}"Eq"EԋEd"EԋEW"EԋEJ"EԃEԃPEԋL$T$$/gEԋE"EԃEԃPEԋL$T$$ EԋT$$ E!Eԃ@=tD$$̓ Eԃ$lEԃtEԃ@D$$Db!D$$话I!EԋD$ D$D$,$"E!EԋEԃT$ D$D$,$E E EԋE EԋEԋD$ T$D$1$語E EԋEԃEԃL$ T$D$1$uEo EԋD$ D$D$0$HEB EԋEԃT$ D$D$0$E EԋE̋EԋXD$ D$D$/$۝C4Eԋ@@4@EԃPEԋB4EԃE̋EԋEԃT$$`Eԋf=/tEԋf=2uEԋ@@Dt R CEԃPEԋB4EԃE Eԃ@t0L0L ,L,LEԃ$E U9}  EԃD$ D$D$@$tE̋EԃPẺP]Eԋ@@EԋEAEԃPEԋ@BEԋ@v)Eԃ@D$$臙Eԋ@Eԃ@@EԃEEԃ PEԃ@BEԃ @@ Eԃ E EԋD$2T$$( EtEԋD$ D$D$2$MEG<8EԃEԃD$ T$D$2$ E  Eԋ@@f=Eԋ@@<<EԃE̋EԋẺP$Eԋt&Eԃ@@f=tEԃ@f@   u: u1Eԃ@@fuEԃ@D$$6轗EԋtEԋP EԃT$$<EEԋD$ D$D$.$ЙEEԋEEԋE̡ D$$N  }  4Lf4LEԋEԃ Eԃ L$ T$D$r$1E̋EԋD$RD$$_    4Lf4LEԋEԃ Eԃ L$ T$D$s$谘E̋E@EԋD$SD$$_Eԋ$GsvEԃD$ D$D$$LE̋EԃPẺPẺ$L*q Eԃ D$ D$D$$E̋EԃPẺPẺ$D$ D$D$$讗Ew‹ẺPEԋD$ D$D$$tE̋Eԋ@@ft,Eԋ@@f=tEԋ@D$$[輔Eԋ@f@#EԋEԃD$ T$D$:$E̋Eԃ@@ft2Eԃ@@f=tEԃ@D$$[7Eԃ@f@EԋEԃEԃL$ T$D$:$lE̋EԋEԃT$$aYEԋEԃD$T$$Eԃ$D$ D$D$/$E̋E@EԃẺD$ T$D$+$•E̋EԃEԃẺD$ L$D$:$蔕E̋EԃEԃT$$XEԃ$Eԃ@@f@ND$$m蛓5D$ D$D$/$E̋E@EԃẺD$ T$D$-$۔E̋EԃEԃẺD$ L$D$:$譔E̋EԃEԃT$$WEԃ$Eԃ@@f@gD$$贒N0 ?EԃEԃ D$ T$D$$E0 EԃD$ D$D$$דEEԃD$ D$D$$觓EEԋD$ D$D$$zE̋EԋD$$%_EԋER  @  4Lf4LEԋEԃ Eԃ L$ T$D$r$EfvLE@EԋD$RD$$>Y    4Lf4LEԃEԃEԃL$ T$D$r$]E̋E@EԃD$RD$$X-    4Lf4LEԃEԃEԃL$ T$D$r$̑E̋E@fvLEԃD$RD$$X    4Lf4LEԋEԃ Eԃ L$ T$D$s$5EftLE@EԋD$SD$$WEԋ$kEԋD$ D$D$c$ːE̋Ẻ$kD$ D$D$$蔐E$}EԃD$ D$D$$SE$D$$‹ẺPE̋@D$$$ NEԃD$ D$D$$яE$ED$$A‹ẺPE̋@D$ $$yD$ D$D$$SE$D$$‹ẺP)  EԃEԃ@T$$7  EԋEEԋ@D$$N‹ẺPEԋPEԃ@T$$"‹ẺP$wD$ D$D$$QE$‹ẺP7EԋE*EԋEEԃE EԋEԃT$ D$D$+$EEԋEԃT$ D$D$-$豍EEԋEԃT$ D$D$*$耍EzEԋEԃT$ D$D$/$OEIEԋEԃT$ D$D$%$EEԋEԃT$ D$D$&$EEԋEԃT$ D$D$^$輌EEԋEԃT$ D$D$|$苌EEԋEԃT$ D$D$F$ZETEԋEԃT$ D$D$E$)E#EԋEԃT$ D$D$D$E EԋEԃT$ D$D$C$NjE EԋEԃT$ D$D$B$薋E EԋEԃT$ D$D$A$eE_ EԋEԃT$ D$D$@$4E. EԋEԃT$ D$D$?$E EԋEԃT$ D$D$H$ҊE EԋEԃT$ D$D$G$衊E EԋD$ D$D$~$tEn EԋD$ D$D$L$GEA EԋD$ D$D$!$E EԃEԃ T$ D$D$?$E̋EԃẺD$ T$D$?$載E  D D$$  EԃEԃD$ T$D$ $HE̋EԋtEԋ@ DžE̋HEԃEԃD$AT$$oOẺ$L EԃEԃD$ T$D$ $趈E EԃD$ D$D$ $膈EnLfnLp  ^  4Lf4LEԃEԃEԃL$ T$D$R$E    4Lf4LEԃEԃEԃL$ T$D$R$訇EfvLE@ EԋE̋Eԋ$cu EԋEh D$ D$D$/$BE̋EԋPEfPEԋPẺP D$ D$D$!$ED$ D$D$"$̆ErLfrLEԃD$ D$D$$茆EpLfpLvEԋPEԃ Eԃ@T$L$$ECEԋX EԋPEԃ Eԃ@\$ T$L$$̊EEԋPEԃ@T$D$$胉EEԋP EԋHEԃ@T$ L$D$$bEEEԋEEԋEtEԋEgE[Eԃ$u D$$蹂E'EԃEED$$̔肂EԋEEԃEEԋEԃT$ D$D$@$评EEԋEԃT$ D$D$@$~ExEԋEԃT$ D$D$?$MEGEԋEԃT$ D$D$?$EEԋEԃT$ D$D$@$EEԋEԃT$ D$D$?$躃EEԃEԃD$ T$D$+$膃EEԃEԃD$ T$D$-$RELEԃEԃD$ T$D$,$EEԃEԃD$ T$D$.$EE@EԋPẺPE̋@D$$ EԋPẺPE@EԋPEԋD$ D$T$$\EVEԋEԃHEԃT$ D$L$$$EEEԋEEEԋEEԋEEԃ f,u$EԃEԃ T$$(EEԃEԃ T$ D$D$,$|EvEԋf,u EԋE[EԋD$ D$D$,$4E.Eԃf,u!EԋEԃT$$zEEԋEԃT$ D$D$,$рEEԋE̋EԋEԋT$$CEԋ$EԃD$ D$D$ $qE̋Eԃ $I[D$ D$D$/$5E̋EԋPEfPEԋPẺPD$ D$D$/$E̋Eԋ@ڋẺPEԋf,u EԋEEԋD$ D$D$,$EEԃf,u!EԋEԃT$$EYEԋEԃT$ D$D$,$.E(Eԃ f,u$EԃEԃ T$$qEEԃEԃ T$ D$D$,$~EEԃEEԋD$ D$D$2$~ED$ ẺD$D$,$b~E_EԋD$ D$D$2$8~E̋EԃD$ ẺD$D$,$~E EԃE̋EEԋEEEEUԋẺEvEEb`}ЋEE}x3}*EEf9uE ~EUEb`yE>}u$}u=%D$ED$$rEE zE}t9E}x/}&EfuE ~E}CE;EtcE ЋEԉD$T$$0mmEEl})tEUԉEE"EE$?Et%tD$ED$$P[EEԋEE0E ЋEԉD$T$$nmmE;Euȍ9Et E$E@[^]UD$E$xÐU}"t} t EEEUVEu}_u EEEUE%UE%U(EEUEOEUE}\u90 y$EEEEEEUE0 y$ EEEEE$E ЅuEƀ0 yD$E${U(0 y$EjEEEE;EuE E*0 yD$E$jEEEUE$$wEED$E$DEhEET$$uCED$$vUEPUEBUE BEPE@$E}u$(>wEUEUEPUEBEt3E$$w‹EPEPED$$UE BEPDEP$EDU(<ED$ D$ D$$ED$ D$D$$ED$ D$D$$2q~LfDEE@ftE@fED$D$GE$$E@EEE< tE< tE<\tދED$$"4EEE}"t}%t-} t<_ED$ D$D$$QRD$TE$=ED$ D$D$$WKEЋED$$EEEt }JEt#ED$ D$D$$ZED$$"2ED$ D$D$$^E@$E}HED$ D$D$$cyED$ D$D$$xVU(DE,ED$E$u EE@$E}uEEU(@tI@EB@}uL@ 0 `EB` 0 `EB`}u`0 @0 0 @ 0 0 0 y$]E-EEEEEEU@t@@0 ``]UDE#ED$E$tE@$E}u׃}uED$$|=rEU$LrEUEUE BUEBEP EU$rEUEUE BUEBEP E}ED$$u E@kED$$tIED$$t0ED$Ù$utED$$ЙFp f U(EEEE< tE< tEE< tE< uEE< tE< tEE<*tEE< tE< tEuED$$spD$[E$kt3D${E$TuED$$WoEEEEU(ED$ D$D$$-PEfE@OE@D$D$D$E@E(E<"uE E<\u E EEEu΋E$PE}E@D$ ED$D$ME$E@D$D$\$'u}E@E(E<"uE E<\u E EEEu΋E$E}t&E@D$ ED$D$eE$E@ E}ED$ D$D$$pU8EE D$D$sE$E|E@eE@D$D$$ =E@EE<"uE EEuE$EE@EEE< tE< tE$t$mEED$E$脿E$IEE EmE< tE< tED$E$Nuc}t*ED$ D$D$$AE}t-E@D$ED$ E D$D$E$E@ E}zED$ D$D$$pѾU( t EE@D$D$D$:tTE@D$D$\$t0E@D$D$$t  E@ E}uU8Euu EEKE@D$D$D$xuED$D$ǚE$覽E@ E}uEyE@D$D$D$tLE@D$D$\$t(E@D$D$$սtEE@ E}uE EE@ E}u}u EEED$ D$D$$͚襼EE@D$D$D$8E@D$D$\$tjE@D$D$$tFE@E}u EݚEޚED$ ED$D$E$EE@ E}7EYE@uFE@E}u EݚEޚED$ ED$D$E$艻EE@ E}u}uED$$4譻ED$ D$D$$*EEU(EEYE@tFE@E}u EݚEޚED$ ED$D$E$˺EE@ E}u}u#ED$ D$D$$U(Eu t\ ftPEE@tEE@ E}u}~#ED$ D$D$$US$EE@D$D$$茺u_EE$R ED$D$E$蘹EE$"E@ E}j$[]U(E D$$ D$D$0$ 许 $葸EE@D$D$$蔹u]E@EEE< tE< tD$ E$uuED$D$ǚE$胸E@ E}lUS$ED$ D$,D$$44E.EE$豷 E E@E@$膷 E@ E@D$D$D$rE@D$D$\$JE@D$D$$"t\ED$&$tED$$ddEE@T$ D$D$E$E@ E}E^EE$o E E@E@$D E@ E@ E}u<u(ED$ D$D$$TV fED$ D$#D$$ED$ D$D$$ED$ D$D$$ޛֵD$E$ӵED$ D$D$$蠵EE@ED$D$E$wE@ET$ D$D$E$MED$ D$D$$9E@D$D$@E$ E@D$D$YE$E@ E}6ED$ D$D$$h覴ED$ D$D$$l胴ED$ D$D$$ޛ`D$E$]ED$ D$D$$*EE@D$D$D$轴E@D$D$\$蕴tmE@D$D$$qtIE@ET$ D$D$E$蓳E@D$D$ҜE$tE@ E}4EE@ED$D$E$(E@ET$ D$D$E$ED$ D$D$$9˲E@D$D$@E$輲E@D$D$YE$蝲E@ E}6ED$ D$D$$pW f)ED$ D$D$$$ED$ D$D$$ޛD$ E$ED$ D$D$$˱EzE@tgED$D$E$話E@ET$ D$D$4E$E@D$D$YE$`E@ E}uED$ D$D$$pED$ D$D$$PED$ D$D$$ޛذD$pE$հED$ D$D$$袰EE@D$D$D$5E@D$D$\$ tmE@D$D$$tIE@ET$ D$D$E$ E@D$D$ҜE$E@ E}4EzE@ugED$D$E$觯E@ET$ D$D$4E$}E@D$D$YE$^E@ E}uED$ D$D$$pED$ D$D$$$[]U(} E P$ED$T$E$E @DE @;EE D$D$E$蔮E @EEE< tE< tE<\tދEE E ED$ʝE$RE}uڋED$D$͝E$E D$D$ѝE$UDD$D$E$U<u tE$IE$DD$D$E$u t%ED$ D$D$$F#ED$ D$D$$! t E$E$E$UEleE1JJxJxT$$|xD$D$|$l@|D$$stAxJT$D$$lD$$DYx@xx7Ee3t1UE $EE$E@‹ED$$ U(} E f=E @$EE@E@D$D$dE$YED$ D$%D$$&E@D$D$E$E@D$D$E$ED$ D$D$$ɪ*E @$D$E$ E @ D$E$U(E$EE@ED$0E$苪uD$(E$;Ev EEEU(E $?EE$&ED$ D$D$$5}E@tzE@D$D$8E$שE@D$D$WE$躩ED$ D$ D$$q臩E@D$D$|E$z}u#ED$ D$ D$$AE@‹ED$$芧ED$ D$D$$˟UE$ EE@ED$;E$腧u.D$ϟE$ިuD$ҟE$ǨtjE@0 E@ED$$՟DU[Et E<D$*D$$/E}  D$:D$$:ED$-D$I$-D$D$$>|EcD$+D$J$+XE?D$ED$C$=4D$D$H$<ED$FD$D$=D$D$G$>ED$:D$B$=ED$>D$=$!D$D$A$=EjD$<D$;$?_EID$&D$@$&>E(D$|D$?$|EE 7D$ D$D$$HEE؋E؃D[]US$D$ D$D$$wHEyE1 D$E$uVE1 BE 1 tE 1 $9 CE1 EEE1 sE$~CCtf@E/D$E$5ujLfjL0 @0 @EEE@ @D$E$Ϙ0 P ED$E$螘n0 @EE@ @0 P EL$$NuE@ @0 D$T$$%0 D$$ĥDE@ fE@ @$jCE2E@$E}90 P EE.E<.cE$=E<.JEED$E$虖E}u0 P E@EzE@$EE}(E$CE$lt E37E$苶t E4E$t E5E2E$[]U(tE2E=u0}t'}tEE(}ur}$ti}9t`}7tW}tN}tE}t<}}t6} t-}t$}tEE}uEDt <V}t =uEE CD$$Hu!    ƀ D$$uQƒt   D$$_D$$覔u?o  D$$J}/uP<'uE@D$D$$近  D$$诓}/uE@D$D$$q  D$$aE-E}3nU,D$D$$/AD$D$$ D$D$ҟ$D$D$ϟ$̑D$D$$諑D$D$$芑D$D$ $i{D$D$ $HZD$D$$'9D$D$$D$D$$D$D$$ĐD$D$$裐D$D$$肐D$D$$avD$D$ $CXD$D$#$%:D$D$%$D$D$($  D$$蹐EEEÐU}u} u E6}t} u E!E ET$$ƐEEUE#EEEeE%tMEuӋE%U(E$EEDEdEED$$9uCDE@DT$$t'<E@@T$$t EE`E@HE}uDtgEDEREED$$跏u1E@Du'<E@@T$$t EEE@HE}u$LR<EE$$9<‹EEED$$#E@KEPDEPD<EP@ udEDEPHUED$;EUEDuEDDDDUPEDEEEUE@E}E E}/tW}2E @@fE@ ƒEP E @@ftxE@ ƒEP dE @tE @tE@ ƒEP E @x E @=~&E@ ƒEP E@ ƒ EP UDD$ ED$D$$;DUhEEeE1EDEE؋@ EԋEԋPE@D9Eԋ@ EEE;E EЋ@ Eȁ}/u1EЋ@ @Eȃ}t }tM}x }~UMO}2u)EЋ@ @@Eȃ}t-M}t#MM EЋ@$EЃE}\E؋@$E؃}EătEă Eău EEED$E܉$E@D$E$a E$襊EED}~mED< t}E܉D$E$見tnE$EEE@Dt E@DEEED$ ED$ED$$PED$E܉D$$/4Ee3t蓊U(EEEuE@ t^E@ @tQE@ @@f@u>} t E @EEE@ PED$ ED$ED$$k8E@$EE}uU(0 EEE@@ftJE@@  u6E@0 E@E@D$$96E0 EPE fB tAEPE@@ B } @u%EPD$ FED$D$$7} ucE@@xE@@~E@D$$OQ6E@@uHE@@D$$lH5%E@@~E@D$$!5}E@D$D$$uGEPE@@ B `L`L} E@D$$5vE@D$D$$肈uEPE@@ B :E@D$D$$FuEPE@@ @B } @uEPDDDBZE@@E@@4t@E@@4f@u.E@E@0 E@D$$4E@@6E@0 E@E@D$$~3E0 E@$EE}UE@$ U EP$} t } E UDtkDE UDL$$tBDE UDL$D$$0ED$$T2E  DULUEErE@ EXE@@f=uE@P8E D$$%E@@f@uEPE D$$E@$E}uE@$E}uU(fxLtI} uCE@t E@EEtE@D$ UT$D$$|̄Du*E@0 E@D$$è^2EE$(m2EUE BEP EP DEPDEP$EDE@ EE@@f=uE@P8E D$$deE@@f@uEPE D$$>0 EE@0 E@E@D$$ݨ0E0 E@$E}US$0 E}tE@0 E@Du ED&DE E@$EE@$uUEB$DEEE@ t)E@ @tE@ f=2u E@ @ tD$$0E@ @@f=toE@ PE@ @@ ȀB E@ @f@E@ XD$ D$D$/$1C4E@ @P4EB/E@ @@4@;EtE@ @D$$ /E@$EE}E0 }~D$$8/$[]U(EDE3E@ @D$E$躂uEEEE@$E}uEEUE E} +} 4}t}}}}}}}@}]},}$>D$ D$WE$胀BD$D$aE$c"D$D$hE$CD$D$oE$#D$D$vE$D$D$}E$D$D$E$D$D$E$eD$ D$E$HD$D$E$iE+D$D$E$EEEEUeE1ED$|$t"|D$$=Džl DžllUe3tU(E@$v=$ }E@@tE@@D$$~ED$$~E@ E@ <uE@D$$~E@f@u4E@4tE@4@EEED$$@~EE@f=uE@<D$$~E@4$D$$}E@@t$}0E@Du$ϩ}E@DD$$۩}E@yE@؉D$$} $}E@f@E@4E@4@$EE EE@$E}uED$$'}E@4@$EVEf=uE@D$$|E$bE@$t $ {E@$E}u$ {UDEE$E@E}uU$ o|E@DtE@DD$$M|E@@tE@@D$$+|ED$$|E@ E@ <uE@D$${$ zU(EuYE@0E)E@ ruME@ suME@E}uу}fE@ QE$EEE EE@0E!EP E4 9uEE@E}uك}EE4 D$$zE@0EEP E4 9uoED$$zE@tE@D$$zE@tE@D$$ qzm}~ $[zE@E}jE}}u EEE$zUeE1Dxx@@x@lltnl lt\ltSltJVl@tlt0l t'3D&x$}x@ <u>x@Du/~Lfu#5 txx@ B  ~LfD$$3xx@D$|$x@Dtx@DD$$Gux $SgxxD$|D$$\Cxx@xx4Ee3txU(E@EED$$xu D$$$EaED$$xu(Jt J@EEEE ED$$vxu7JtJ@tJ@@EEMMED$$&xu1Ju EJP K)MED$$wuJJ)MYE@DtE@ftE$HE3E@fuE$EUEBE$EEUE@@Dt&E@@ftE D$E$菵E}.}+}}}!t<}:$@OD$$attEE@tSE@@$uCEPE@@$B$<u$$0NE@D$$\MED$E$踏E}$ME $I$ LD$$>v} t } uGI#E u;} u EùE͹ED$$ع-MI E I} "uD$$EEEU(HHEf@ED$E$`D$ E D$D$?$EUEBD$ ED$D$p$E$‹EPD$ D$D$2$EUEBD$ ED$D$q$nEUEBED$ ED$D$B$@U(HHPP5 D$ E D$D$?$EUEBED$ ED$D$p$EUEBEU( EEE}Ew UԼ}~#}ED$D$4E$+KED$D$=E$KO ED$ D$D$$AJ' ED$ D$D$$DJ ED$ D$D$$GJ ED$ D$D$$JaJ ED$ D$D$$M9J ED$ D$ D$$PJ_ ED$ D$D$$ZI7 ED$ D$D$$_I D$5 D$dE$I ED$$@I ED$ D$D$$qaI D$#5 D$zE$QI D$5 D$E$1Io D$5 D$E$IO D$-5 D$E$H/ D$#5 D$E$H D$#5 D$E$HD$#5 D$E$HD$#5 D$E$qHD$#5 D$E$QHD$#5 D$E$1HoD$#5 D$˺E$HOD$#5 D$պE$G/ED$ D$ D$$ݺGD$5 D$E$GD$#5 D$E$GD$#5 D$E$iGD$#5 D$E$IGED$$.GoD$#5 D$E$GOD$-5 D$E$F/D$-5 D$E$FD$5 D$!E$FD$-5 D$&E$FD$#5 D$-E$qFD$-5 D$2E$QFD$5 D$9E$1FoD$#5 D$>E$FOD$5 D$EE$E/D$#5 D$IE$ED$#5 D$RE$ED$5 D$WE$EED$ D$ D$$\YED$#5 D$hE$IED$#5 D$qE$)EgD$#5 D$xE$ EGED$ D$ D$$DD$5 D$E$DD$-5 D$E$DD$5 D$E$DD$5 D$E$aDD$#5 D$E$ADED$ D$ D$$ DWD$5 D$E$C7D$5 D$E$CD$-5 D$ƻE$CD$-5 D$ϻE$CED$ D$ D$$׻aCD$-5 D$E$QCD$#5 D$E$1CoD$#5 D$E$COD$5 D$E$B/D$5 D$E$BD$-5 D$E$BED$ D$ D$$ yBD$-5 D$E$iBD$-5 D$E$IBD$#5 D$(E$)BgD$#5 D$3E$ BGD$#5 D$>E$A'D$5 D$IE$AD$5 D$ME$AD$5 D$RE$AD$5 D$WE$iAED$ D$ D$$]1AED$$;yAgD$#5 D$gE$ AGD$5 D$nE$@'ED$ D$D$$r@D$#5 D${E$@D$#5 D$E$@ED$ D$ D$$I@D$#5 D$E$9@zD$#5 D$E$@]D$5 D$E$?@ED$ D$ D$$?D$#5 D$ʼE$?ÐU(JD$ D$D$$ }?JD$ D$#D$$(X?JD$ D$D$$L3?JD$ D$*D$$`?6 JD$ D$D$$>JE t EEJUT$UT$ D$D$$>JD$ D$D$$n>U(JJJJ JD$ T$D$ $@>6 EIJEt0JED$ D$D$dE$ m}yJD$ D$D$$=6 iJD$D$$=6 iJD$ D$XD$#$n=JD$ dD$XD$#$I=JD$dD$1$,=JD$ D$D$$?D$>D$T$ ED$D$E$JEm}yU JJEJE f]U( 6 E6 E}Љ)‰ЉEJD$ D$D$$ 4JD$ D$#D$$t4JD$ D$D$$LO4JD$ D$*D$$`*4JED$ D$D$$4JEJD$D$$3JD$ D$D$$3JED$ D$D$s$3JEk2 JED$ T$D$# $j3JD$ D$*D$$453JD$ D$'D$$`3JD$ D$D$$2USdEeE1} uE$E$$A2RP,$d$@ٝمٽ f٭۝٭ 6 E6 )Ek2U D$D$D$D$ \$L$$<~Bt Gt%FL>L>?DL>?L>!?L>L>D$!$/t&???ZD$?$/t&????} D$ D$D$$16 9Jt0J$/Ë$/9w-J$q/$JD$$n/مٽ f٭۝٭ 6 E6 )Ek2U D$D$D$D$ \$L$$JD$ D$D$$ .JD$ D$#D$$(.JD$ D$D$$L.JD$ D$*D$$`k. 6 E6 Љ)‹Ek2E JT$ D$D$ $(.JD$D$$.JD$ D$D$$-Ee3t.d[]USdEJk2=Jk2P$d$D6 6 6 ɡJ\$\$D$h$_-6 P$d$]6 E]E}Eʴ fEm]mʋEģ6 6 EIJEt0JED$ D$D$E$m}y6 6 9| 6 6 EJEfuJELEH6 J9|*JD$ D$D$$,JEfEEJEE衸6 UUUE6 E‰EE)EE)EJE JJEf9urE;EujJEȋEXJED$D$D$?D$ED$ L$\$$t JJEȋJED$D$D$?D$ED$ L$ED$$D6 9E JJEEfJEfJE؉EEEܡ6 U܉UUE؋6 E‰E؋E)EE)E܋JE؋ JJE؍D$D$D$?D$E܉D$ \$ED$$$JEtFJEJEЉL$ ED$D$$.EEE6 9EsJD$ D$D$$(d[]U6 6 9|$6 ` D$D$$(J6 ‹EfJ9E~EJU(E $($!EE D$E$(KuJE‹EE$AK6 9}6 6 9|36 ` D$D$$'D$$iJK¡6 J6 ¡KJ6 ‹E6 6 U(D$D$#E $(u EEEEu%Jt J@EEEE;EEEuEE D$E$jS8u-$)&E$,&EE;E~ED$E $$E$%ÐUEEEE$.EE@$E}uEU(E@4u EJ= ~1E@4@0 E@4@ED$$H,t J=~D$$]pE@4f@tE@4$s{E|$$eEJJJ‹EfE@4PEPE@4@$$‹EP KEPE@E}EEEE@ E$‹EPE@ $‹EPE$‹EPE@4@$EEjE@t:Ef=u.E@$P&‹EHT$ED$ $W.EEPE‹EEE@$E}uJEP EJEPE`EEEUE@ $yE} ;}x5E`t'E`PE`@9EEEUE@ $lyE} &}x E`tE`@EEEUE@ $yE} .}x(E`tE`@EEEU(E@ $xE}u$tm#EE} s}xmE`t_E`KBE`@~E`ED$$E%E`ED$$ EEEU(E@ $wE}E@E@D$$"wt EE@$EZE@ f=/t.E@ f= t- EEP ED$$D$$$E@$E}uEEE@t E@EEED$$ !EE[} K}xEE`t7E`KBE`E D$ED$$EEEU8EEE @$EuE@ $OvEPED$L$${EEPE@ EEEE;Et E;E$5E@$EE}tE@ ;EvEE@;EQE@EEiEHEPE@ EEPE@ EE}u%EPE EPEEE@ ;EmE;EsE@ EU(EeE1 E;E tz}@t} @unED$E$OE D$|$:|D$ED$ D$D$$(D$$lEe3tUS4EPE@ ‰EEE@~EPE@9| Ewt EE @tE D$E$[EEHE@ UUUÉKE @$EE@ $sEEHUEEPED$ED$$親t?K9|0ED$ED$D$ D$ ED$E $E@ ${&EPED$L$$E@$EE}tE@ ;EK9EE5ED$ED$D$ D$ D$E $JEE@ ;EE@ ;E~KD$$?}tKD$$@$E@PEPEE4[]USDEE@u EoE @$EEE@ f=/u(EPE@ EEE@ @9u?E@ f= udEPE@ EEE@ @ $?q9t4E @tE @tEE@9EMEE@$EE}tE@ ;E4wt Eyt=E@ ;E~KD$$h}tKD$$KtE JEJEPEEE @$EEt }KuwK9|h}tE @ EEEPE@ EEED$ED$D$ EԉD$T$E $ }}E@ f=/tqE@ f= tbEPE@ EEE@ T$$E@ $"EPED$L$$E @EEjEPE@ EEEHEPE@ E}u%EPE EPEEE@;EE@$EE}tE@ ;Et }KuwK9|hEEU}tE @ EEED$ED$D$ E؉D$D$E $ EE@ ;Eu2}t,Ku#K9|KD$E$}tE @E@PEPEEЃD[]USDJEEE @$EEPEE@ $ mEPED$L$$9E@ $Y EPED$L$$E@$EE}tE@ ;EcE@ LuE@EwtE@EEPKK9E @$EJEEJEJE@ $k‹ED$ED$D$ D$T$E $E@$EE}t E@ ;EEE5ED$ED$D$ D$D$E $VEE@ ;EE@ ;E~KD$$K}tKD$$.EJbJt JuD$$:J@$EEE@ f=2uE@ @D$O$tE@ $jEEt5JJD$ED$D$ D$ED$$/E@$EE}tE@ ;EUtMEE:JJD$ED$D$ D$D$$EE@ ;EuKKD$$JJEE؃D[]U(EeE1@@f@u @D$$+C@@f=2u*@$譃D$$+@@f=@@Dt6$uPuD$Q$+B$/D$$wD$D$$ P D$ D$D$$J!D$$+D$U$+@ @ tD@ @ $gD$D$W$RD$$+LEe3t U(}uV+E$D$D$\E $@t E`EbED$$+D$d$+E <[uD$f$+EPE=D$E$E@ ;Eust ;E/JtJP K)MEEEE <[uD$h$+ D$+E$U(6 tb$j<EED$$n EJJ) K);E$ 6 }ED$$sJt4E$wEJP K);E$||+E$D$D$\E $/t E?E!ED$D$+$  $,E <[u $[ EPE= D$ED$$E@ ;Eu"E <[u $] $ U$nEUEJEPEJUJEE;Eu EE@E}uEEUElEhEdE`eE1l@ $c$qttu5`D$ED$ E D$hD$l$L`D$ED$ E D$hD$l$$t:h<[t-l@ $bD$D$|$ +l@ $bD$D$|$` D$D$\h$ uD$b|$8 0D$`|$ hD$|$V }u@$kLl@lH|D$ T$L$$" $, `PE= D$E D$$`@ ;E$t&$hb uo$ al@ $laD$dD$$m +l$D$+$D $ Ee3t U(eE1DžD;Euu@ @$ =v @ @D$$蚷a@ @D$$~ D$$+ \@$t } WED$D$$D$$+ Ee3ty U+ED$E $D$+E$ U(E@JEEȋEPE 9$~tEPK9[E@MED$$C }t+EP K)‹ET$D$$ E@ E@ tEE D$T$$ED$$E$[Ec}~ $,EPE=ȋEPE@ EE L$D$$BEE@ ;E$].EE@;E^$ E@ E}HU(E}E@E@@f@E@D$ LD$D$$`} t E f=/uD$$ 8} tEE @t;E @@f@u+E @D$ VD$D$$} E f= E f= E f=+E f=-E f=,E f=.E @tRE @@f@uB}uD$$ O&E @D$ VD$D$$)E f=2t E f.uEE P ED$T$E$/E @$D$D$E$U;E2EED$$uE@PEPmE@E}u$ 蟳EE$f$膳‹EE@EED$$f;EPE;UE;EaEED$$5u:E@PEPE@u6}tEPEP"E@;EEE@E}uU;E6EED$$uE D$$<菱E@E}uUHEE EeE1}@0 f=2o@D$$@D$$@ D$c$t$D$$D$D$$@D$f$P D$D$$D$h$D$$GD$$$@$P$D$D$$9f=/uPD$f$A@D$D$E܉$E܉D$$ f.uSD$h$D$h$P D$D$$u,D$j$D$j$yEe3t8U(EeE1;D$D$$1D$D$$D$D$$Ee3tUE@E@twE@EE$uD$mE$t'E$u*D$tE$uED$$xgE$ÐU$mEJD$E$\EEJ}t JUJ6 ]U6 ]U(EE}tgEt^Ef=uPED$$E}tEP6 9}#E@0 E@EdE@$E1EPET$$\u E1E@E}uɋE@0E}t E;E 6EEU}t@} t:EP E @ 9t*E@0 E@D$$¬UEf=t?Ef=t3Efcu0E@ t&E@ f=/uE@ @u EEEU(EEEEEEE$fD$E$E}Ef=Ef=tz t"E@E@T$D$$E;EtBE@;Et7E@;Et,E@ƒEPEP0EP0EEEEEE@0E} U}tVDt& t DT$$Ht'E@EE$E@E}uU8JE}6ED$$qE}EEEtE@EEEtE@EEED$ ED$ED$$r}E$$8$`Z$%$$ $%$$$$ |$$0_$$TG$$v*$n$$$$$$$$$$$# $/$菔}u/EPET$$~uD$$H[J@JJEP EPEPE@uD$$lEU(D$ D$D$ $膩EEPEPEPEPzLfzLE f=u E @E6$BE $ $D$$EEf=uEPEBE@EcEf:E@ f=t"E@ f=tE@ f=E@ EE@ PEBE@ PEP$xE$ D$ D$ED$$@E$D$$‹EPEPEPEPEPD$ ED$D$:E$ߧEEPEPEPEPEEF$E$O $‹ED$$EUEBEEEU$EUEUE BEU}tDEf=t Ef=uE$EuEf= uE$EY$4sEUEJEPBJJEPBJJEP,EJEEEU}u EZEE}r|}s~ E-+w E,E@ $t EE@$$EEUJEEE@0E-E@0E E@0E}tEf.tE@@@0uE@PEB0qE@@@0f=t9}tE@@@0PE@9t3D$$¢E@E@@@0BE@,E}U8EEE@E$ED$ D$D$.$踤$jEEEEEEEEf=uU}tD$$赢E@tEEE}tEPEP1EPEPE@EE$n EEEE@E}]}t3E@}uD$$#EUPEE}tY}tSEf=uAE@lLflLD$$44D$ D$ED$E$0‹EEEBUEB$EE#ED$E$EEE@E}uׁ}ugJD$E$xD$ D$D$E$袢$TEc ‹ED$$J@JJD$E$JD$E$EU(E@(EE;E E@E}uE@(EEE D$$E@E}u݋E@(D$E $a‹EP(E-E}U$E@$E D$$jfE@$EEE D$$IE@E}u6E@E D$$E@E D$$UEE&E D$E$E@;EtE@0E}uU(E@E$ED$ D$D$.$蠠$RED$ D$D$ E$r‹EEEBUEB$}tE@t E@@tD$$H艞EEED$E$E@E}u݋E@ET$$JD$E$JD$E$iEU(D$ D$D$/$臟EE@D$ ED$D$c$W$ U(Ef=uOD$E$IE}t3gEED$ED$E$E D$E$E u U E E PEB0U EBU(}u EPEf:u.E@ $EEPED$$EEEJE$EEU}tVEJE$wEJf=t2Jf=t$Jf= tJD$E$U}JE9E;Eu&EPD9uED$$d2E@E}u$EUEDEPUE BJEPEJU(E@EJEE;Eu E@EGE@E}u܋E@0 E@} tED$$xLEEU(JEE@;E} E u#ED$D$$tZE t#ED$D$$t-E t-ED$D$$u EEE@E}@EEUJEE@;E u UEBGE@E}uۋE tE @0 E @ED$$US$JEBEET$$uE@E T$$tE@E}u}uRE ET$D$$ED$$腘D;E $1E@t E@uED$$)E@f=*$4EE@@EE@@EE@EE $‹EPE@P0EP0JEPBJJEP,EJEXD$ D$D$/$D$ D$D$c$ҙE@E@P EBBAE@E@P EBBAE@@ @EPEB0EPE@@ BE@@&tED$$@Ö$[]U(JEaEET$$uE<:t0E@E@PEL$ T$D$$NE@E}uU($$eEEEE@ЋEP JJ)K‹EPAJu  t?E@EEt EEE`ED$ED$$cE@u/Et EEE`ED$$|kE@@‹E@D$T$$貇‹EPEPEPE@@tE@PE@@@@BJEP EP EPUE B }t E$KE KEJU($ёEUEUE BUEBUEB KʋEfPAK}t+}t%` D$ D$(D$$E‹EPJEPEJE EE'E@ E EE@$E}uE@$E}uӡ(LUUEE9E}UUE(LJUJE'E;EuEPB EB E@E}uӡJEJEUJEE@tlEE@ETE@ E:Ef,tEPEBmE@ PEBmE@$E}uE@$E}uE@E}wUS6 ufJJP K)É؉L$ D$D$$+2JP K)D$+$*JJP K)É؉L$D$$DL,}tED$$ $ JJP K)É؉L$D$$J@ ~J@ D$$$ }[]U(E@EE@ EE@ E@JEEET$$&JJ)=~D$$E@D$D$E$H$JED$ED$$J$wJP K)K‰UE@E}-EEU8E @EEJEEET$$$E @ tE @ @0 E @ @E@E'E@ E EE@$E}uE@$E}uӋE;EtCED$ED$$4D$Z$[rE@E}7U(EJE\E@;EuFED$v$6u+D$D$E$)E@E}u$fKKD$$nJEiED$v$tEEE@T$ D$D$$+E@D$+$E@ E}uJ@tvJEJ@ JE@E@ f KJE4EP K‹EPE@ u UEB E@ E}uU(EJEdED$E$uA}x2ED$$yE@D$ED$$\ E@EE@ E}uEU(t$u u $  JJ9EJJ) K)KD$$!lE JJJ$J@ JJu݋E$u Jt E1EZJ K)KUT$D$$4$t $t}t $tU(U %)ƀ KEEEE KEEJJ);EڡJJ);E%D$D$$ KVEEEU(EEE}%}}.}t} tHKED$$EEET$$@EE_E@$$NEHE@PE@0B0E@$EE@0$ EEEEUSdEeE1DžJPJ9|JJDž0tK9JJ)¡K9~D$$JJq‹ KCJ@ )JJ@ JJuDžJJJP )ЅyDžDžJ$bJJDžRJ@=LJPfUJ@t J@t>J@$T-u*JJ9J@fDŽEJJ@$ CJ@@$J@ J@$j;t  $u!t u "D$$uJ@D$$t $S$GJ@ D$D$$=J@@(t $$|DžJ@@$Džr$>f=uEKu Dž$9t  $u!t u D$$uJ@D$$t $$ D$D$$x$@)ы)Ѓ9|HD$$uJ@D$$$nAD$$uJ@D$$$+J@ JJJJ)Ѓ,Ju#JDžDž?$tD$$H)ȃ$$lD$$$u>)ȃu'D$$v $D$$Dž%t$EE@ $bEED$E$tpE@f=u#E D$ D$ED$E$u@EPEEPE@ȉT$E D$ $:MKEP$[]UJ}tKD$$D軿$J诿 KftJ@u$P苿&JP K)ȉD$$ScJD$$WJU u tJE@D$$6$ tOt E$_TU8E}tEt E@E KftIJt@J@u46 ;Et*}t$$tED$$^jE6 E $n}E@EEtE@EEoEt E@EEED$ ED$ED$$q$u0E@@uD$E$Ct $讽U(E@0 E@E@@ftEE@@f=t5E@@D$$TE@D$$kE@ xE@D$$jE@ PE@D$T$$$E}uE@D$$jEU8EE@0 E@E@ @ uE@ @$E*E@ @ $]E KE KE}y E,JJ)ȉEJE7mE;EE@ @ET$$tBUE)щʋE@ @T$D$$ϻED$$2hE@D$P$蠼u'E@tE@@E`ETJEEJE@ EEP$EP E@EE@$‹EPE$CEUEBUEB EJEEE@ E}UE)щʋE@ @T$D$$SE@D$$gg$tLJJ)ȃEJEME@ @ET$$]uED$ED$$;E@ Em}uEEUE6 ]US 6 E_ NE )É]iE)‰Ui]A 6 E_ NE )i6 6 6 6 6 []U}u E1E@$E}tEEE$EEUxEeE1t uDžB f=KtDž JD$$@D$D$$[T$$ f= u @$$e @$]DžDžDžDž0t|;us Luj$Lua@ uQK9|B$膷$$JJ)Ѓ~ $@$Dž|0Y;L L?$L2@ K9 $u& u$f=uBKu@0 DžsD$$"$u$ D$D$$a$ Ŵ@wutD$$聵0_K9L$L?@ + L;$tD$$D$$ $bD$$NDž;;~;~$t $ ݴDžu?t@ x Dž‰DžDžDž@$f=Ku@0 Dž0t(K9|$Lu@ t>@t@@$f=tf=@f=@Ku@0 Dž0t(K9|$Lu@ t>@t@@$;$`t0tLK9|=@ u- Lu$Lu $!ֱDžn@t@@$;Jf=tf=uz@@@P0P0$uDžl[f=uV@@@P0P0$|f.u9Ku@0@0$2@ @( $/ D$D$$ [$7@($[ĭf=tf=u@ D$D$$uZ$IO@c$ '[$L$LtZ@($|t $Lx$L$L@($Xt_$ZYt;@t,P@T$D$$i$ $L$L?@6$L$L.}`ctWc|YrwK> t2 t#!t :u JKt;$t@0 Dž;$t@0 DžUe3tU(}t EEEEE}t&EfruE@E$u EEJE$ EEU(wt EE@$E} |} ~ E-+w EE@$$%EE@ $D$oED$$bE@$$j‹E@ T$$ 4EEU(JE,E@D$$ȼt EE@ E}uEEUSD}E@0 E@E!E܁}+U܋ E@EE@ $EE@ $wىMyE@ $]҉U_E@ $CËE@$$3ډE.E@ $ËE@$$ЉUE@ $ËE@$$)ME@ $ËE@$$É]E@ $ËE@$$EЉډ}ЉU~E@ $bËE@$$R9EPE@ $4ËE@$$$9E"E@ $ËE@$$!‰UE@ $ËE@$$1ME@ $ËE@$$ ‰UE@ $ËE@$$x9EvE@ $ZËE@$$J9EHE@ $,ËE@$$9EE@ $ËE@$$9EE@ $uE@$$t EEMME@ $tE@$$t EEEEnE@ $RËE@$$BUBE@ $&ËE@$$EE@ $tE@$@ $EE@$@$$EUUE$EE$ED$E$聃EE$E{E$xEhE$ρEME$JE2E$虁Et EE@ $ EE@ $EE@ $E_EE$,E JMwuE$EEEEgE$老ETD$E$,E9E@ $E#wu UT$$EEUUwu UT$$EEMME$E,uBE@D$$z蔣E@ D$ D$D$$PEQ,u>E@D$$z=E@ D$$d$ EwuE@ $t ED$$O$ĢE@  D$D$$N$Ht$u Ep$4E[EREIED$$=t $آD$$OEED[]U+ultK9|TE @ @ftE @ @EE @ $ED$E$qD$+E$0zUHEE eE1@ @+mtK9QDž%\t"nt;tdD$D$$+%+$hD$D$$++$ڟ:%u.D$D$$+褟+$臟uD$$L@ $@$c&D$D$$̝6D$D$$觝D$+$+D$$軓D$+$蹞D$$+裞D$D$$D$D$$fD$D$$לDD$$KƅƅD$$+苞$薝;D$+$bv$+h=vD$$RKUe3tU(E}EE})}}r2}s}ct:}tv}:tm&E@ D$ $%t EW L LE$E L LEEEEE$CytnKt Ew L LE$)E L LwEEEE$xEqE$xt EYEfR L LE$E L LEfrEEEEEUS$}t Eu EwEE}tz}}.t_}@t-}}} t^JHJJ)É؃9EEKt EEE@$$EE@$EE@$t?E@$E%E$t E^E@E}uEFE@(E%E$t EE@E}uՋE$~EE$[]U(JJ)ȉEE$EEJ@;EuJD$$lWGJE@mE;Eu+JEEJE@$EEJE@ E}uEÐU}t/E@$E;D$D$ $1US$<u;$?,L;D$D$& $0L;D$D$7 $Θ;D$ D$D$$J 虘;D$ D$D$$Y t;D$ D$D$$l O;D$ D$D$$ *;D$ D$D$$ ;D$ D$D$$ ;D$ D$D$$ 軗;D$ D$D$$ 薗;D$ D$D$$my q;$袘;D$ D$D$$ ?JEEKJ9Et E E_;ED$ ED$D$ $E@EE}u;ED$D$ $Ж;D$ D$D$$ 蛖;D$ D$D$$ vJ$ ;D$ D$ D$$ D;D$ D$D$$$ JE<KP LE@؋ET$ L$\$$+E@E}uKL KD$ T$L$$) +;D$ D$D$$ <;D$D$0 $g;D$ D$D$$ ;D$ D$D$$X  ;$;D$ D$D$$l ۔;$Q;D$ @ D$D$$! ;D$ D$D$$ 8LD$$_#;$L ;D$ D$D$$o /;D$ D$D$$  ;D$ D$D$$  ;D$D$ $֓<t$$[]U(E<A;D$ D$D$$ q!;ED$D$ $bE(L9E|ա;D$ D$D$$ K;D$ D$D$$m ;D$ D$D$$H |Lfto;D$ D$(D$$ 蟒;D$ D$D$$ z;D$ D$D$$ U-JE!E@;E$.E@E}u١<;|LftJ;D$ D$(D$$ ֑;D$ D$D$$A 豑E;D$ D$ED$$ <u,K;D$ D$D$$ 'K;D$ D$D$$ ;D$ D$D$$ U(JE+EE@T$D$E$'E@E}uU(<E}tS}t}0 0 0  ;D$ D$T$ $;D$ ` D$D$$0 ;D$ D$D$$K0  ;D$ T$D$ $]O;D$ ` D$D$$6K;D$ D$D$$ JE$E@ЋET$$`E@E}u֡<E}tS}t}0 0 0  ;D$ Ԧ D$T$ $|0 ;D$ Ԧ D$D$$PK0  ;D$ Ԧ T$D$ $$;D$ D$D$$R 臎0 ;D$D$f $x'K;D$ Ԧ D$D$$;D$ D$D$$<uU;D$ D$D$$USEXeE10 tp0 9E u<!0 9E t< JlRDžhh h lL$T$$Xl@T$$l@Hh ;L$E D$ T$D$0 $މh ;D$ D$D$$ e8LD$$ ;D$ D$D$$l Fe4[]U(KE;ED$D$ $%e;ED$D$ $e;ED$D$ $d;ED$D$ $d;ED$D$ $d;ED$D$1 $d;ED$D$N $wd<u;ED$D$c $Pd{;ED$ ED$D$x $*d;ED$D$ $ d;ED$D$ $c;ED$D$ $c;D$ D$ D$$ cUHE@EEEE@EE@E0 9Euw<umE;D$ ED$D$ $Ec;ED$D$c $(c;D$ D$ D$$ bV0 9Et<>E@D$D$E$@E;ED$ ED$D$ $b0 9Eu;ED$D$ $xb4 9Eu;ED$D$! $QbE;D$ ED$D$ $+b;ED$ ED$D$x $b;ED$ ED$D$9 $a;ED$ ED$D$V $a|LfE;D$ ED$D$i $aE@ tj;D$ D$D$$ JaE@ ;D$D$$n;D$ D$D$$ a;D$ D$ D$$ `E@ t%;D$ D$ D$$ `;D$ D$D$$ `EEEZE@ E9Ef,u E@ EEE̋ẺEE@@E@@ t.E@0 E@E@D$$  ;ED$D$ $_E@@f=u[E@;D$ D$ED$$ltJE@0 E@E@D$$  ;E@T$$];E܉D$D$ $P_E@$EE}E@$E};D$ D$D$$ ^E;D$ED$ D$D$_$E؃}~x;D$ D$D$$ ^E;D$ED$ D$D$ $;D$ D$D$$my B^;D$ D$D$$ ^;ED$D$! $^;D$ D$D$$my ]E;D$ED$$;D$ D$ D$$ ]UEEEEMEEEt>Ef.uE@0t E@0EEf= u E@$EE;Et}Eu}}uD$$2  EU(EEE}E@;EEE}t(} }.tI}t;} tRuED$$QnEEET$$\ME@0u EEE@0E-E@$ED$E D$$ EEEhE tE@uEEIEEE} E}}uD$$2 A EEEU8E E@E}}*}}3},}tM}@}@}} }}aE@ t!E;D$D$N $Z)EPE ;T$ D$D$Y  $ZE8LDL}Ѕ~EDL}E)щʋE@9}$DL}E)щʡDLDLEPDLDLE@uUE@ uJE@ u9E;D$D$k $YE8LDLDLBE@ u+ tEPET$D$$| eYE@DLDLE;D$D$ $\YE8LE;D$D$ $0YE8LE;D$D$ $YE8LkE@8 ƒ8 ;T$D$ $>J=';D$ D$D$$ |>XJ=';D$ D$D$$$ I>%;D$ D$D$$A ">LD$ D$D$$\ =<u'LD$ D$$D$$t =%LD$ D$0D$$ =LD$ D$ D$$ͤ =LD$ D$D$$ۤ ]=LD$ D$D$$ 8=LD$ D$D$$ =U;D$ D$D$$$ <;D$ D$D$$7 <;D$ D$'D$$H <;D$ D$D$$p w<;D$ D$&D$$ R<;D$ D$D$$ -<;D$ D$&D$$ <;D$ D$D$$ ;;D$ D$&D$$ ;U8<@ D$ $J;;;<@ D$ $;;;<@ D$ $:;;tZ< @ D$ $:LLt-< @ D$ $:;;u$ T;$\;D$ D$ $: ;D$D$ $:;D$ D$ D$$ U:;D$ D$"D$$$ 0:;D$ D$D$$G  :;D$ D$D$$_ 9;D$ D$D$$f 9;D$ D$D$$ 9<tJ;D$ D$+D$$| m9;D$ D$D$$ H9;D$ D$D$$ #9;D$ D$D$$Ч 8;D$ D$D$$ 8;D$ D$D$$ 8;D$ D$D$$ 8;D$ D$D$$ j8;D$ D$D$$ E8;D$ D$D$$  8;D$ D$D$$ 7;D$ D$D$$ 7;D$ D$D$$ 7;D$ D$ D$$< 7;D$ D$D$$J g7;D$ D$D$$ B7<ud u[$LE$EEe E D$D$ ED$D$E$R<Ht$x A7$ 57;D$ D$D$$Ψ 6;D$ D$#D$$ [6;D$ D$D$$ 66jLfjL;D$D$ $6;D$D$ $5;D$ D$ D$$+ 5;D$ D$$D$$8 5;D$ D$D$$] s5;D$ D$D$$q N5;D$ D$ D$$z )5;D$ D$D$$ 5;D$ D$D$$ 4;D$ D$ D$$ 4;D$ D$ D$$ 4;D$ D$#D$$̩ p4;D$ D$D$$ K4;D$ D$D$$Ψ &4;D$ D$#D$$ 4;D$ D$D$$ 3t;D$D$ $3t;D$D$ $3Pt%;D$ D$D$$ ^3HtH;D$D$& $F3`Lt`L;D$D$; $3jLft"jL;D$D$ $2tLft"tL;D$D$R $2t%;D$ D$D$$i 2vLft"vL;D$D$y $f2;D$ D$D$$ 12 ft" ;D$D$ $2nLft%;D$ D$D$$ 1zLft"zL;D$D$Ϫ $1|Lft"|L;D$D$ $1pLft"pL;D$D$ $X1lLft"lL;D$D$ $*1nLfu$pLfulLfu jLfto;D$ D$D$$/ 0;D$ D$D$$A 0;D$ D$D$$ {0rLft"rL;D$D$U $]0 5 t%;D$ D$D$$h 0;D$ D$'D$$| /;D$ D$&D$$ /;D$ D$D$$˫ /;D$ D$(D$$ /;D$ D$D$$q f/;D$ D$D$$ A/;D$ D$&D$$ /;D$ D$D$$3 .;D$ D$D$$D .;D$ D$D$$q .;D$ D$D$$ .;D$ D$#D$$\ c.rLfu%;D$ D$D$$ 2.K;D$D$ $#.;D$ D$D$$ -;D$ D$D$$ -  $0 ;D$ D$%D$$Ĭ -0 ;D$D$ $v-0 ;D$D$ $W-;D$ D$D$$ "-  $(4 4 ;D$D$ $,4 ;D$D$ $, V<t ;D$ D$D$$ LD$ D$ D$$ LD$ D$D$$ ;D$ D$D$$ <;D$ D$D$$ɖ-<;D$ D$ D$$ȴ ;D$ D$ D$$ ;D$ D$D$$ ;D$ D$D$$ ;D$ D$!D$$@ o;D$ D$D$$d ^;D$ D$D$$ 9;D$ D$D$$ ^F$ 躑JuD$$ ~;D$ D$D$$ӵ ;D$ D$D$$ٵ ;D$ D$D$$ jJ$;D$ D$ D$$ 8J$;D$ D$D$$ ;D$ D$D$$w ;D$ D$D$$4;D$ D$D$$8 ;D$D$ $;D$ D$ D$$ S;D$ D$D$$$ .;D$ D$D$$  ,LG0L:;;D$$K证;D$ D$ D$$8 ;D$ D$ D$$\ ;D$ D$D$$ _;D$ D$D$$ :;D$ D$D$$ ;D$ D$D$$ȶ ;D$ D$D$$_ ;D$ D$D$$ ;D$ D$D$$ ;D$ D$D$$ \;D$ D$D$$ 7;D$ D$D$$5 ;D$ D$D$$Q ;D$ D$D$$m ;D$ D$D$$ ;D$ D$D$$ ~;D$ D$D$$ Y;D$ D$D$$߷ 4;D$ D$D$$ ;D$ D$ D$$ ;D$ D$D$$! ;D$ D$D$$ ;D$ D$D$$0 {貆;D$ D$D$$? Q蛃;D$ D$D$$ ';D$ D$D$$O ;D$ D$<D$$T ;D$ D$@D$$ ;D$ D$D$$߷ ;D$ D$D$$ո n;D$ D$D$$ I;D$ D$D$$ $;D$ D$D$$ ;D$ D$'D$$, ;D$ D$D$$T <t%;D$ D$D$$<t;$聡;$̖U}t0JE E;Eu E@EE@E}uEEU}~%;D$ D$ D$$j ;E D$D$v $E@ uNE@Dt;ED$D$z $%;D$ D$ D$$ k;UD$$} E@ t;ED$D$ $7;D$ D$D$$ U} tXzLft& ;U  L$$$v ;U  L$$PzLft# ;U L$$! ;U L$$U(E @EE @E;ED$D$ $%E;D$ D$D$$ D$E$;D$ D$D$$ǹ E}~%;D$ D$ D$$j uD$E$bE ;D$ ED$D$͹ $L}~;ED$D$ $);D$$)dEE;ET;D$ D$D$$ӹ }';D$ D$D$$۹ %;D$ D$D$$߹ }E}f;D$ D$D$$ JU(;ED$D$ $5E;D$ D$D$$ D$E$;D$ D$D$$ǹ zLftSE=EHU P L$ED$ E D$T$E$VEE@;EQE=EHU P L$ED$ E D$T$E$EE@;E;D$ D$D$$ӹ }';D$ D$D$$۹ %;D$ D$D$$߹ E}n;D$ D$D$$ bUeE1Džt;D$ D$D$$ ;D$ D$D$$ ;D$ D$D$$ ;D$ D$D$$0 ;D$ D$D$$D ;D$ D$D$$X d;D$ D$D$$m ?;D$ D$D$$ ;D$ D$D$$  ;D$ D$D$$  ;D$ D$D$$  ;D$ D$ D$$º  ;D$ D$D$$к a t Dž\  Dž\ ;\T$D$ $3 ;D$ D$D$$*  ;D$ D$D$$F  ;D$ D$ D$$Y  ;D$ D$D$$g  ;D$ D$0D$$x j ;D$ D$D$$ E ;D$ D$D$$  ;D$ D$D$$  DlKlxx@@x@D$[px@f@uKx@;tx@ttD$pD$x$x@f=D$D$ |$ x@ uMx@Dt"pD$D$һ |$W D$D$ |$W xD$|$Ml@ll;D$ D$+D$$ n ;D$ D$D$$ I ;D$ D$D$$# $ ;D$ D$D$$  ;D$ D$ D$$(  ;D$ D$D$$w  Ee3t US$E@;E@v;0 91<#;;D$D$4 $O EE@@ ; ;\$D$ T$D$P  $ ;;D$D$p $;;D$D$ $;;D$D$ $E@@tE@@@EE;;ML$ D$D$ļ $o0 ;D$D$ۼ $P;0 9tM<uC;;D$D$p $;;D$D$ $E@ fLEE@@ ; ;\$D$ T$D$P  $;0 9u;;D$D$ $u;4 9u;;D$D$ $GE@@tE@@@EE;;ML$ D$D$ļ $ELD$D$= $E;D$D$= $E; ;D$ T$D$P  $;;D$D$i $pE@@ ;D$D$ $M;4 9uJ;D$ D$D$$  ;D$ D$D$$ E@D$D$$.;4 9uJ;D$ D$D$$޽ ;D$ D$D$$޽ m;E@@ T$$˓$[]U}~REEw;Et:Ev9E| v)Љ‹EwAvU}trEEbE$V w$pw$cE@$EE$E@E}uE@;EtE@0E}uUvwwE$Qv~w wU}@EE}c}cp}+2}*}!}!E%}/}/}-}?}^}.4}+}H}~tp}~ }|tt}tV}!tw}?|n}H~I}Lt0Z v)Љ‹EvAv,E@ $E@ $E@$$vUE@t=E@@f=u-E@$t#E@$@ tE@$@ $ETE@t E@@u1E@t E@EE ED$$ ֯E@@EEUEEE}!tv}!}rtM}stN}@tdi},t/}, }+tL}-t }.t8EEEE@ $EE E EU ww}vvvvEfcu)E@ $~ w w>Evvtv$ wvtv$wUS4E@(tEf.bE@(EEE@‹ED$T$$r@EEP ;;ED$ED$T$ L$D$ $/; ;ED$ T$D$  $E@EE}aE@(EEqE@‹ED$T$$@;D$ ED$D$5 $ED$D$$H(E@EE}u;D$ D$D$$L 34[]UWVS $F  $_ $k $2 $> $u $ $ USDEEE@E@ƒEPE@t E$cEf= u#E@$ED$E D$$}E@$E@; ;D$ T$D$  $}E@ƒE@ ;T$ D$D$  $NEHE;L$D$$E@%tE@ƒEPE@Ћ ;ED$E D$ T$D$ȿ  $;D$$  5 u0EHE@;L$ D$D$ؿ $E@$EE@$`E$wEE@(tED$E$E@EEfcE@ f=/E@ @E@(u{;D$ D$D$$ E tJE@tE@EEث E@U؉T$D$$ BEE@t';D$ D$D$$ *%;D$ D$D$$# E@EP;ED$L$ T$D$ $EHE;L$D$$E@%tEE@BE@Ћ ;ED$E D$ T$D$ȿ  $Y;D$$ 5 u0EHE@;L$ D$D$ؿ $ }t%;D$ D$D$$ E@E}UE@$E$EED$E D$$tE@E}u^Ef=tEf=tEf=uED$E D$E$ED$E D$E$E@;EtE@0E}D[]UEEEEf=ED$$EEET$$;E@t/E@u"E@ƒEPE@ƒEPE@tXE@tKE@ƒEPE@ƒEP'E@$EE$E@E}uE@;EtE@0E}UEEE@ƒEPEf=tEf=tEf=uE@$E@$EE$E@E}uE@;EtE@0E}nU(}u EEw ƒwtD$$2 }EE}t }t@wED$$EEET$$AE$cE?E@0t/E@‹E@0D$T$$r$*EEEEEEU}uEE2E@0 E@wE$EEU(EE~E;E u E~E@%uUE@€EPE@$E3Et!EE D$$t E)E@E}uNjE@0E}xEEUS4EEE@%uE$t EEf=u{E@ unE$E}tZED$E$uDE@ EXE@;L$\$ D$D$H $EYE@$E#E$t E4E@E}u׋E@;EtE@0E}EE4[]UEE@$ENE@ f=/t6E@ f= uE@ @ $EE@ $uEE@$E}uEU(JEEP$ED$T$E$ED$$)8CED$$(EP ED$T$E$ED$ D$D$$j +EP$ED$T$E$SED$$)\BED$$(DEP ED$T$E$ ED$ D$D$$m EP$ED$T$E$ED$$),BED$$(EP ED$T$E$ED$ D$D$$p EP$ED$T$E$GED$$)PAED$$(8EP ED$T$E$ED$ D$D$$s EP$ED$T$E$ED$$) AED$$(EP ED$T$E$zED$ D$D$$v EP$ED$T$E$;ED$$)D@ED$$(,EP ED$T$E$ED$ D$D$$y 荿EP$ED$T$E$ED$$)辿@ED$$(覿EP ED$T$E$nED$ D$D$$| EP$ED$T$E$/ED$$)8?ED$$( EP ED$T$E$ED$ D$D$$ 聾EP$ED$T$E$ED$$)貾?<u%ED$ D$ D$$  #ED$ D$D$$ w>0 D$$ 蹽>E@uD$$ O t3 E@T$$su D$$ k t3 E@T$$7u D$$ jwtD$$$ jE@$1}D$D$J E$ E@ EELED$ D$D$$U żEP ED$T$E$E@$EE}uED$E$(L9E~AE@D$$X j'ED$ D$D$${ =E(L9E|ϋED$$)|<ED$ D$ D$$ EP ED$T$E$ED$$)%{<<u(ED$ D$D$$ 蓻I<ED$ D$%D$$ k!<ED$ D$ D$$ CEP ED$T$E$kED$ D$ D$$ ;fLf6w)xLfED$ D$D$$ 诺EP D$ ED$ T$D$ E$Q;EP D$ ED$ T$D$ E$%;ED$ D$ D$$ 4EP D$( ED$ T$D$ E$:EP D$1 ED$ T$D$; E$:ED$ D$ D$$F 蹹EP D$Q ED$ T$D$S E$[:C:fLf6w)xLfED$ D$D$$ 8EP D$ ED$ T$D$ E$9EP D$ ED$ T$D$ E$9ED$ D$ D$$ 轸EP D$( ED$ T$D$ E$_9EP D$1 ED$ T$D$; E$39ED$ D$ D$$F BEP D$Q ED$ T$D$Z E$88fLf6w)xLfED$ D$D$$ EP D$ ED$ T$D$ E$c8EP D$ ED$ T$D$ E$78ED$ D$ D$$ FEP D$( ED$ T$D$ E$7EP D$1 ED$ T$D$; E$7ED$ D$ D$$F ˶EP D$b ED$ T$D$h E$m7U7fLfwxLfED$ D$D$$ JEP D$( ED$ T$D$ E$6EP D$1 ED$ T$D$; E$6ED$ D$ D$$F ϵEP D$p ED$ T$D$s E$q6Y6fLfwxLfED$ D$D$$ NEP D$ ED$ T$D$ E$5EP D$1 ED$ T$D$ E$5ED$ D$ D$$F ӴEP D$} ED$ T$D$h E$u5]5;4 9ED$ D$'D$$ lEP D$ ED$ T$D$ E$5E@$EEE@ f=/tE@ f= ED$ D$D$$ EP D$U ED$ T$D$ E$4EP D$ ED$ T$D$S E$\4ED$D$ E$脳E@ f=/uEP ED$T$E$E@ P ED$T$E$lE@$EE}ED$ D$D$$ ED$ D$ D$$ ˲EP ;D$Q ED$ T$D$  $j3R3wtRtED$$1Ҳ(3EP D$Q ED$ T$D$ E$32xLfJED$ D$.D$$  EP D$3 ED$ T$D$; E$2EP D$H ED$ T$D$R E$2ED$ D$D$$w 莱tLft}E@urEP D$_ ED$ T$D$g E$2ED$ D$?D$$x (ED$ D$D$$w ED$ D$ D$$ ,L~0Lu E E ED$D$ E$趰EP D$ ED$ T$D$ E$H1t%ED$ D$"D$$ N6ED$ D$D$$ )D$ E$nLft#ED$ D$D$$ ,Lt50Lu,t#ED$ D$ D$$ 詯ED$ D$D$$ 膯ED$ D$D$$5 cED$ D$D$$P @EP D$e ED$ T$D$i E$/LfLE@$EED$ E$EP ED$T$E$ED$ D$D$$ 蝮E@$t#ED$ D$D$$ pE@$EE}jLfLED$ D$D$$# &ED$ D$ D$$ EP D$ ED$ T$D$ E$.E@D$D$ E$ʭE@$EELED$ D$D$$U 腭EP ED$T$E$E@$EE}u 9E~fLffLEP D$ ED$ T$D$  $-fLffL D$ED$$ D$ $ rZEE'ED$ D$D$${ 袬E 9E|ϋED$D$4 E$芬,LED$ D$D$$W J0Lt,EP D$: ED$ T$D$> E$,EP D$ ED$ T$D$J E$,wt#ED$ D$ D$$T 轫ED$ D$D$$u 蚫H,ED$ D$D$$y j ,;4 9ED$ D$'D$$ /EP D$ ED$ T$D$ E$+E@$EEE@ f=/tE@ f= ED$ D$D$$ 詪EP D$U ED$ T$D$ E$K+ED$D$ E$sE@ f=/uEP ED$T$E$|E@ P ED$T$E$[E@$EE}ED$ D$D$$ ݩED$ D$ D$$ 躩EP ;D$Q ED$ T$D$  $Y*A*wmED$ D$D$$ V,Lt#ED$ D$D$$ *EP D$Q ED$ T$D$S E$),LtcE@XEP D$ ED$ T$D$ E$)EP D$p ED$ T$D$ E$`)ED$$)ߨE@tE@E@$EEEEE@ f=/ED$ D$D$$ EP ED$T$E$=ED$ D$D$$ ֧EP D$U ED$ T$D$ E$x(ED$D$ E$蠧E@ f= ED$ D$D$$ UE@ P ED$T$E$zED$ D$D$$ EP D$U ED$ T$D$ E$'ED$D$ E$ݦEE@$EE}eED$ D$ D$$ 舦EP D$ ED$ T$D$ E$*'E@$EEE@ f=/uAED$ D$D$$ EP ED$T$E$=vE@ f= uDED$ D$D$$ ťE@ P ED$T$E$#ED$ D$D$$ 聥E@$EE}#'ED$ D$D$$ EE 9E|ϋED$$)脥ED$$)q%xLfED$ D$.D$$ ٤EP D$_ ED$ T$D$; E${%EP D$H ED$ T$D$ E$O%vLft-E@t#ED$ D$?D$$0 HED$ D$D$$w %ED$ D$ D$$ ,LqE@0LtrED$ D$D$$p 躣EP D$p ED$ T$D$ E$\$ED$ D$D$$u kED$ D$D$${ HED$ D$ D$$ %0Lt#ED$ D$D$$ ED$ D$D$$ ֢MED$ D$D$$p 订0Lu1EP D$ ED$ T$D$ E$G#EP D$p ED$ T$D$ E$#ED$ D$D$$ %EP D$ ED$ T$D$ E$"D$ E$ED$ D$D$$ áD$W E$x0Lt#ED$ D$D$$ 脡EP D$ ED$ T$D$ E$&"D$ E$ E@$EE+E@ f=/tE@ f= tEE@$E}uϋED$ D$ D$$ ߠE@tE@E@$EEE@ f=/ED$ D$D$$W {ED$ D$D$$p XEP ED$T$E$ED$ D$D$$ EP D$U ED$ T$D$ E$ ED$D$ E$D$ E$E@ f= ED$ D$D$$W 腟ED$ D$D$$p bE@ P ED$T$E$ED$ D$D$$  EP D$U ED$ T$D$ E$ED$D$ E$D$ E$E@$EE}\ED$ D$D$$ 舞EP D$ ED$ T$D$ E$*E@$EEE@ f=/uAED$ D$D$$ EP ED$T$E$=vE@ f= uDED$ D$D$$ ŝE@ P ED$T$E$#ED$ D$D$$ 聝E@$EE}#'ED$ D$D$$ EE 9E|ϋED$ D$D$$2 D$ E$wED$ D$D$$W ќ;t3j;D$D$ E$贜;;#ED$ D$D$$- rED$ D$D$$7 OnLft#ED$ D$D$$:  }u3E@~(ED$ D$D$$W wEED$ D$D$$W 谛}E@ED$ D$D$$T uEP D$l ED$ T$D$ E$ED$D$v E$?ED$ D$-D$$  E@$E+E@ f=/tE@ f= tEE@$E}uσ}E@$EEE@ f=/aE@ f= N;t3$;D$D$ E$Θ;;D$D$- E$ęE@ @tyE@ @D$v $uZED$E$EP D$ ED$ T$D$ E$ED$D$ E$qLfLED$E$蜙EP ED$T$E$ED$ D$D$$W MLfLE@$EE}u}E@$EE@ f=/E@ f= E@ @E@ @@f=E@ @@u{E@ @@ ujE@ @D$v $ctKE@$E:E@ PE@ @9uE@ @D$$ EE@$E}uE@$E}E@$EEuE@ f=/tE@ f= uE@$<ED$ D$D$$W 轗E@ f=/E@ f= E@ @E@ @D$v $KtqfdLLfLEP ED$T$E$vLfLfdLED$ D$D$$ EP D$U ED$ T$D$ E$ED$D$ E$E@$uE@ EEUT$D$ E$聖E@ f=/E@ f= E@ @E@ @D$v $sE@ f=2uE@ @@f@MED$ D$D$$ ΕED$ D$ D$$ 諕fdLdLffLfLfLLfLEP ED$T$E$fdLdLffLfLfLED$ D$D$$$ EP ED$T$E$>LfLED$ D$ D$$( ǔED$ D$D$$ 褔E@$EE}ED$ D$D$$W jED$ D$D$$ GED$ D$D$$5 $ED$ D$D$$P EP D$e ED$ T$D$3 E$LfLE@$EEE@ f= tTD$ E$螓EP ED$T$E$ED$ D$D$$ OUD$ E$JE@ P ED$T$E$_ED$ D$D$$ E@$t#ED$ D$D$$ ˒E@$EE}LfLED$ D$D$$# 聒ED$ D$ D$$ ^,L EP D$p ED$ T$D$> E$ED$ D$D$$P ED$ D$D$$` ߑED$ D$D$$p 輑ED$ D$D$$ 虑ED$ D$D$$ vED$ D$%D$$ SED$ D$ D$$ 0ED$ D$ D$$  ED$ D$D$$ ED$ D$D$$ ǐED$ D$D$$ 褐ED$ D$ D$$8 聐D$H E$~D$| E$kED$ D$%D$$ 8ED$ D$D$$ ED$ D$D$$ ED$ D$D$$ ϏED$ D$D$$ 謏ED$ D$D$$ 艏?fLf6w)xLfED$ D$D$$ 4EP D$ ED$ T$D$ E$ED$ D$ D$$ EP D$ ED$ T$D$ E$EP D$( ED$ T$D$ E$[EP D$1 ED$ T$D$; E$/ED$ D$ D$$F >,L~,EP D$ ED$ T$D$ E$E@$EEEE/E@ f=/tE@ f= tEE@$EE}uˋE@t E;EGEP D$ ED$ T$D$h E$HE@$EEE@ f=/tE@ f= ED$ D$D$$  EP D$U ED$ T$D$ E$ ED$D$ E$E@ f=/uEP ED$T$E$E@ P ED$T$E$E@$EE}ED$$)Č EP D$ ED$ T$D$* E$ E@$EEE@ f=/uAED$ D$D$$ EP ED$T$E$vE@ f= uDED$ D$D$$ 蜋E@ P ED$T$E$#ED$ D$D$$ XE@$EE}#'ED$ D$D$$ E 9E|ϋED$$)[ E@ D$E$:ED$ D$D$$1 辊EP ED$T$E$ED$ D$D$$8 D$ E$4" wuj<u%ED$ D$D$$? 1#ED$ D$D$$O  D$ E$ ED$ D$ D$$e щ E@ tbED$ D$D$$p 蟉EP ED$T$E$ED$ D$D$$t `E@$ ED$$(蟉E@$P ED$T$E$dED$ D$D$$y ED$$(JE@$P$ED$T$E$ED$ D$D$$ 計^ nLft#ED$ D$D$$~ tLfLw;;D$D$ E$薆;;ED$E$EP ED$T$E$/ED$ D$D$$W ȇbED$ D$D$$- 裇EP ED$T$E$˾ED$ D$D$$W dfdLEP ED$T$E$胾fdLED$ D$D$$ LfLEP$ED$T$E$+E@@f@u ED$ D$D$$ 视ED$ D$ D$$ 脆fdLdLffLfLfLLfLEP ED$T$E$yfdLdLffLfLfLED$ D$D$$$ EP ED$T$E$LfLED$ D$ D$$( 蠅ED$ D$D$$ }3nLft#ED$ D$D$$~ IE@D$D$ E$:E@ EHED$ D$D$$U EP ED$T$E$$E@$E}uED$$)tnLft#ED$ D$D$$~ 芄ED$ D$D$$ gE@ t1E@ @ft"E@ @D$D$X E$>EP ED$T$E$TED$$)]dLfuHE@t>E$.D$Q ED$ ED$D$ E$w_D$ ED$ ED$D$ E$I1ED$ED$E$j fLftE@ED$$蕁E$YD$D$X E$ED$$(VE@D$E$ED$$),E@tE@D$D$ E$讂nLft#ED$ D$D$$~ oE@t+wE@T$ D$D$E$D$$  wED$$ fED$ D$(D$$ ED$ D$)D$$ ED$ D$D$$ 蝁SnLft#ED$ D$D$$~ iED$ D$D$$ FEP ED$T$E$nED$ D$D$$U fdLdLffLED$$">EP ED$T$E$ED$ D$ D$$ 蟀fdLdLffL?;4 9u#ED$ D$D$$ RE$ ;4 9u(ED$ D$D$$ nLftFED$ D$D$$" ED$ D$D$$4 ED$ D$D$$T D$ E$KL$~$Ee3tU(E@EE@0 E@}uD$$D ,E@Dt#DtE@ftE$YE}u2E@ED$T$ E D$D$V E$~E@fuE$EE@fu5D$] E $3tED$$_ +Ef@ E@f=$uED$$x +E D$E$ ~fLfE@@LfE@Du2ED$ $~tED$q $v~u;D$D$һ E$}xED$v $?~EE@ u)}t#ED$ D$D$$ "}}u LfuD$$ *Lft@E@Dt6D$] E $}tE@DD$D$ E$|LftEED$$zE@E@ <hLft8D$$ )$ |$ |$@ |LfuD$n E$!|LfuVfLED$ D$D$$U {EP ED$T$E$fLOfLfu@E@ t"E@ f=/uE@ PE@9|E@ uQE@~GED$$[{EP ED$T$E$rED$$]{{ED$ D$D$$t zEP ED$T$E$ED$ D$D$$U zE@D$D$} E$z;E@ t1E@ f=/u E@ @tED$$ 'E@f=uFE@$tEnD$ D$D$$ mP ED$T$$D$$)m]D$ D$D$$ PmP ED$T$$CD$$)xmD$$(]mP ED$T$$D$$/%mP$ED$T$$D$$)loD$$(lP ED$T$$eD$$*lP$ED$T$$-D$$)blD$$(GlP ED$T$$D$$-lP$ED$T$$D$$)kYD$$(kP ED$T$$OD$$+kP$ED$T$$D$$)LkD$$(1kP ED$T$$D$ $jP$ED$T$$D$$)jCD$$(jP ED$T$$9D$$&njP$ED$T$$D$$)6jD$$(jP ED$T$$D$$^iP$ED$T$$vD$$)i-D$$(iP ED$T$$#D$$|XiP$ED$T$$D$$) iD$$(iP ED$T$$D$ D$D$$ ]hP$ED$T$$PD$$)hD$$(jhP ED$T$$D$ D$D$$ gP$ED$T$$D$$)glD$$(gP ED$T$$bD$$>gP$ED$T$$*D$$)_gD$$(DgP ED$T$$D$$< gP$ED$T$$D$$)fVD$$(fP ED$T$$LD$ D$D$$ fP$ED$T$$D$$)9fD$$(fP ED$T$$D$ D$D$$ veP$ED$T$$iD$$)e D$$(eP ED$T$$D$ D$D$$ dP$ED$T$$D$$)eD$$(dP ED$T$${D$ D$D$$ @dP$ED$T$$3D$$)hdD$$(MdP ED$T$$D$ D$D$$ cP$ED$T$$D$$)cOD$$(cP ED$T$$ED$ D$D$$  cP$ED$T$$D$$)2c@D$D$ $b@ |@ ;u$P ED$T$$y8D$$,bP ED$T$$?@$wD$$)Xb P D$ ED$ T$D$ $ P D$ ED$ T$D$ $Xl P D$ ED$ T$D$ $!5 P D$ ED$ T$D$ $ P D$ ED$ T$D$ $ @t Dž  Dž P D$ED$ T$D$ $W@$Dž~@$;tD$$,`@ D$$u"P ED$T$$@$u P D$ ED$ T$D$ $z@t& jt#t2VD$$?_>D$$<_&D$ D$D$$ _@$Dž~@$;tD$$,6_@ D$$`u"P ED$T$$@$u@G D$$>^, @t Dž  Dž P D$ED$ T$D$ $@$Dž~@$;tD$$, ^@ D$$6u"P ED$T$$@$uD$$]] D$ D$D$$ ]P ED$T$$D$$)/]D$ D$D$$ \P ED$T$$D$$)\ND$ D$D$$ A\#D$ D$ D$$ \P ED$T$$ D$$)>\D$$(#\P ED$T$$D$$)[m@ tnD$ D$D$$ S[P ED$T$$FD$ D$D$$  [@$D$$(D[@$P ED$T$$D$ D$D$$! ZD$$(Z@$P$ED$T$$sD$ D$D$$& 8ZP ED$T$$&D$ D$D$$* YP$ED$T$$@D$D$$oXDž@\u"uƄ'tmf=u(D$ D$D$$. X&D$ D$D$$5 XD$D$> $X@ GD$$,XP ED$T$$@@$uD$$)]XD$ D$D$$B WP ED$T$$D$$)W|D$ ED$ D$D$ $4HED$D$$O$@D$$U@D$D$J $WD$ D$D$$O VP ED$T$$D$$)VuD$ D$D$$W hVJ@D$D$_ $NV D$ D$D$$g VD$ D$D$$m UD$ D$D$$r UD$ D$D$$x UtD$ D$D$$ gUID$ D$ D$$ ;ED$D$ $OEP ;E D$T$ $-};D$D$ $N;~EE@$EE};+EEE@u ;~EE@$EEE@ E܁} }/E@ @t#E@ @D$ $NfdLEP ;E D$T$ $)fdL;D$ D$D$$ M;~;ED$D$ $M;D$ D$D$$ lM;~EE@$EE};+E;F;D$ D$D$$ MfdLEP ;E D$T$ $(fdL;D$ D$D$$ L;~/;;;;D$D$ $LEP$E D$$wEP E D$$`;D$ D$ D$$ +L9E D$E$F%ED$$# K$U}u EEE}}}A}.tS}ctT}tBE-w>3E@ D$ $2E(D$ E$EEEEU}u E_E;E u EHEP E D$$uEP$E D$$t EEEEEU}tyEf@t Ef= u7;D$ D$D$$ JE D$E$EP E D$$EP$E D$${US4eE1;D$ D$D$$J;D$D$ $ItLfD$D$ $H;D$ D$D$$ I;D$ D$D$$# ^I;D$ D$D$$5 9I;D$D$@ $%I;D$ D$D$$j HDžE;D$D$D$ D$D$p $H@ ;;D$ D$D$$ iH;D$ D$D$$ DHD$D$ $FDž0;T$ T$D$ $G@ ;@uq;D$ D$D$$ G;D$ D$D$$ |G;D$ D$ D$$ WG%;D$ D$D$$ 0G;D$ D$ D$$/  G@ ;D$ ` D$D$$BJD$D$ $E;D$D$ $F@u*;D$ D$D$$9 @F@ @;D$D$T $F;D$ D$D$$l E;D$ D$D$$ EDž[;D$ D$D$ $E;D$ D$D$ $iE@ ;;D$ D$D$$ ED$ D$ $D$}D;D$ D$D$$ DDž0;T$ T$D$ $D@ ;;D$ D$D$$ VD@ u%;D$D$ $8D;D$ D$D$$ CDžQ;D$ D$D$ $C;D$D$# $C@ ;;D$ D$D$$ kC;D$ D$ D$$/ FC@ p;D$ D$D$$}Ee3tDC4[]U}u EAEE}~}~}-}-3}&}%}!xE*r}R}R}/X}?N}c?}|5}^+b}.]}+} } }} t_}}!}H$}?}/tf}2t}Ltwf|LE@D$8 $BBu EE@@DEf|LEE@ $+EE@ $ElE@ $tE@$$t EEEE0$= @E$5$ y?EEÐU(ww;w9}!w;w$;"w;D$D$$'?www;E;E‹EE@$E}uU(}u E;EE}u'ED$$H ~?D$$^ /E@t EE@E@EsE:EUDE!E PE@9uEEPE@ E}uكE}~EE D$$u EE@E}uEEUE1;Et;E@Ew9E|UE @E}t=}u\Ef=:uNE@$f=/u=E@$@u.E,EfctEfrt EEEU(EE}t E@E}t E@E}E@E@(E@%Ef=Ef=Ef=Ef=Ef=twD$E$Ou`Ef=tTEf= tHEf=tE @ D$D$E$E @ D$D$E$E @$E&E@ D$D$E$ZE@$E}uE @ D$D$E$)E @$ErE@ f= u"E@ @ D$D$E$8E@ f=/t)E fRtE@ D$D$E$E@$E}uE @ D$D$E$E @$E @$@ D$D$E$VE @$@$D$D$E$6ED$E D$E$E @ @ D$D$E$D$E D$E$AE @$D$D$E$$7E PE T$D$$ ..D$$ U(JEE@С4 9E@С0 9E@$/XE@E}t} t(E@D$D$E$f@t/E@D$D$E$@D$E$4!E@E}+JEE@ui t]$ ,EPE@T$D$$ ,E D$D$$$ +E@ƒEPE@,E}ftu$-U(JD$D$ E${,E D$ D$D$$ H,JEEEE}rt }t!lE@D$D$ E $,ME@EEE}t}t}rtD$$ J딋E@,E}UE D$ D$D$$ m+E D$ D$D$$ =+E D$ D$D$$- +E D$ D$ D$$J *E D$ D$+D$$X *E D$ D$D$$ *E D$ D$$D$$ *E D$ D$$D$$ k*E D$ D$)D$$ H*E D$ D$#D$$ %*E D$ D$D$$@ *E D$ D$ D$$D )E D$ D$D$$ )U8EEE@E@ƒEPE@EEf= uE@$$uE@$E@$EuE$EE@EEfcu*E@ f=/uE@ @u E@(tED$ED$E$E@E}uE@$EE$E@E}uEf=tEf=tEf=u^E@EE$EEPE@0B0E@EED$ED$E$E$\-Ef=uCED$$9EE@D$D$E$EE@EAE@0t0E@‹E@0D$T$$EE@EEED$ED$E$ZE@(txEf=tjEf.t\E@(EKE$EE@ED$ED$E$E$9E@E}uE@;EtE@0E}UJE-E@;EuED$$P r&E@ E}uUED$E$y DžLEPD$E $y DžL UE9} DžL DžLLUJEGEt5Ef=tEf=tEf=u E$#E@,E}uU KftJt J@t EEEUWVSeE1@tJ@$$=w@D$p$#p@D$$V W(t-( T$ D$D$k p$>#! D$D$v p$#D$ p$E$wwMp$$ƄpD$ p$$ww  D$.$"\\\(t-( T$ D$D$k p$K"! D$D$v p$("\.D$ p$I#wwuUp$#ƄpD$ p$ #wwu$ #$ڼ$u> pD$$t! pD$T$$ "J Ku;$3D Ku# 5 D$$_ KuKx u D$ $T D$ $: ~5K9|&$ "D$$ !4 Kft ;J`"`Pd9t`@,``uՃ`u=d; K)É؋KL$ D$T$$ M!JJ)Kl`f@4lP;9J@ JJJu D$@ $d Kft#;uKD$$G  ; K)ȋKD$T$$^ T l;^KD$$w , `ȋd; K)‰L$\$ lD$T$$ s$u+ t;D$lD$$ JJ!l;9ltJ@ JJu֡J* d; K)É؋KL$ D$T$$ " KKȋJ5JJJ)K|$L$\$ t$D$$ $ nJJ2JJ@T$D$$ J@ JJu$ k;KD$T$$ GJ`B`@0 `@`f=`TT$dXXK9 utvD$T$^Tf=uT@T$. AT D$D$$9$1 tt J$h$t $ XTXt`@0;XJJHXt&D$D$X$蠿L XLLHYw`@t`@h`@ hJtNJ`$bCJ@t+JJPhD$D$$CK9 usD$`$\`f=u`@`$. -` D$D$$%$]hta tUJtJ@tJ@@P DžP`@ PT$D$$3 $ tet J$ޯ$t $ JJt1J@u%J`B$G Džhht;Jt2J@t&J@@;htJ@` KfJJ@``P$ 9`@$ u7$ D$D$Z p$pD$$C$ D$$` ` D$D$$ $1 wdT$D$ ;D$KD$ $KD$$ $M}.}}}sN}t7}E@ED$T$E$1EED$ED$E$EE@0f=uEP0ED$T$E$EQ}Et#ED$ D$D$$ ;0 9t(ED$ D$D$$ ED$ D$D$$ }Et#ED$ D$D$$ MED$$(wEPET$D$E$VHED$$)_w1}Et#ED$ D$D$$ ED$$( wEPET$D$E$GED$$)w}Et#ED$ D$D$$ /ED$$(|w;0 9t#ED$ D$D$$ EPET$D$E$GED$$)w}Et#ED$ D$D$$ nED$$(w;0 9t#ED$ D$D$$. E PE@ T$D$E$BF;0 9tED$$)<ED$$))wE@E}EUEEE EEEeE1E;= E$-EE}sF}s8}R4}R}.E}c}r,}}}q}} t}:D$$H qE@ED$ED$D$ ED$T$E$E$E@ED$ED$D$ D$T$E$JED$ D$D$$i  ED$D$E$uED$$13 ED$ D$D$$p  EE@0f=ED$ D$D$$i j E@0D$D$E$ uED$$1 ED$ D$D$$p  E&ED$ D$D$$i  wEPET$D$E$BED$ D$D$$p  wED$ D$D$$i a wEPET$D$E$yBED$ D$D$$p  w$ED$ D$D$$  ;0 9t#ED$ D$D$$  ED$ D$D$$  wEPET$D$E$AED$ D$D$$p < wNED$ D$D$$i  ;0 9t#ED$ D$ D$$  wEPE@ T$D$E$@ED$ D$D$$p  wED$ D$D$$ T <t#ED$ D$D$$ ' ED$ D$D$$  #ED$ D$ D$$ }t EED$ D$D$$ ;ED$ T$D$ E$;D$D$ E$z;D$D$' E$^ED$D$@ E$E;EPEED$ED$ T$L$E$}E@$tRE@t E@ u8E@D$D$g E$E@ƒEPwE@D$$E0 E@E$E@$'wUEUe3tUSEEE EEEEEeE1EEE@E@ƒEPE@ u=wE@D$D$z E$E@$lVE@D$D$ E$|wE@D$$E@$4E$Exxxx.xtTxE@EEP0EHED$T$ L$D$E$lwE@0t}E@‹E@0D$T$$p$6@EED$D$ E$CED$ D$D$$ E$U}tSE@D$D$ E$ED$ D$ D$$ E@$D$$ 8wE@ËED$$OD$\$$e@EED$D$ E$@ED$ D$ D$$  E$RwEE@07E@0@#E@0tE@0@| Dž||EED$D$ E$ED$ D$ D$$ cE$6E@$ȎwEwED$ D$D$$ EPET$D$E$6:ED$ D$D$$ wwEEwwwE@0tE@0@EEEEE@0E@0@wED$D$ E$MED$ D$ D$$( E$E@$EEEPED$ T$D$3 E$AwwwE;EtEf=t E@0EEEEEEHED$ED$ L$T$E$(wwED$D$B E$;wE@EE}wuwED$ D$D$$O Et E@EEwƒwED$ T$D$h E$wE;EuEe3trĤ[]ÐU<uD$$ 蚭E@E<T$$uED$$ 耬FE@E}u$ dE<EUEBEPEU(} E @D$E$E D$D$ E$9E @E1E@ EE@$tE@$E}uE@$E}uɋED$ D$D$$ UD$E$E@t+E@EE D$ T$ED$ $E@E}uE@$E}uE@E}uU(DEEE}E@DEE@DT$$quwE@xmE@f@u`E@4f=2uQD$ D$D$$腅EUEBE$E@4D$$/E@E}7U(EE$ E@EE@ EEf,tEE E@ EEE$@uK$[EUEEP E죀|EED$$E@$E}qE@$E}PU}tAE$Z@uD$E$E@$$E@ $UEE@$E EE@$E}uEUEE@$E(EE PE@ @9uEEE@$E}uEEU(}u} u E}t} u EE@EE @E}t}u E}tEPDE@D9t EEPE@f9t EvEET$$t ESE@f=u?E@$t5E @$t+E @$P E@$@ D$T$$EEEU(E3ED$ED$$t E|DE@ E}u$赀EUEEP E|U8E@EE@EmE@ELE$@-E@E$E@E܃}rt%}:E@@$$EE$+EE@$EE;EuTEPET$$&EEE@T$$ EE;EuE@D$$E@E}n2E@D$$T @D$$_ ~E@ E}E@E}E@$E}hU(EW$x EPED$T$$7$ E@EE@u$ !EPED$T$$$<PE@t $ 7E@t $ E@t $ E$t E E ED$$ $>E@ t $ E@ E}$ E@ E}$ qU(E @u ‹E fPE f@ E @ED$$ E @ D$D$$zED$$ }t-$ EPED$T$$#$ E @EE;EtsE@ tf tCE@D$$ LEPED$T$$$ EPET$$E@ E}rU(Ef=]E @EEE$*@EE;EE@ED$ED$$Et&ED$ D$ E D$E$}EEED$T$$ttE@E]ED$ED$$t4E$t#ED$ D$  E D$E$NE@ E}u}uE@ E}WE@ E}U(}E$@E tBED$$ 2E@D$D$E$$3 lE9E@u!ED$ ED$ED$$6 E@E}upE9E@u!ED$ ED$ED$$? E@E}uxEED$F $QED$N $0ED$V $tiE@EXE@E>E@u&EED$ ED$ED$$E@E}uE@$E}uE@E}%U(lE EEE@E@EE@@fE@@DtuE@@DED$$uU t@ED$$` EPED$T$$P$ EXE@ E}TE@E} l9Eu pEEEE}EEUErxEuE@ƒU*E@E}uD$$ tEEU}u E[Ef= uE@$dE:E@ $uE@$$t EEEEEU(xEED$F $ZtWED$N $=t:ED$V $ tED$ $uE@ƒEPE$NtE@ƒEPWE@E/E@EE@fuE@E}uE@$E}u˃}tE@ƒEPE@E}xEE@EiE@EOE@t}u E E EU܉T$D$$ 轶E E#}uED$$0 薶ME@E}Et$T $  Et$T $ Et $ նU(EoE@ftiE@EE+EED$T$$uE@E}uσ}uUBEEE}uEU(E6ED$ED$$0t E@;E tOE@E}u$ 'cEUEE ‹EfPEf@EPEU(EuEf@ tJ$ մEPED$T$$:E$D$$1 藴E$ E@E}uU(;E EE@EE@t EE@E@tzE@-E}M%ED$E$Wtl‹EfPE@ƒEfPE\ED$E$t*‹EfPE@ƒEfPEE@E}EEU(;E EE@EE@E@tsE@tgE@-E}w(M%tED$E$k‹EfPE@ƒEfP5ED$E$4‹EfPE@ƒEfPE@E}(U(E2ED$ED$$t EXE@E}uȡE2ED$ED$$t EE@E}uEEU}u ESE$@u E:E@ $uE@$$t EEEEEU}tE@tE@$mu E;E@E#E$t EE@ E}uEEU(;E EE@EE@E@E@-E}w*M%tED$E$vwE@D$$E$tP$< E@ D$D$$[$ ׮ED$E$E@E}U(;E EE@E@E@ E@EE@uED$E$t^E@  t[E@D$$e  E@ D$D$$[$ ߭E@E}hE@ U( tED$$w 藮E@EE@E@EE@E@E@E}s}r}}ct p}ug‹EfPE@ƒEfP t:$ E@ D$D$$Y$ 跬E@E}:E@$E}E@E(;E‹EE@E@$E}uҋE@EED$E$E@EE@toE@ƒEfP tP$ E@t.E@t"E@ D$D$$X$ 被E@E}oE@$E}2E@EyEE@EE@t]E@tQE@-E}wTM%t@ED$E$t(EED$E$jtE}uE@E}a}E@E‹EfPE@ƒEfP tP$ iE@t.E@t"E@ D$D$$KW$ %ED$E$E@E}\E@$E}}E@EHE@E.E@tED$E$E@E}űE@$E}uUxEkED$F $gtEED$N $Jt(ED$V $-t E$\E@E}uUxEED$F $ED$N $ED$V $蟪tnE@E]E@ECE@t0E@t$E@f=uE@ƒEfPE@E}uE@$E}uE@E} UVjN tD$T$$ 賨t uUxEE$CE@E}uxEE$pE@E}uxEE$E@E}u6 tUEuD$$ TExxEE$E@E}u}t  tZExE(E$E@tEE@E}uu}t $ ܧc tUED$F $ED$N $اteED$V $轧tJ$ TEUEUE BE@;EPxEPEx;U$ED$V $DEEE}E@DEE@DT$$ˢuuE@xkE@f=t^E@4tTE@4f@tED$ D$D$0$PEUEBE@4D$E$E@E}7E@E}U($ ȡlE EEE@E@ft E- E/ ED$$ àE@D$$1 諠E@EL$5 蔠EPED$T$$E@D$$8 ]E@ E}u$ BE@E}/$? Ӡl9Eu pEEEE}$B 蜠U^tltttptU(E@t E@t EE@t EE@ƒEP t&EPET$ E D$L$$F +E@t; tED$$S E@ƒEPEQE;E t@E@E/;EE D$$uE@E}uEEUE;E tdE@tZE@uME@ƒEPE@E+;EE D$$E@E}uUE@EE;E u E@;EtDE@E}u$ KEUE UEBEPEPUEBU(E@E t!EE@T$D$$e jEPET$$uD t!EE@T$D$$z "EPET$$~E@E}aU(;EEE EE EE@E tAEEM!ЅЋEE T$ L$D$$ pEEM!ЅtE D$ED$E$#U8E@EHE@1E@ EE";E@EE@E}u؃}EE;E;E@EEEEEPEM!Ѕtq;E@EE";E@EE@E}u؃}~#E@tED$ED$E$EE@;EE@$E}U(E@EE@E@$E}uE@D$D$E$KU(E@EE@tE@tsE@-E} wWMUE%uEt1EB;E$pt EE@E}dEEU(E@ E;EEE@ttE@tjE@t^E@E}t#} }t0E-w# E2E$et EE@E}YEEUH tED$$ ٘E@EnE@WE@FEEEEEEEE@E;EEE@ EE@EE@tZE@tNE@E܃}s}r}*}ct$)}t }uE$y EEE@E}\}u}u}u }~c}u]E$uNE@ƒEP t1EED$ED$ED$ ED$T$$ fE@$E}USE@EE@oE@ $E‹EPEE@9u7E@EE@EEPE‹MEEPEEE@ ;E܋E@tdE@EPEHE@ ¸)؍EHE@ ¸)؍M!ЉE}~E^;E@uBEEEEEPEEPEM!ЉEE@;EE@$E}p[]US$EEP $9~ E@ $$$YC(E(EEE@ ;E܋E @ Ev;EEE@tME9(E(EEPE!ȉEE@ ;EE@E}uE EE E(E(EM ЉEPE PE(E9t&EE PE (EEE@ ;EE$[]UE$EE@E7E@t$EE@9tED$E$EE@$E}uÃ}u;E@D$E$US4/xEE@E@E7E@PEP;E‹EE@E@$E}uE.;Eu;E@EE@;ENjE@‹EP  tdEPET$D$$ 耒E@ƒEH ;E@T$D$ L$ \$D$$ ?E$dE$%E$E@E=E@ EEPEP UEBEPEPE@E@$E}uE@E졠;@t E@E$E$aE$E@E'E@ EEPEP UEBE@$E}uӋUEBE@E}(xEE@E/;E‹EE@ƒEPE@$E}uE.;Eu;E@EE@;ENjE$E@E'E@ EEPEP UEBE@$E}uӋE$E@E'E@ EEPEP UEBE@$E}uӋE@E}4[]ÐUE$ E( 9E|UEE}t0}t }t($ G$ 9 $' +( ( E@$ ( ( F$* U(EE$D$E$蛡E}tED$$. Ef= uZ$3 莏E@$$B kE@@$j$M EwE@$&EE}t)}u>Y$a ( ( 9$d ( ( E@$EM( ( ( ( $g 螎E$$ ՌE@E}uEE}t0}( ( $j 4f( ( i$n CEf=tEf=tEf=uE$N Ef.Ef@Ef=Ef=u=$r ͌E@ D$ D$D$$EfcuJE@ f=u9$z qE@ @ D$$$ +E D$D$$?8$ ɌE@;EtE@0E}U}E@tE@$E@t $D躊ED$$ 裋E@ t,$ 荋E@  D$D$$7$ E@$$ UJ$9U(EE}X}%}}}(tH<}  } }tQ} }  E)t $ j <E )‹EPE$]E EEf=xEf= hEf= uE@f=IE@ ED$D$$tiUT$D$$ ]iE jEEf= D$ED$$ iE %EEf= Ef=Ef= uE@f= tsEf= u E@ ED$D$$ hUT$D$$ {hE&<E% <E }u $ }EUS$} E-E}  U E@ f= tE@ f=tE@f=uE@ ES EP E@T$$ltE@ E) E@f= u3EP E@@T$$ktE@P EPE@ f= u E@ @f= uE@ EE@ f= E@f= E@ PE@@T$D$$ fD$D$$ fELE@ f=tE@ f= tE@f= uE@ EEP E@T$$jtE@ EE@f=u#E@ f= uE@ P EP E@ f= E@ @f=D$D$$e‹EPE@ P EP TEP E@T$$ jt$D$D$$ eEEX E@D$D$$ee$~X\$D$$IeEE$CW$WEEP E@T$$kit$D$D$$ dEvE@ $reËE@$be\$D$$d$V$[WEE@ D$D$$d$WËE@D$D$$`d$yW\$D$$Dd$DV$VEED$ED$$dEE$V$VEE@ f= u-EPE@ @ T$$'htE@EHE@f= u-EP E@@ T$$gtE@ E E@ f= u-EPE@ @ T$$gtE@ EE@f= u-EP E@@ T$$sgtE@EE@ f= u|E@f= umE@P E@ @ T$$%gtKE@X E@ PE@@T$D$$b\$D$$ bE E@ f= u~E@f= uoE@PE@ @T$$ftME@ P E@@ T$D$$b‹E@ @T$D$$ aE|E@ f= uUE@f= uFE@PE@ @T$D$$aD$D$$ aEEP E@T$$euE@ f=tE@f= uE@ EE@ f= tE@f=uE@EE@ f= E@f= ~E@ P E@@ T$$-eXE@EJE@ f= u-EPE@ @ T$$dtE@ EE@ f= u-EPE@ @ T$$dtE@EE@ f= u~E@f= uoE@PE@ @T$$cdtME@ P E@@ T$D$$_‹E@ @T$D$$ _EEEP E@T$$cuE@ f=tE@f= uE@EE@ f= tE@f=uE@ EE@ f= uyE@f= ujE@ P E@@ T$$bctHE@ X E@ PE@@T$D$$^\$D$$ ^EIE@ f= u:E@f= u+E@ P E@@ T$$bt E@ EE$[]U(E}y xEE$EEqEUЋ@ 9uRE$EUЋ@ L$ED$$]EE$E늃E}~}u $ EEEUO$UEt#$ }E$ $ |t$ o E$0UEEUEUEEEE$E Ѕu׋Eƀ?UHeE1UE؋E;EuU U8EأED$D$ E܉$O{E܉$EE̋E̋Ue3t }UkEEUEE+EUEE}{u $ .}}t}t }~EƀUS$rEE}-D$D$$;[<E;D} t}{uG;D$D$$ P[<<$ CE }}u $- W zE%D$E$D$$< #|u-D$D$$ Z<E eD$$A {u-D$D$$jZ<E D$D$$ =Z<<$CE }<E}>u-D$D$$Y<E}-tI$G  fE}>u-D$D$$Y<EG$^  E!E}[Up D$/D$$\yED$\D$$/UED$&D$$&1ED$|D$$| EdD$[D$$]ECD$-D$$>E"EE E E D$D$E$DX<EEE$[]U(E$EEE)EED$$MyuEErE@E}u$zFEE$w$aF‹EEED$$wEEPUEEEEU$ FEEEEÐU9}҉UEEUEE*E<(uEE<)umE9E|̃}t$ U<D$$TuU塼~ ]UD$$ vD$$ vUGU($)УBE E}ft9}f }dt}n}vmE ETE E< t*E E<"tE E< uE E EE E;EE D$$[u$u>/#E D$$* u*mE }~E <-u0$@ u$a u$| |u$uautU}EE}}D}}}q}}{t} '} } } ?} b}  <D$$(;tE@$<D$ D$D$$ sE@ $<D$$)s<D$$(sE@$<D$ D$D$$ 8sE@ $r<D$$)us[<D$$([sE@$5<D$ D$D$$ rE@ $<D$$)s<D$$(rE@$<D$ D$D$$ XrE@ $<D$$)r{<D$$X{r<D$ D$D$$ qE@$0<D$$)3r<D$$!r<D$ D$D$$ qE@$<D$$)q<D$ D$D$$ Gq<D$ D$D$$ qfE@<D$D$ $ qB<D$ D$D$$ p$ pE$UEE}}Q}}};S}O}}} } }}u} } } $ o$ o$ o$ o$ so$ bo{$ Tom$!Fn_$U8nQ$V*nC$Xn5$ o'$ o$ n E$mU$ n} tE D$E$n E$nt.t%$  n$$'tmD$$ `nE$-KmE9E|$, n $mUD$E$UE D$E$$nU$0 mE@E E$$8 mE@E}u$; mE@E E$$8 cmE@E}u$C HmE@ E E$$8 &mE@E}u$K  mE@E E$]$8 lE@E}u$ kU}EEtQED$$U lE@EED$$e elE@E}u܋E$w9~ UE}tEEU ƒ T$D$j $RjU8EE}t}t`E@D$E D$E$t)E@ D$E D$E$t EEEEE@D$E D$E$bu E@ D$E D$E$Bt EEEEUE @E=E$<EED$ED$E$@Rt EE@E}uEEUS$E$)<EEhE@tRED$ED$$t4E١‹ETdQEEE}uEf= uE@ En$[]US$E$|;EEE@t~ED$ED$$t`E<>vD$$n tE١‹ET$QEEE}b$[]U}tsE-E} w^U E@$BE$E@ $*E@$E@ $U(E.EED$$miuEEhEE}u̡E,EED$$1iu E@E)E@E}u΋ED$$ hEEUE $PE}t+E$K$EEPEPUEBUEE}t} t }t EECE@ $tE@$t EEEEEEU(EE}u EEE$HGEE$8$O9EEf= tEf=t Ef=uB}u%<D$ D$D$$ fE$EEf=u}u%<D$ D$D$$ mf<D$ D$D$$ HfEPD$E D$$E}u'<D$ D$D$$ eCE@$ t1<D$ D$D$$ eE3EP D$E D$$LE}tEE@ $t<D$$1e<D$$0eE<D$ D$D$$ (eEf= uBEP E D$T$$kLu!EP ED$E D$$EJEf=u>EPED$E D$$^EEP ED$E D$$?EEEEUEE EEE UEDd;Eu EEE;E΃}tEEE UED$;Eu EEE;E΃}uEE9E[EU(Et u D$D$ E$c9E |D$D$ E$bfE D$E$EU E9|D$D$ E$bUE ЉD$D$ E$baEUSEhEdeE1h@u@D$D$$)BD$  D$dD$h$-h@pmp$tt;t@tMtD$E D$x$XpD$ xD$D$ x$Z`D$ D$ x$ZaxD$dD$ E D$T$$ lat@$Ћtȋt@d؋tT$L$ \$D$$, atPxD$ T$dD$h$+p@ppEe3t*aĴ[]UheE1EEE@}t(ED$L $\au 9Eu8ED$L $*atD$D$Q E$_ED$D$Y E$^ED$E$y`ED$ED$E$EE}#E9E+Ee3t_UEEE]EE#EET$$M`tE@E}u׃}uE$_EUEBEEE@E}uEU(EEtEE EVEET$$_tEE+E@EE$2/}t UEBEE E@E}uE@E}u}uE ES} uEEEE @uU EBE E*EE E@EE@uUE BEEEU(E$L xD$D$ D$D$$EEUEBEPEPEEYE@E2E@EEET$$vE$-EE}uȋE@EE}uU(EEEBE$V=E}tED$ED$$<EEEE@E}u}uEEE$s.$/EEEEUEEEE:E$<E}tEUPEE EEEEE@E}uEU$*E}t UE/$‹E} tE $~‹EP}tE$‹EP}tE$#‹EP}tE$~‹EP E$UE-E} Up E@D$$@[D$^ $@[@D$` $@[*D$b $@[D$d $@[E@ $TE@$FlD$f $@n[D$h $@X[D$j $@B[*D$l $@,[D$n $@[U}u E8Ef= u E@E!@E$$@EEUHE@$EEPEPUEBE@$t‹EP E@ $EE$P‹EPt E$t1E@ t E@ EE̠ ẺD$$ nYt1E@t E@EEР EЉD$$ 4YEtED$$ Yt1E@ t E@ EEԠ EԉD$$ XtED$$ Xt1E@t E@EEؠ E؉D$$ sXEP E@ 9uEPE@9t&t $ XEEt $  XE@t EPE@T$$‹EPE@EbE@EED$E$;uE@E}uۃ}u#E$7EEPEPUEBE@E}u$ %EEEUEBEPEE@E"E@EED$$i6EE}u؋E@E"E@EED$$66EE}u؋E@ E"E@EED$$6EE}uE}mt tED$$ aVE@E2t E$t $8 -VE@E}uȡtD$$" Vt EEEEUSDE@tED$$+ Ut E$E$Gt$9 UE@ t $E $UE@ E2t E$mt $8 TE@E}uȡt $Q |UEX E$D$D$ \$D$$MtxED$$S pTE@EED$$e PTE@E}u$e 5TtE@$E$;E@f=E@@t0E@@ E E@EE@uE@PEPE@@EEE E@EE@uE@P EPE@D$$2UEBE$EE@EE@PEPE@Ef= t[E@tHE@E(ED$E$7t E'E@EE@u΋UEB UEBE-E؃}U؋ E$ED$$1E$}tED$$1E$E@ u#E$D$$p "E@u#E$pD$$p E@ @t#E$@D$$p E@@t#E$D$$p E@ EEPEP}tEEE$D1EEP EPE@EE@ $1‹EPEPE@BE$‹EPE$:EPEHED$T$ ED$L$$E@ @t#E$$D$$p E@@t#E$D$$p yE@E}tEEE$40EEP EPE@ EEPEPE@u#E$|D$$p E@$.0EEP EPUEB }tED$$ /E$E@ @t#E$D$$p E@@t#E$D$$p RE@EE@ EE@ EEPEPEPEPEPEHED$T$ ED$L$$E$‹EP}tED$$ .E$D[]US4}u EEE-E} wnMUE%AuE% u0DE@$‹EPE@ $‹EP E@$m‹EPEf=E@f= E@@f=E@ f= urE@ @f=u`E@ P E@@ T$D$$?-D$D$$!-\$D$$  -EEf=E@f= E@@f= u~E@ f= uoE@ @f= u]E@ P E@@ T$D$$,D$D$$ k,\$D$$ W,EEEMME4[]U(}E$Eu tU<D$ D$ D$$ OLE$<D$ D$D$$ LE$(,E$L T$D$D$ ED$T$$_EE$E}u١E$QE$&$?tW$ KD$$ $KD$$ KD$$  J$ KUE ET$$Kt EE PE@T$$.EEU}RE-E} 9MUE% uE@uEMME@$‹EPE@u"E@ D$$I)EE@ $C‹EP E@ u"E@D$$)EEEE@$‹EPE@uE@ $EME@ $‹EP E@ u E@E"UUED$$w(EEUhEEeE1@E.EED$$Iu UUE@E}uD$$ E$ID$D$/ E$sItfEEE<_t E}?~}?~ED$$6 \EED$D$G E$FE$EEEUe3t~HU}E@E@E@ tED$$P GE@EXE@uEE$$Du%ED$$ $xHu DE@E}uU(E $EtE D$ED$$j "G@EhEED$$Hu E@ u1EET$$>uEE@_EET$$W>u.ED$$ $<>uEE@E@E}$}NE@E}E @EE@E@EE@EE@EPE@T$$ EET$$n=u1E ET$$P=uEE@_EET$$=u.ED$$ $=uEE@E@E}$}tE@E}EE @EE@E@E}uEUxeE1EEE@EE@vE@ gE@EOE@7E@ (ED$E$Et"EET$D$$ :E@ tIE@ u>ED$ $;uEEEEE@ EEEE EEEEEET$$ED$D$/ $;uUuLED$D$  E$8ED$E$E@E}E@E}h}t } @EUe3t:UxeE1Et EEE@Ec}tE@EE@ 6E@E}tE@E@ ED$E$tEtKEET$ D$ED$$ 8E$$. N9E$EET$$ ED$D$/ $:9uUuLED$D$  E$6ED$E$E@E}E@E}}t } kEEEUe3t18U}E@$E@t <D$ D$D$$1 7EPE@D$T$$t<D$$17E<D$D$7 $;7HHU}uE@yE@E<D$D$E $6t[<D$ D$D$$J 6E@@$<D$ D$D$$O h6ED$D$/ $ 7u-u$E<D$D$T $(6<D$ D$D$$[ 5HE@$Hu%<D$ D$ D$$` 5<D$ D$D$$k 5U($EE$赼‹EE$h$‹EPtOE D$$q 4E$X$y 4E@$>ED$$| 4E@tE@$[$‹EP@E:EE D$$w5uEPEPUEB{E@E}u$EE $读‹EUEBUEBD$D$/ E $4uE@ @UBE@U@EE@E@E}uDU(Et$ hE}tuE@ $$ 7E<D$ D$D$$ M39<D$ D$D$$O #3E$fE$?EtED$ED$$ 2}E$}t0E@ t%<D$ D$ D$$ 2}u0@u'<D$ D$D$$ T2/E$+@EE$E@E}uDt%<D$ D$D$$ 1<D$ D$D$$ 1ÐUS4EE}O~V  tED$$ g1E$DEEYE`EEEEEtEEEEEUUE}~EEUEE]EE$r`UEE`EEEEUEEEE`;Ev֋MEPPAPE`EUE`EUEEUEEE;E|EEED$D$E$.E4[]UEEmE%=UtD$$ OEEEE}O~``>MEPE`EUE`U($  x/EjEEEPEEEUE Et(ED$ED$ ED$ED$$' Y.E}O~ÐU}u EEEf=t2Ef=uD$E@EEP EPUEB EEE@tE@Ef9tE@$‹EPE@ $i‹EP EEEU}uEEVE$ E}tEE:E@ $‹EP E@$‹EPE$o EEU(Ef=t#E$D$$< E@-E} U ࡨt $P q-E@D$$ E@Eft $_ /-E@D$$ E@Ef t $n ,E@@EE@D$$h E@ED$$K EE+t $w ,Ef t $ l,Ef t $ M,Ef E@fE@$I‹EPt $  ,Eft $ +EfE@@ EE@@ D$ED$$ $‹EP E@fE@EE$‹EPE$q$U8E} E ;Eu/E @ D$E$E @D$E$E $ Eu EhE$E졠;Et EEEE@$E}tEET$$*EE}}y6}u%D$ED$E$C E E2EEE@ EE;EuE@ XE EE$EEET$$**E}tL}y$ED$ED$E$‹E"EED$T$E$‹EUE ;Et E @ D$$E @ E fUhE}u EEEE}t}t EEED$E$ED$$p})EEf=u E@EEEEEEf= u4ED$$D$D$$ WEGEf=u;D$$D$D$$Ef=u E@ EEEE}(E-EE;EEfEfEf=u E@EEEEEEf=u E@EEEEEED$E$ tED$$1ED$ED$$ tED$$vEf=u E@ EEEE}Ef=u E@ EEEĉE}})EEf=u E@EEEȋEȉEEf=u4ED$$D$D$$!EGEf= u;D$$D$D$$ Ef=u E@ EEẺE}(E-EE;EEfEfEf=u E@EEEЋEЉEEf=u E@EEEԋEԉEED$E$atED$$s1ED$ED$$ tED$$@Ef=u E@ EEE؉E}Ef=u E@ EEE܉E}EEEfE@ EED$$}u@ EUEB E@ EE@ E@Ef=t Ef=uiE@EE@EfE@PEPE@P EP E@PEPED$$EEE@ E}u"}uD$$ @EEEEÐU(EEoEED$$=tJE@t ED$E$/tEE-E@$1EE@ EE}uEEU(}u EEE$FE}t EE$EE$‹EE$‹EPEPET$$ct+E@E@D$$gEEPEP EE@$.EEUD$$$  D$$=  U} tQ}t@E @D$$E @E @ D$$E @ E $U$EE‹EfUE BUEB EU}uEEE$QEEEfEPEPEPEPEP EP EEEU}uEE@E$EE@$‹EPE@ $‹EP EEEU} u E}u E|ED$E $Ht E]E;Et EHE@D$E D$E$t EE@ D$E D$E$`EEU} u ErE ;EtED$E D$E$EHE PED$T$E$u EE P ED$T$E$|EEUED$E D$E$Uu EE D$ED$E$/EEU}u} u E}t} u EEE f9t EE@t6E @t,E @E@T$$bt EQE-E} U E E@t E @uD$$V E @E@T$$EE PE@T$$EE PE@T$$u EE P E@ T$$u E_EVEЋE D$ED$$E2ED$$b D$$l EEU}u} u E}t} uB}uE f= u$EEf= u EEEE f9t EE@t3E @t)E @E@T$$Ct EVE PE@T$$"t%E P E@ T$$t EE D$E$EEU}u} u E}t} u EEE f9t EE@t3E @t)E @E@T$$Xt EHE PE@T$$Xt%E P E@ T$$?@AEFGHIJKLRSUVWbcddeeeeeeeeeeghfiijjjjlknmporqssutvvwwwwxxy{|z}}~~~~~~ *+ 9:; %$  !<&'"-M=>GI?()88A,QTPav_Q}{l026XYu8NHKJ8V#kbwy3E88.8mZs\feDO@BUg8^885Q4c˻1d7ˣWji`F/n[t]S~|hxzrpйLoʸLW-(&'2$F|b7I}~>S?@Acde #9!"  {:gaThNO<K&*S22mqr2yxok|Lkkkk9H*okkkkkkkkkkkkkkkkkkkkkkb|<kxk;\k8Fnn|||$kkkL \L \;kVY 2 =kkk ,0kQ <$%2&)^ 35{l}k@ NzS8oI{F{{BKj$YTkUVW XQ<Y[ =J"\#YZ^_)f.[/\!]RM%KNi{^lmL0_1&(*,`G3a~+,<UU>?E45bRcd6R\ f9w[T;\UVWCX<Dr  EGHJYZ%')+OMPMstuv[Q\3]5^MM_`MzMMfSSMM\f .-/60=7:;@AijkTBCUVWPXHRX`lmnotpefqfrYZ|gh pfstuv[qwxs]yuvxyz}^ijkTUVW_X*[D`lmnzop{qrVYZ8 stuv[wx]y^ijkTUVW_X`lmnzop{qrYZ stuv[]y^ijkTUVW_X`lmnzop{qrYZstuv[]y^ijkTUVW_X`nz{qrYZstuv[\]yTUVWX^_YZ`z{[\]^_`a   n]4Z12'IizIW/7:XIZ_ 7 q3/Z3'();0w33P6"#<=671Z4F1^04a335EZQZN^L]?]P_RX^_`aYX7@AN7TXXZZjk^%&z"#Y  Z35^0E3@A<>?\03'();<=>RS*`^3a 7OPQn37  [\[[0"#\_ ,-./0;X3500;<=>??367GHIJKLMNOPQN]ERSXTXXLX3YPZRMNOPQKLMNOPQXX"#X\\XXjkX3!/0[Z37`X[{_YXZYZYYYYYY I]IA_]Y`] "#gX0'()\n,-./0Y23356[[YJ]]YJ?+YY_] NZYTX\{ #"#'(),-./02356? NTX\ "#'(),-./02356? NTX\ "#,-./0356? NTX\ "#,-./0356 ?DEFGHIJKLMNOPQN"#TX\035?NTX@ABCDEFGHIJKLMNOPQY@ABCDEFGHIJKLMNOPQY $%&'()14 89:$%&'()1489:@ABCDEFGHIJKLMNOPQX_@ABCDEFGHIJKLMNOPQEFGHIJKLMNOPQ_@ABCDEFGHIJKLMNOPQ^@ABCDEFGHIJKLMNOPQ[@ABCDEFGHIJKLMNOPQ[@ABCDEFGHIJKLMNOPQY@ABCDEFGHIJKLMNOPQY@ABCDEFGHIJKLMNOPQY@ABCDEFGHIJKLMNOPQY@ABCDEFGHIJKLMNOPQ@ABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQABCDEFGHIJKLMNOPQBCDEFGHIJKLMNOPQCDEFGHIJKLMNOPQ $'()89:cdefjkmoqtvwx77336sZnple%&i1477rX03\zz*33;77\u[[{0zgZ^\_; "#035?NTXy ,-./236X\x}~X003Z]35XXXZ^a<=@ABCDEFGHIJKLMNOPQ_YXX3\\XXXX^;<=>?RS!@A@A[3]_0Z3Y`70_23XY}|~Y[XYYY[ZZYY}}}YYYY^]0NXIIh[^a^_Y]X0X_X\Y3[[Y]]YJJ+14YYYYXz_]=YDeletinginitializer in parameter list:root:max nr of processes is 255 undeclared variable %sneed constant initializer for %s claim %s redefinedtrace %s redefinedtypedef %s must be globalinvalid use of '%s'label preceding declaration,label predecing xr/xs claim,malformed declarationcannot %s mtype (ignored)mtype declaration must be globalwidth-field %s too largeundeclared variable: %snot an eventbad label-name %sarithmetic on chanarithmetic on chan id'sused 'run' outside proctypeinvalid PROVIDED clauseusage: provided ( ..expr.. )unsigned cannot be used as mesg typesyntax errorError: discardingError: poppingmemory exhaustedCleanup: discarding lookaheadCleanup: poppingYeɐRʒ1Ԕf N`Ӗ^ Leי 7CP]jkɛ՛ErqWs@m|%7>fuUbt!3©&7*;Ϋ۫,=}ج :kͭ/`®$UFs1бDV%?L³>qߴ&3@MYʵڵ <m϶4hз-^ȸո>Y)Uprocedure name %s redefinedstruct { char *c; char *t; } code_lookup[] = { { "%s", \"%%\n... }, { (char *) 0, "" } }; cannot happen, missing inline def %s"Matched""UnMatched""unMatched""StackOnly"expecting '[Un]Matched', saw %sc_state format (%s)array initialization error, c_state (%s)void globinit(void) { Global now.%s = %s; Hidden %s = %s; } void locinit%d(int h) { Local uchar *this = pptr(h); ((P%d *)this)->%s = %s; %s; uchar c_state[+%ssizeof(%s)%s%s]; WS uchar c_stack[StackSize]; "Hidden"%s; /* Hidden */ #if defined(C_States) && defined(HAS_TRACK) dereferencing state object: %sextern %s %s; #endif int cpu_printf(const char *, ...); void c_stack(uchar *p_t_r) { #ifdef VERBOSE cpu_printf("c_stack %%u\n", p_t_r); if(%s) memcpy(p_t_r, %s, %s); else memset(p_t_r, 0, %s); p_t_r += %s; } void c_update(uchar *p_t_r) { printf("c_update %%u\n", p_t_r); memcpy(p_t_r, &%s, sizeof(%s)); p_t_r += sizeof(%s); void c_unstack(uchar *p_t_r) { cpu_printf("c_unstack %%u\n", p_t_r); memcpy(%s, p_t_r, %s); void c_revert(uchar *p_t_r) { printf("c_revert %%u\n", p_t_r); memcpy(&%s, p_t_r, sizeof(%s)); /* start of %s */ \#%s /* end of %s */ #define C_States 1 #undef C_States P%s->spin: in proctype %s, ref to object in proctype %s invalid variable ref in '%s'if (!(%s)) { if (!readtrail) { depth++; trpt++; trpt->pr = II; trpt->o_t = t;trpt->st = tt; uerror("%s"); continue; } else { printf("pan: precondition false: %s\n"); _m = 3; goto P999; } } now.{ if (!(%s)) { if (!readtrail) { uerror("%s"); continue; } else { printf("pan: precondition false: %s\n"); _m = 3; goto P999; } } sv_save(); } ++--c_expr %s has side-effectsinline fcts too deeply nestedwrong nr of params on call of '%s'cyclic inline attempt on: %s#identmalformed preprocessor directive - # .malformed preprocessor directive - # .linenomalformed preprocessor directive - .fnamemalformed preprocessor directive - fname."bad param to inline %sc_code%dspin: saw char '%c' bad inline: %s /* line %d %s */ #line %d %s {inline text too long%3d: %s, warning: empty inline definition (%s) string not terminatedcharacter quote missing: %sfqu&f*_activeassertatomicbitboolbreakbytec_codec_declc_exprc_statec_trackD_proctypedochanelseemptyenabledevalfalsefifullgotohidden:hide:ifinit:init:intlenlocal:local:mtypenemptynever:never:nfullnotrace:notrace:np_odofpc_valuepidprintfprintmpriorityproctypeprovidedrund_stepinlineshortskiptimeouttrace:trace:trueshow:show:typedefunlessunsignedxrxs_lastspin: line %d replacement value: %s formal par of %s contains replacement value,()'%c'%d::;<<>><=<>=>===!=???!!!&&|| bA{Z9bitbyteproctype %s, '%s %s' could be declared '%s %s' redeclaration of '%s'(%s) has invalid width-fieldunsigned without width-field(%s) only an unsigned can have width-field:hide:bit variable (%s) cannot be hidden:show::local:chan initializer for non-channel %sbad array size for '%s'error: x[rs] claims from %s and %s conflicting claims on chan '%s'stdinspin: line %d %s warning: xs tag not compatible with -m (message loss)non-local x[rs] assertionxr or xs of non-chan '%s'bad mtype definitionname %s appears twice in mtype declarationtoo many mtype elements (>255)unsigned bit byte chan short int mtype structproctypelabel value %s%s.[%d] %d %s <:struct-field:> <:global:> <%s> %d struct %schan %s-exported as run parameterimported as proctype parameterused as l-value in asgnmntused as r-value in asgnmntpolled in receive stmntused as parameter in receive stmntused as parameter in send stmntreceived fromsent to %s by: to %s par %d, never used under this namespin: warning, %s, proctype %sglobal, '%s%s' variable is never used _attempt to read value of '_'_last_p_pid_nr_prself-reference initializing '%s'undecl var %s (assuming int)findlab through getglobal on %s cannot happen, cast_val%d->%d (%d)value (%s) truncated in assignment#ifndef XUSAFE setq_claim(, %d, ", h, ""%s"); #endif %s[%d] = ~G%s = %s = %s MSC: ~G %s %s %3d: proc %3d (TRACK) line 1 "var" (state 0) [printf('MSC: globvar\\n')] = %s %s(%d):%s~G%s(%d):%s = %s(%d):%s = MSC: ~G %s(%d):%s %s (state 0) [printf('MSC: locvar\\n')]/lib/cppseed used: %d spin: %d error(s) - aborting Exit-Status 0 spin: too many -D args, aborting %s %s > %sspin: preprocessing failed rwspin: cannot cp %s to %s use: spin [-option] ... [-option] file Note: file must always be the last argument -A apply slicing algorithm -a generate a verifier in pan.c -B no final state details in simulations -b don't execute printfs in simulation -C print channel access info (combine with -g etc.) -c columnated -s -r simulation output -d produce symbol-table information -Dyyy pass -Dyyy to the preprocessor -Eyyy pass yyy to the preprocessor -f "..formula.." translate LTL into never claim -F file like -f, but with the LTL formula stored in a 1-line file -g print all global variables -h at end of run, print value of seed for random nr generator used -i interactive (random simulation) -I show result of inlining and preprocessing -J reverse eval order of nested unlesses -jN skip the first N steps in simulation trail -k fname use the trailfile stored in fname, see also -t -l print all local variables -M print msc-flow in Postscript -m lose msgs sent to full queues -N file use never claim stored in file -nN seed for random nr generator -o1 turn off dataflow-optimizations in verifier -o2 don't hide write-only variables in verifier -o3 turn off statement merging in verifier -o4 turn on rendezvous optiomizations in verifier -o5 turn on case caching (reduces size of pan.m, but affects reachability reports) -Pxxx use xxx for preprocessing -p print all statements -qN suppress io for queue N in printouts -r print receive events -S1 and -S2 separate pan source for claim and model -s print send events -T do not indent printf output -t[N] follow [Nth] simulation trail, see also -k -Uyyy pass -Uyyy to the preprocessor -uN stop a simulation run after N steps -v verbose, more warnings -w very verbose (when combined with -l or -g) -[XYZ] reserved for use by xspin interface -V print version number and exitonoffspin: dataflow optimizations turned %s spin: dead variable elimination turned %s spin: statement merging turned %s spin: rendezvous optimization turned %s spin: case caching turned %s spin: bad or missing parameter on -o*M+++C,Spin Version 5.2.5 -- 17 April 2010spin: warning -o[123] option ignored in simulationsspin: cannot open %s pan.prepan.___progressaccept_%sspin: missing argument to -freading input from stdin:spin: -c precludes all flags except -t__p_pid_last_nr_prx-----).11..11/7/1/11N-T0011?1i1u1111111i----1L.l.~..../(/Z////00B0c00101nofilenamespin: line %3d %s, Error: saw ' near '%s'not enough memoryspin: Warning, never claim has side-effectnever claim contains i/o stmntsspin: warning, make sure that the S1 model also polls channel '%s' in its claim spin: never, saw incompatible with separate compilationenabled()pc_value()spin: Warning, using %s outside never claim spin: Error, using np_ outside never claim '%c' = '%d'\b\t\f\n\rconditionsendrecvrecv poll %s(x->y:z)%sactive%s&&%s=%sassert%satomic%sbreak%sc_code%sc_decl%sc_expr%sc_state%sc_track%snevera constant%s--%sd_step%sd_proctype%sdo%selse%sempty%senabled%s==%seval%sfi%sfull%s>=%sgoto%s>%shidden%sif%s++inline name%sinline%sinit%slocala label-name%s<=%slen%s<<%s<%smtypean identifier%s!=%s! (not)%snempty%snfullsub-sequence%snp_%sod%sof%s||%s!!%spc_valueprocess name%sprintf%sprintm%spriority%sproctype%sprovided%s?%s??%s>>%sruntoken: ::%sshow%s!a string%strace%stimeoutdata typename%stypedef%sx[rs]%s- (unary minus)a typename%sunlesst@@@,@@A,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@AA,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@A,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@ %s)%s->Send send%3d: warning: missing params in send %3d: warning: too many params in send %3d: warning: missing params in next recv %3d: warning: too many params in next recv Recv [Recv] <-recvrv-sendSent %3d: warning: missing params in rv-send %3d: warning: too many params in rv-send cannot happen, s_snd_*?*-[%d]Sen?!,[]q\p %3d%3d . %s%c(state -) [values: %d(state -) [%dline %3d %s %s %s queue %d (%s) mtype name %s too long%d queue %d (%s(%d):%s[%d]): %s): invalid asgn to chaninvalid use of chan namedo not index an array with itself (%s)[]1.??_nr_pr_pattempt to assign value to system variable %sjump into d_step sequencespin: line %d %s, redundant skip -error: (%s:%d) label %s placed incorrectly =====> stmnt unless Label: stmntsorry, cannot jump to the guard of anescape (it is not a unique state)=====> instead of "Label: stmnt unless stmnt"=====> always use "Label: { stmnt unless stmnt }""atomic { Label: statement ... }""Label: atomic { statement ... }""d_step { Label: statement ... }""Label: d_step { statement ... }""{ Label: statement ... }""Label: { statement ... }"=====>instead of do (or if) :: ... :: Label: statement od (of fi)=====>always useLabel: do (or if) :: statement od (or fi)cannot happen - labelsnon_local jump in d_step sequencesequence must have at least one statementyTmunexpected: loose endsduplicate `else'cannot happen - if_seqdubious use of 'else' combined with i/o,**wwZunexpected unless structurelabel %s redeclaredundefined label %sacceptendprogresscannot happen - mov_lab %sspin: label '%s' (proctype %s) unknown label '%s'spin: cannot remote ref a label inside the same proctypefix_dest error (%s)cannot reference label inside atomic or d_step (%s):b%dmisplaced break statementd_stepatomicspin: warning, line %3d %s, atomic inside %s (ignored) spin: warning, line %3d %s, d_step inside d_step (ignored)spin: error, line %3d %s, unless in d_step (ignored) label %s %d <%s> --Starting %s with pid %d parsing error, no sequence %sspin: bad value for det (cannot happen) %d:%sproc %d = %s 0: proc - (%s) creates proc %2d (%s) priority %dspin: too many processes (%d max) spin: saw %d parameters, expected %d wrong number of parameters:never:spin: couldn't find claim (ignored)0::never:spin: remote ref to proctype %s, has more than one match: %d and %d ------------- final state: -------------#processes: %d es%d process%s created cannot happen - weightsSelect a statement choice %d: unexecutable, [ + Escape] [else] unexecutable, [else]Make Selection %d no executable choicesSelect [1-%d]: %d %64s choice is outside rangespin: error, cannot use 'enabled()' in models with synchronous channels.warning: never claim not used in random simulationwarning: trace assertion not used in random simulation-------------depth-limit (-u%d steps) reached <> [stmnt in d_step blocksterminates timeout rv-attempt in d_step sequencesaw preinitialized struct %ssetlocals: cannot happen '%s'missing actual parameters: '%s'array in parameter list, %stype-clash in params of %s(..), (%s<-> %s)%sspin: indexing %s[%d] - size is %d indexing array '%s'%3d: proc -%2d (%s) MSC: ~G line %d -line %3d %s (state %d) spin: error, type: %d not a labelname: '%s'remote ref to label '%s' inside d_stepunknown labelname: %sspin: remote reference error on '%s[%d]' refers to wrong proctype '%s'_premote ref: %s[%d] %s not foundhave only: %d %s Select stmnt () choice 0: other process choice %d: unexecutable, choice %d: (else) Make Selection %d Select [0-%d]: %64s choice outside range unexecutableStmnt [] has escape(s): ] Escape taken Escape taken %s:%dassignment%s: assertion violatedspin: text of failed assertion: assert(spin: bad node type %d (run) spin: trail file doesn't match spec?aborting!j@-K tuE T,WmW) %too few print args %s%c%d%o%u%xbad print cmd: '%s'printf string too long>                used: enabled(pid=thisproc) [%s]#if defined(VERI) && !defined(NOREDUCE) && !defined(NP) if (!state_tables#ifdef HAS_CODE && !readtrail#endif#if NCORE>1 && core_id == 0 ) { printf("warning: for p.o. reduction to be valid "); printf("the never claim must be stutter-invariant\n"); printf("(never claims generated from LTL "); printf("formulae are stutter-invariant)\n"); } UnBlock; /* disable rendez-vous */#ifdef BITSTATE if (udmem) { udmem *= 1024L*1024L; #if NCORE>1 if (!readtrail) { void init_SS(unsigned long); init_SS((unsigned long) udmem); } else #endif SS = (uchar *) emalloc(udmem); bstore = bstore_mod; } else { void init_SS(unsigned long); init_SS(ONE_L<<(ssize-3)); } #else SS = (uchar *) emalloc(ONE_L<<(ssize-3));#else hinit();#if defined(FULLSTACK) && defined(BITSTATE) onstack_init();#if defined(CNTRSTACK) && !defined(BFS) LL = (uchar *) emalloc(ONE_L<<(ssize-3)); stack = ( Stack *) emalloc(sizeof(Stack)); svtack = (Svtack *) emalloc(sizeof(Svtack)); /* a place to point for Pptr of non-running procs: */ noptr = (uchar *) emalloc(Maxbody * sizeof(char));#if defined(SVDUMP) && defined(VERBOSE) if (vprefix > 0) (void) write(svfd, (uchar *) &vprefix, sizeof(int));#ifdef VERI Addproc(VERI); /* never - pid = 0 */ active_procs(); /* started after never */#ifdef EVENT_TRACE now._event = start_event; reached[EVENT_TRACE][start_event] = 1; globinit();go_again: do_the_search(); if (--Nrun > 0 && HASH_CONST[++HASH_NR]) { printf("Run %%d:\n", HASH_NR); wrap_stats(); printf("\n"); if (udmem) /* Dillinger 3/2/09 */ { memset(SS, 0, udmem); { memset(SS, 0, ONE_L<<(ssize-3));#ifdef CNTRSTACK memset(LL, 0, ONE_L<<(ssize-3));#ifdef FULLSTACK memset((uchar *) S_Tab, 0, maxdepth*sizeof(struct H_el *)); nstates=nlinks=truncs=truncs2=ngrabs = 0; nlost=nShadow=hcmp = 0; Fa=Fh=Zh=Zn = 0; PUT=PROBE=ZAPS=Ccheck=Cholds = 0; goto go_again;}#ifdef HAS_PROVIDEDint provided(int, uchar, int, Trans *);#define GLOBAL_LOCK (0)#ifndef CS_N#define CS_N (256*NCORE)#ifdef NGQ#define NR_QS (NCORE)#define CS_NR (CS_N+1) /* 2^N + 1, nr critical sections */#define GQ_RD GLOBAL_LOCK#define GQ_WR GLOBAL_LOCK#define CS_ID (1 + (int) (j1_spin & (CS_N-1))) /* mask: 2^N - 1, zero reserved */#define QLOCK(n) (1+n)#define NR_QS (NCORE+1)#define CS_NR (CS_N+3)#define GQ_RD (1)#define GQ_WR (2)#define CS_ID (3 + (int) (j1_spin & (CS_N-1)))#define QLOCK(n) (3+n)void e_critical(int);void x_critical(int);#ifndef SEP_STATE #define enter_critical(w) e_critical(w) #define leave_critical(w) x_critical(w) #ifdef NGQ #define enter_critical(w) { if (w < 1+NCORE) e_critical(w); } #define leave_critical(w) { if (w < 1+NCORE) x_critical(w); } #define enter_critical(w) { if (w < 3+NCORE) e_critical(w); } #define leave_critical(w) { if (w < 3+NCORE) x_critical(w); }intcpu_printf(const char *fmt, ...){ va_list args; enter_critical(GLOBAL_LOCK); /* printing */ printf("cpu%%d: ", core_id); fflush(stdout); va_start(args, fmt); vprintf(fmt, args); va_end(args); leave_critical(GLOBAL_LOCK); return 1;Printf(const char *fmt, ...){ /* Make sure the args to Printf * are always evaluated (e.g., they * could contain a run stmnt) * but do not generate the output * during verification runs * unless explicitly wanted * If this fails on your system * compile SPIN itself -DPRINTF * and this code is not generated */ if (readtrail) { va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); return 1;#ifdef PRINTF va_list args;extern void printm(int);#ifndef SC#define getframe(i) &trail[i];static long HHH, DDD, hiwater;static long CNT1, CNT2;static int stackwrite;static int stackread;static Trail frameptr;Trail *getframe(int d){ if (CNT1 == CNT2) return &trail[d]; if (d >= (CNT1-CNT2)*DDD) return &trail[d - (CNT1-CNT2)*DDD]; if (!stackread && (stackread = open(stackfile, 0)) < 0) { printf("getframe: cannot open %%s\n", stackfile); wrapup(); if (lseek(stackread, d* (off_t) sizeof(Trail), SEEK_SET) == -1 || read(stackread, &frameptr, sizeof(Trail)) != sizeof(Trail)) { printf("getframe: frame read error\n"); return &frameptr;#if !defined(SAFETY) && !defined(BITSTATE)#if !defined(FULLSTACK) || defined(MA)#define depth_of(x) A_depth /* an estimate */depth_of(struct H_el *s){ Trail *t; int d; for (d = 0; d <= A_depth; d++) { t = getframe(d); if (s == t->ostate) return d; printf("pan: cannot happen, depth_of\n"); return depthfound;extern void cleanup_shm(int);volatile unsigned int *search_terminated; /* to signal early termination */voidpan_exit(int val){ void stop_timer(void); if (signoff) { printf("--end of output--\n"); if (search_terminated != NULL) { *search_terminated |= 1; /* pan_exit */#ifdef USE_DISK { void dsk_stats(void); dsk_stats(); if (!state_tables && !readtrail) { cleanup_shm(1); if (val == 2) { val = 0; { stop_timer();#ifdef C_EXIT C_EXIT; /* trust that it defines a fct */ exit(val);char *transmognify(char *s){ char *v, *w; static char buf[2][2048]; int i, toggle = 0; if (!s || strlen(s) > 2047) return s; memset(buf[0], 0, 2048); memset(buf[1], 0, 2048); strcpy(buf[toggle], s); while ((v = strstr(buf[toggle], "{c_code"))) { *v = '\0'; v++; strcpy(buf[1-toggle], buf[toggle]); for (w = v; *w != '}' && *w != '\0'; w++) /* skip */; if (*w != '}') return s; *w = '\0'; w++; for (i = 0; code_lookup[i].c; i++) if (strcmp(v, code_lookup[i].c) == 0 && strlen(v) == strlen(code_lookup[i].c)) { if (strlen(buf[1-toggle]) + strlen(code_lookup[i].t) + strlen(w) > 2047) return s; strcat(buf[1-toggle], code_lookup[i].t); break; } strcat(buf[1-toggle], w); toggle = 1 - toggle; buf[toggle][2047] = '\0'; return buf[toggle];char * transmognify(char *s) { return s; }add_src_txt(int ot, int tt){ Trans *t; char *q; for (t = trans[ot][tt]; t; t = t->nxt) { printf("\t\t"); q = transmognify(t->tp); for ( ; q && *q; q++) if (*q == '\n') printf("\\n"); else putchar(*q);wrap_trail(void){ static int wrap_in_progress = 0; int i; short II; P0 *z; if (wrap_in_progress++) return; printf("spin: trail ends after %%ld steps\n", depth); if (onlyproc >= 0) { if (onlyproc >= now._nr_pr) { pan_exit(0); } II = onlyproc; z = (P0 *)pptr(II); printf("%%3ld: proc %%d (%%s) ", depth, II, procname[z->_t]); for (i = 0; src_all[i].src; i++) if (src_all[i].tp == (int) z->_t) { printf(" line %%3d", src_all[i].src[z->_p]); printf(" (state %%2d)", z->_p); if (!stopstate[z->_t][z->_p]) printf(" (invalid end state)"); add_src_txt(z->_t, z->_p); pan_exit(0); printf("#processes %%d:\n", now._nr_pr); if (depth < 0) depth = 0; for (II = 0; II < now._nr_pr; II++) { z = (P0 *)pptr(II); c_globals(); c_locals(II, z->_t);#ifdef ON_EXIT ON_EXIT; pan_exit(0);FILE *findtrail(void){ FILE *fd; char fnm[512], *q; char MyFile[512]; char MySuffix[16]; int try_core; int candidate_files; if (trailfilename != NULL) { fd = fopen(trailfilename, "r"); if (fd == NULL) { printf("pan: cannot find %%s\n", trailfilename); pan_exit(1); } /* else */ goto success;talk: try_core = 1; candidate_files = 0; tprefix = "trail"; strcpy(MyFile, TrailFile); do { /* see if there's more than one possible trailfile */ if (whichtrail) { sprintf(fnm, "%%s%%d.%%s", MyFile, whichtrail, tprefix); fd = fopen(fnm, "r"); if (fd != NULL) { candidate_files++; if (verbose==100) printf("trail%%d: %%s\n", candidate_files, fnm); fclose(fd); if ((q = strchr(MyFile, '.')) != NULL) { *q = '\0'; sprintf(fnm, "%%s%%d.%%s", MyFile, whichtrail, tprefix); *q = '.'; fd = fopen(fnm, "r"); if (fd != NULL) { candidate_files++; if (verbose==100) printf("trail%%d: %%s\n", candidate_files, fnm); fclose(fd); } } { sprintf(fnm, "%%s.%%s", MyFile, tprefix); sprintf(fnm, "%%s.%%s", MyFile, tprefix); } } } tprefix = MySuffix; sprintf(tprefix, "cpu%%d_trail", try_core++); } while (try_core <= NCORE); if (candidate_files != 1) { if (verbose != 100) { printf("error: there are %%d trail files:\n", candidate_files); verbose = 100; goto talk; { printf("pan: rm or mv all except one\n"); exit(1); } } strcpy(MyFile, TrailFile); /* restore */try_again: if (whichtrail) { sprintf(fnm, "%%s%%d.%%s", MyFile, whichtrail, tprefix); fd = fopen(fnm, "r"); if (fd == NULL && (q = strchr(MyFile, '.'))) { *q = '\0'; sprintf(fnm, "%%s%%d.%%s", *q = '.'; { sprintf(fnm, "%%s.%%s", MyFile, tprefix); sprintf(fnm, "%%s.%%s", MyFile, tprefix); if (fd == NULL) { if (try_core < NCORE) { tprefix = MySuffix; sprintf(tprefix, "cpu%%d_trail", try_core++); goto try_again; printf("pan: cannot find trailfile %%s\n", fnm); pan_exit(1);success:#if NCORE>1 && defined(SEP_STATE) { void set_root(void); /* for partial traces from local root */ set_root(); return fd;uchar do_transit(Trans *, short);getrail(void) int i, t_id, lastnever=-1; short II; Trans *t; fd = findtrail(); /* exits if unsuccessful */ while (fscanf(fd, "%%ld:%%d:%%d\n", &depth, &i, &t_id) == 3) { if (depth == -1) printf("<<<<>>>>\n"); if (depth < 0) continue; if (i > now._nr_pr) { printf("pan: Error, proc %%d invalid pid ", i); printf("transition %%d\n", t_id); break; II = i; for (t = trans[z->_t][z->_p]; t; t = t->nxt) if (t->t_id == (T_ID) t_id) if (!t) { for (i = 0; i < NrStates[z->_t]; i++) { t = trans[z->_t][i]; if (t && t->t_id == (T_ID) t_id) { printf("\tRecovered at state %%d\n", i); z->_p = i; goto recovered; printf("pan: Error, proc %%d type %%d state %%d: ", II, z->_t, z->_p); printf("transition %%d not found\n", t_id); printf("pan: list of possible transitions in this process:\n"); if (z->_t >= 0 && z->_t <= _NP_) for (t = trans[z->_t][z->_p]; t; t = t->nxt) printf(" t_id %%d -- case %%d, [%%s]\n", t->t_id, t->forw, t->tp); break; /* pan_exit(1); */recovered: if (gui) simvals[0] = '\0'; this = pptr(II); trpt->tau |= 1; if (!do_transit(t, II)) { if (onlyproc >= 0 && II != onlyproc) goto moveon; printf("pan: error, next transition UNEXECUTABLE on replay\n"); printf(" most likely causes: missing c_track statements\n"); printf(" or illegal side-effects in c_expr statements\n"); if (onlyproc >= 0 && II != onlyproc) goto moveon; if (verbose) { printf("%%3ld: proc %%2d (%%s) ", depth, II, procname[z->_t]); for (i = 0; src_all[i].src; i++) if (src_all[i].tp == (int) z->_t) { printf(" line %%3d \"%%s\" ", src_all[i].src[z->_p], PanSource); break; } printf("(state %%d) trans {%%d,%%d} [%%s]\n", z->_p, t_id, t->forw, q?q:""); c_globals(); for (i = 0; i < now._nr_pr; i++) { c_locals(i, ((P0 *)pptr(i))->_t); if (strcmp(procname[z->_t], ":never:") == 0) { if (lastnever != (int) z->_p) { for (i = 0; src_all[i].src; i++) if (src_all[i].tp == (int) z->_t) { printf("MSC: ~G %%d\n", src_all[i].src[z->_p]); break; } if (!src_all[i].src) printf("MSC: ~R %%d\n", z->_p); lastnever = z->_p; goto sameas; if (strcmp(procname[z->_t], ":np_:") != 0) {sameas: if (no_rck) goto moveon; if (coltrace) { printf("%%ld: ", depth); for (i = 0; i < II; i++) printf("\t\t"); printf("%%s(%%d):", procname[z->_t], II); printf("[%%s]\n", q?q:""); } else if (!silent) { if (strlen(simvals) > 0) { printf("%%3ld: proc %%2d (%%s)", depth, II, procname[z->_t]); for (i = 0; src_all[i].src; i++) { printf(" line %%3d \"%%s\" ", src_all[i].src[z->_p], PanSource); printf("(state %%d) [values: %%s]\n", z->_p, simvals); printf("(state %%d) [%%s]\n", z->_p, q?q:""); /* printf("\n"); */ } }moveon: z->_p = t->st; wrap_trail();f_pid(int pt){ int i; for (i = 0; i < now._nr_pr; i++) { z = (P0 *)pptr(i); if (z->_t == (unsigned) pt) return BASE+z->_pid; return -1;void check_claim(int);#if !defined(HASH64) && !defined(HASH32) #if WS>4 #define HASH64 #define HASH32#if defined(HASH32) && defined(SAFETY) && !defined(SFH) && !defined(SPACE) #define SFH#if defined(SFH) && (defined(BITSTATE) || defined(COLLAPSE) || defined(HC) || defined(HASH64) || defined(MA)) #undef SFH#if defined(SFH) && !defined(NOCOMP) #define NOCOMP /* go for speed */#if NCORE>1 && !defined(GLOB_HEAP) #define SEP_HEAP /* version 5.1.2 */bstore_mod(char *v, int n) /* hasharray size not a power of two */{ unsigned long x, y; unsigned int i = 1; d_hash((uchar *) v, n); /* sets j3, j4, K1, K2 */ x = K1; y = j3; for (;;) { if (!(SS[x%%udmem]&(1< RANDSTOR) return 0; { SS[x%%udmem] |= (1< 0) { sprintf(fnm, "%%s%%d.%%s", MyFile, Nr_Trails-1, tprefix); {#ifdef PUTPID sprintf(fnm, "%%s_%%s_%%d.%%s", MyFile, progname, getpid(), tprefix); sprintf(fnm, "%%s.%%s", MyFile, tprefix); if ((fd = open(fnm, w_flags, TMODE)) < 0) { if ((q = strchr(MyFile, '.'))) if (iterative == 0 && Nr_Trails-1 > 0) MyFile, Nr_Trails-1, tprefix); fd = open(fnm, w_flags, TMODE); if (fd < 0) { printf("pan: cannot create %%s\n", fnm); perror("cause");#if NCORE>1 && (defined(SEP_STATE) || !defined(FULL_TRAIL)) void write_root(void); write_root(); printf("pan: wrote %%s\n", fnm);#ifndef FREQ#define FREQ (1000000)double freq = (double) FREQ;#ifdef BFS#define Q_PROVISO#ifndef INLINE_REV#define INLINE_REVtypedef struct SV_Hold { State *sv; int sz; struct SV_Hold *nxt;} SV_Hold;typedef struct EV_Hold { char *sv; int nrpr; int nrqs; char *po; char *qo; char *ps, *qs; struct EV_Hold *nxt;} EV_Hold;typedef struct BFS_Trail { Trail *frame; SV_Hold *onow; EV_Hold *omask;#ifdef Q_PROVISO struct H_el *lstate; short boq; struct BFS_Trail *nxt;} BFS_Trail;BFS_Trail *bfs_trail, *bfs_bot, *bfs_free;SV_Hold *svhold, *svfree;#ifdef BFS_DISK#ifndef BFS_LIMIT #define BFS_LIMIT 100000#ifndef BFS_DSK_LIMIT #define BFS_DSK_LIMIT 1000000#if defined(WIN32) || defined(WIN64) #define RFLAGS (O_RDONLY|O_BINARY) #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC|O_BINARY) #define RFLAGS (O_RDONLY) #define WFLAGS (O_CREAT|O_WRONLY|O_TRUNC)long bfs_size_limit;int bfs_dsk_write = -1;int bfs_dsk_read = -1;long bfs_dsk_writes, bfs_dsk_reads;int bfs_dsk_seqno_w, bfs_dsk_seqno_r;uchar do_reverse(Trans *, short, uchar);void snapshot(void);SV_Hold *getsv(int n){ SV_Hold *h = (SV_Hold *) 0, *oh; oh = (SV_Hold *) 0; for (h = svfree; h; oh = h, h = h->nxt) { if (n == h->sz) { if (!oh) svfree = h->nxt; oh->nxt = h->nxt; h->nxt = (SV_Hold *) 0; if (n < h->sz) { h = (SV_Hold *) 0; /* else continue */ if (!h) { h = (SV_Hold *) emalloc(sizeof(SV_Hold)); h->sz = n; if (bfs_size_limit >= BFS_LIMIT) { h->sv = (State *) 0; /* means: read disk */ bfs_dsk_writes++; /* count */ if (bfs_dsk_write < 0 /* file descriptor */ || bfs_dsk_writes%%BFS_DSK_LIMIT == 0) { char dsk_nm[32]; if (bfs_dsk_write >= 0) { (void) close(bfs_dsk_write); sprintf(dsk_nm, "pan_bfs_%%d.tmp", bfs_dsk_seqno_w++); bfs_dsk_write = open(dsk_nm, WFLAGS, 0644); if (bfs_dsk_write < 0) { Uerror("could not create tmp disk file"); printf("pan: created disk file %%s\n", dsk_nm); if (write(bfs_dsk_write, (char *) &now, n) != n) { Uerror("aborting -- disk write failed (disk full?)"); return h; /* no memcpy */ bfs_size_limit++; h->sv = (State *) emalloc(sizeof(State) - VECTORSZ + n); memcpy((char *)h->sv, (char *)&now, n); return h;EV_Hold *getsv_mask(int n){ EV_Hold *h; static EV_Hold *kept = (EV_Hold *) 0; for (h = kept; h; h = h->nxt) if (n == h->sz && (memcmp((char *) Mask, (char *) h->sv, n) == 0) && (now._nr_pr == h->nrpr) && (now._nr_qs == h->nrqs)#if VECTORSZ>32000 && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(int)) == 0) && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(int)) == 0) && (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(short)) == 0) && (memcmp((char *) q_offset, (char *) h->qo, now._nr_qs * sizeof(short)) == 0) && (memcmp((char *) proc_skip, (char *) h->ps, now._nr_pr * sizeof(uchar)) == 0) && (memcmp((char *) q_skip, (char *) h->qs, now._nr_qs * sizeof(uchar)) == 0)) { h = (EV_Hold *) emalloc(sizeof(EV_Hold)); h->nrpr = now._nr_pr; h->nrqs = now._nr_qs; h->sv = (char *) emalloc(n * sizeof(char)); memcpy((char *) h->sv, (char *) Mask, n); if (now._nr_pr > 0) { h->ps = (char *) emalloc(now._nr_pr * sizeof(int)); memcpy((char *) h->ps, (char *) proc_skip, now._nr_pr * sizeof(uchar)); h->po = (char *) emalloc(now._nr_pr * sizeof(int)); memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(int)); h->po = (char *) emalloc(now._nr_pr * sizeof(short)); memcpy((char *) h->po, (char *) proc_offset, now._nr_pr * sizeof(short)); if (now._nr_qs > 0) { h->qs = (char *) emalloc(now._nr_qs * sizeof(int)); memcpy((char *) h->qs, (char *) q_skip, now._nr_qs * sizeof(uchar)); h->qo = (char *) emalloc(now._nr_qs * sizeof(int)); memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(int)); h->qo = (char *) emalloc(now._nr_qs * sizeof(short)); memcpy((char *) h->qo, (char *) q_offset, now._nr_qs * sizeof(short)); h->nxt = kept; kept = h;freesv(SV_Hold *p){ SV_Hold *h, *oh; if (h->sz >= p->sz) if (!oh) { p->nxt = svfree; svfree = p; { p->nxt = h; oh->nxt = p;BFS_Trail *get_bfs_frame(void){ BFS_Trail *t; if (bfs_free) { t = bfs_free; bfs_free = bfs_free->nxt; t->nxt = (BFS_Trail *) 0; { t = (BFS_Trail *) emalloc(sizeof(BFS_Trail)); t->frame = (Trail *) emalloc(sizeof(Trail)); return t;push_bfs(Trail *f, int d) t = get_bfs_frame(); memcpy((char *)t->frame, (char *)f, sizeof(Trail)); t->frame->o_tt = d; /* depth */ t->boq = boq; t->onow = getsv(vsize); t->omask = getsv_mask(vsize);#if defined(FULLSTACK) && defined(Q_PROVISO) t->lstate = Lstate; if (!bfs_bot) { bfs_bot = bfs_trail = t; { bfs_bot->nxt = t; bfs_bot = t;#ifdef CHECK printf("PUSH %%u (%%d)\n", t->frame, d);pop_bfs(void) if (!bfs_trail) return (Trail *) 0; t = bfs_trail; bfs_trail = t->nxt; bfs_bot = (BFS_Trail *) 0;#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE) if (t->lstate) t->lstate->tagged = 0; t->nxt = bfs_free; bfs_free = t; vsize = t->onow->sz; boq = t->boq; if (t->onow->sv == (State *) 0) { char dsk_nm[32]; bfs_dsk_reads++; /* count */ if (bfs_dsk_read >= 0 /* file descriptor */ && bfs_dsk_reads%%BFS_DSK_LIMIT == 0) { (void) close(bfs_dsk_read); sprintf(dsk_nm, "pan_bfs_%%d.tmp", bfs_dsk_seqno_r-1); (void) unlink(dsk_nm); bfs_dsk_read = -1; if (bfs_dsk_read < 0) { sprintf(dsk_nm, "pan_bfs_%%d.tmp", bfs_dsk_seqno_r++); bfs_dsk_read = open(dsk_nm, RFLAGS); if (bfs_dsk_read < 0) { Uerror("could not open temp disk file"); if (read(bfs_dsk_read, (char *) &now, vsize) != vsize) { Uerror("bad bfs disk file read");#ifndef NOVSZ if (now._vsz != vsize) { Uerror("disk read vsz mismatch"); memcpy((uchar *) &now, (uchar *) t->onow->sv, vsize); memcpy((uchar *) Mask, (uchar *) t->omask->sv, vsize); if (now._nr_pr > 0) { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(int)); { memcpy((char *)proc_offset, (char *)t->omask->po, now._nr_pr * sizeof(short)); memcpy((char *)proc_skip, (char *)t->omask->ps, now._nr_pr * sizeof(uchar)); if (now._nr_qs > 0) { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(int)); { memcpy((uchar *)q_offset, (uchar *)t->omask->qo, now._nr_qs * sizeof(short)); memcpy((uchar *)q_skip, (uchar *)t->omask->qs, now._nr_qs * sizeof(uchar)); if (t->onow->sv != (State *) 0) freesv(t->onow); /* omask not freed */ printf("POP %%u (%%d)\n", t->frame, t->frame->o_tt); return t->frame;store_state(Trail *ntrpt, int shortcut, short oboq) Trans *t2 = (Trans *) 0; uchar ot; int tt, E_state; uchar o_opm = trpt->o_pm, *othis = this; if (shortcut)#ifdef VERBOSE printf("claim: shortcut\n"); goto store_it; /* no claim move */ this = (((uchar *)&now)+proc_offset[0]); /* 0 = never claim */ trpt->o_pm = 0; tt = (int) ((P0 *)this)->_p; ot = (uchar) ((P0 *)this)->_t;#ifdef HAS_UNLESS E_state = 0; for (t2 = trans[ot][tt]; t2; t2 = t2?t2->nxt:(Trans *)0) if (E_state > 0 && E_state != t2->e_trans) if (do_transit(t2, 0)) if (!reached[ot][t2->st]) printf("depth: %%d -- claim move from %%d -> %%d\n", trpt->o_tt, ((P0 *)this)->_p, t2->st); E_state = t2->e_trans; if (t2->st > 0) { ((P0 *)this)->_p = t2->st; reached[ot][t2->st] = 1;#ifndef NOCLAIM check_claim(t2->st); if (now._nr_pr == 0) /* claim terminated */ uerror("end state in claim reached");#ifdef PEG peg[t2->forw]++; trpt->o_pm |= 1; if (t2->atom&2) Uerror("atomic in claim not supported in BFS mode");store_it: if (!bstore((char *)&now, vsize))#ifdef MA if (!gstore((char *)&now, vsize, 0)) if (!hstore((char *)&now, vsize)) { static long sdone = (long) 0; long ndone; nstates++;#ifndef NOREDUCE trpt->tau |= 64; ndone = (unsigned long) (nstates/(freq)); if (ndone != sdone && mreached%%10 != 0) { snapshot(); sdone = ndone;#if defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(MA) if (nstates > ((double)(1<<(ssize+1)))) { void resize_hashtable(void); resize_hashtable();#if SYNC if (boq != -1) midrv++; else if (oboq != -1) { Trail *x; x = (Trail *) trpt->ostate; /* pre-rv state */ if (x) x->o_pm |= 4; /* mark success */ push_bfs(ntrpt, trpt->o_tt+1); } else { truncs++;#if !defined(NOREDUCE) && defined(FULLSTACK) && defined(Q_PROVISO)#if !defined(BITSTATE) if (Lstate && Lstate->tagged) trpt->tau |= 64; if (trpt->tau&32) { BFS_Trail *tprov; for (tprov = bfs_trail; tprov; tprov = tprov->nxt) if (tprov->onow->sv != (State *) 0 && memcmp((uchar *)&now, (uchar *)tprov->onow->sv, vsize) == 0) { trpt->tau |= 64; break; /* state is in queue */ } } ((P0 *)this)->_p = tt; /* reset claim */ if (t2) do_reverse(t2, 0, 0); this = othis; trpt->o_pm = o_opm;Trail *ntrpt;bfs(void){ Trans *t; Trail *otrpt, *x; uchar _n, _m, ot, nps = 0; int tt, E_state; short II, From = (short) (now._nr_pr-1), To = BASE; short oboq = boq; ntrpt = (Trail *) emalloc(sizeof(Trail)); trpt->ostate = (struct H_el *) 0; trpt->tau = 0; trpt->o_tt = -1; store_state(ntrpt, 0, oboq); /* initial state */ while ((otrpt = pop_bfs())) /* also restores now */ { memcpy((char *) trpt, (char *) otrpt, sizeof(Trail));#if defined(C_States) && (HAS_TRACK==1) c_revert((uchar *) &(now.c_state[0])); if (trpt->o_pm & 4) printf("Revisit of atomic not needed (%%d)\n", trpt->o_pm); nps = 0; if (trpt->o_pm == 8) { revrv++; if (trpt->tau&8) { printf("Break atomic (pm:%%d,tau:%%d)\n", trpt->o_pm, trpt->tau); trpt->tau &= ~8; else if (trpt->tau&32) printf("Void preselection (pm:%%d,tau:%%d)\n", trpt->tau &= ~32; nps = 1; /* no preselection in repeat */ trpt->o_pm &= ~(4|8); if (trpt->o_tt > mreached) { mreached = trpt->o_tt; if (mreached%%10 == 0) { snapshot(); depth = trpt->o_tt; if (depth >= maxdepth) Trail *x; if (boq != -1) { x = (Trail *) trpt->ostate; if (x) x->o_pm |= 4; /* not failing */ truncs++; if (!warned) { warned = 1; printf("error: max search depth too small\n"); if (bounded) uerror("depth limit reached"); if (boq == -1 && !(trpt->tau&8) && nps == 0) for (II = now._nr_pr-1; II >= BASE; II -= 1)Pickup: this = pptr(II); tt = (int) ((P0 *)this)->_p; ot = (uchar) ((P0 *)this)->_t; if (trans[ot][tt]->atom & 8) { t = trans[ot][tt]; if (t->qu[0] != 0) { Ccheck++; if (!q_cond(II, t)) continue; Cholds++; From = To = II; trpt->tau |= 32; /* preselect marker */ printf("%%3ld: proc %%d PreSelected (tau=%%d)\n", depth, II, trpt->tau); goto MainLoop; trpt->tau &= ~32;Repeat: if (trpt->tau&8) /* atomic */ { From = To = (short ) trpt->pr; nlinks++; { From = now._nr_pr-1; To = BASE;MainLoop: _n = _m = 0; for (II = From; II >= To; II -= 1) this = (((uchar *)&now)+proc_offset[II]); /* no rendezvous with same proc */ if (boq != -1 && trpt->pr == II) continue; ntrpt->pr = (uchar) II; ntrpt->st = tt; trpt->o_pm &= ~1; /* no move yet */ trpt->o_event = now._event; if (!provided(II, ot, tt, t)) continue; E_state = 0; for (t = trans[ot][tt]; t; t = t->nxt) if (E_state > 0 && E_state != t->e_trans) ntrpt->o_t = t; oboq = boq; if (!(_m = do_transit(t, II))) continue; trpt->o_pm |= 1; /* we moved */ (trpt+1)->o_m = _m; /* for unsend */ peg[t->forw]++; printf("%%3ld: proc %%d exec %%d, ", depth, II, t->forw); printf("%%d to %%d, %%s %%s %%s", tt, t->st, t->tp, (t->atom&2)?"atomic":"", (boq != -1)?"rendez-vous":""); if (t->e_trans) printf(" (escapes to state %%d)", t->st); printf(" %%saccepting [tau=%%d]\n", (trpt->o_pm&2)?"":"non-", trpt->tau); E_state = t->e_trans;#if SYNC>0 if (t->e_trans > 0 && (boq != -1 /* || oboq != -1 */)) { fprintf(efd, "error: the use of rendezvous stmnt in the escape clause\n"); fprintf(efd, " of an unless stmnt is not compatible with -DBFS\n"); pan_exit(1); if (t->st > 0) ((P0 *)this)->_p = t->st; /* ptr to pred: */ ntrpt->ostate = (struct H_el *) otrpt; ntrpt->st = tt; if (boq == -1 && (t->atom&2)) /* atomic */ ntrpt->tau = 8; /* record for next move */ else ntrpt->tau = 0; store_state(ntrpt, (boq != -1 || (t->atom&2)), oboq); now._event = trpt->o_event; /* undo move and continue */ trpt++; /* this is where ovals and ipt are set */ do_reverse(t, II, _m); /* restore now. */ trpt--; enter_critical(GLOBAL_LOCK); /* in verbose mode only */ printf("cpu%%d: ", core_id); printf("%%3d: proc %%d ", depth, II); printf("reverses %%d, %%d to %%d,", t->forw, tt, t->st); printf(" %%s [abit=%%d,adepth=%%d,", t->tp, now._a_t, A_depth); printf("tau=%%d,%%d]\n", trpt->tau, (trpt-1)->tau); leave_critical(GLOBAL_LOCK); reached[ot][t->st] = 1; reached[ot][tt] = 1; ((P0 *)this)->_p = tt; _n |= _m; /* preselected - no succ definitely outside stack */ if ((trpt->tau&32) && !(trpt->tau&64)) { From = now._nr_pr-1; To = BASE; cpu_printf("%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\n", depth, II+1, (int) _n, trpt->tau); _n = 0; trpt->tau &= ~32; if (II >= BASE) goto Pickup; goto MainLoop; trpt->tau &= ~(32|64); if (_n != 0) printf("%%3ld: no move [II=%%d, tau=%%d, boq=%%d, _nr_pr=%%d]\n", depth, II, trpt->tau, boq, now._nr_pr); if (boq != -1) { failedrv++; x = (Trail *) trpt->ostate; /* pre-rv state */ if (!x) continue; /* root state */ if ((x->tau&8) || (x->tau&32)) /* break atomic or preselect at parent */ { x->o_pm |= 8; /* mark failure */ this = (((uchar *)&now)+proc_offset[otrpt->pr]); printf("\treset state of %%d from %%d to %%d\n", otrpt->pr, ((P0 *)this)->_p, otrpt->st); ((P0 *)this)->_p = otrpt->st; unsend(boq); /* retract rv offer */ boq = -1; push_bfs(x, x->o_tt); printf("failed rv, repush with %%d\n", x->o_pm); else printf("failed rv, tau at parent: %%d\n", x->tau); } else if (now._nr_pr > 0) if ((trpt->tau&8)) /* atomic */ { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */ printf("%%3ld: atomic step proc %%d blocks\n", depth, II+1); goto Repeat; if (!(trpt->tau&1)) /* didn't try timeout yet */ { trpt->tau |= 1; printf("%%d: timeout\n", depth);#ifndef VERI if (!noends && !a_cycles && !endstate()) uerror("invalid end state");putter(Trail *trpt, int fd){ long j; if (!trpt) return; if (trpt != (Trail *) trpt->ostate) putter((Trail *) trpt->ostate, fd); if (trpt->o_t) { sprintf(snap, "%%d:%%d:%%d\n", trcnt++, trpt->pr, trpt->o_t->t_id); j = strlen(snap); if (write(fd, snap, j) != j) { printf("pan: error writing %%s\n", fnm);nuerror(char *str){ int fd = make_trail(); int j; if (fd < 0) return; sprintf(snap, "-2:%%d:-2\n", VERI); (void) write(fd, snap, strlen(snap));#ifdef MERGED sprintf(snap, "-4:-4:-4\n"); trcnt = 1; putter(trpt, fd); if (ntrpt->o_t) trcnt++, ntrpt->pr, ntrpt->o_t->t_id); close(fd); if (errors >= upto && upto != 0) { wrapup();clock_t start_time;clock_t crash_stamp;#if !defined(WIN32) && !defined(WIN64)struct tms start_tm;start_timer(void) start_time = clock(); start_time = times(&start_tm);stop_timer(void){ clock_t stop_time; double delta_time; struct tms stop_tm; stop_time = times(&stop_tm); delta_time = ((double) (stop_time - start_time)) / ((double) sysconf(_SC_CLK_TCK)); stop_time = clock(); delta_time = ((double) (stop_time - start_time)) / ((double) CLOCKS_PER_SEC); if (readtrail || delta_time < 0.00) return; if (core_id == 0 && nstates > (double) 0) { printf("\ncpu%%d: elapsed time %%.3g seconds (%%g states visited)\n", core_id, delta_time, nstates); if (delta_time > 0.01) { printf("cpu%%d: rate %%g states/second\n", core_id, nstates/delta_time); { void check_overkill(void); check_overkill(); printf("\npan: elapsed time %%.3g seconds\n", delta_time); if (delta_time > 0.01) { printf("pan: rate %%9.8g states/second\n", nstates/delta_time); { printf("pan: avg transition delay %%.5g usec\n", delta_time/(nstates+truncs));#ifdef T_ALERTdouble t_alerts[17];crash_report(void) printf("crash alert intervals:\n"); for (i = 0; i < 17; i++) { printf("%%d\t%%g\n", i, t_alerts[i]);} }crash_reset(void){ /* false alarm */ if (crash_stamp != (clock_t) 0) double delta_time; int i; delta_time = ((double) (clock() - crash_stamp)) / ((double) CLOCKS_PER_SEC); delta_time = ((double) (times(&start_tm) - crash_stamp)) / ((double) sysconf(_SC_CLK_TCK)); for (i = 0; i < 16; i++) { if (delta_time <= (i*30)) { t_alerts[i] = delta_time; if (i == 16) t_alerts[i] = delta_time; printf("cpu%%d: crash alert off\n", core_id); crash_stamp = (clock_t) 0;crash_test(double maxtime){ double delta_time; if (crash_stamp == (clock_t) 0) { /* start timing */ crash_stamp = clock(); crash_stamp = times(&start_tm); { printf("cpu%%d: crash detection\n", core_id); return 0; delta_time = ((double) (clock() - crash_stamp)) / ((double) CLOCKS_PER_SEC); delta_time = ((double) (times(&start_tm) - crash_stamp)) / ((double) sysconf(_SC_CLK_TCK)); return (delta_time >= maxtime);do_the_search(void) depth = mreached = 0; trpt = &trail[0]; trpt->tau |= 4; /* the claim moves first */ for (i = 0; i < (int) now._nr_pr; i++) { P0 *ptr = (P0 *) pptr(i);#ifndef NP if (!(trpt->o_pm&2) && accpstate[ptr->_t][ptr->_p]) { trpt->o_pm |= 2; if (!(trpt->o_pm&4) && progstate[ptr->_t][ptr->_p]) { trpt->o_pm |= 4; if (accpstate[EVENT_TRACE][now._event]) { trpt->o_pm |= 2; if (progstate[EVENT_TRACE][now._event]) { trpt->o_pm |= 4;#ifndef NOCOMP Mask[0] = Mask[1] = 1; /* _nr_pr, _nr_qs */ if (!a_cycles) { i = &(now._a_t) - (uchar *) &now; Mask[i] = 1; /* _a_t */#ifndef NOFAIR if (!fairness) { int j = 0; i = &(now._cnt[0]) - (uchar *) &now; while (j++ < NFAIR) Mask[i++] = 1; /* _cnt[] */ if (fairness && (a_cycles && (trpt->o_pm&2))) { now._a_t = 2; /* set the A-bit */ now._cnt[0] = now._nr_pr + 1; printf("%%3ld: fairness Rule 1, cnt=%%d, _a_t=%%d\n", depth, now._cnt[now._a_t&1], now._a_t); c_stack_start = (char *) &i; /* meant to be read-only */#if defined(HAS_CODE) && defined (C_INIT) C_INIT; /* initialization of data that must precede fork() */ c_init_done++; /* capture initial state of tracked C objects */ c_update((uchar *) &(now.c_state[0])); if (readtrail) getrail(); /* no return */ start_timer(); bfs();#if defined(C_States) && defined(HAS_STACK) && (HAS_TRACK==1) /* initial state of tracked & unmatched objects */ c_stack((uchar *) &(svtack->c_stack[0]));#if defined(P_RAND) || defined(T_RAND) srand(s_rand); mem_get(); new_state(); /* start 1st DFS */#ifdef INLINE_REVuchardo_reverse(Trans *t, short II, uchar M){ uchar _m = M; int tt = (int) ((P0 *)this)->_p;#include REVERSE_MOVESR999: return _m;#ifndef INLINEstatic char _tp = 'n'; static int _qid = 0;do_transit(Trans *t, short II){ uchar _m = 0;#ifdef M_LOSS uchar delta_m = 0; uchar ot = (uchar) ((P0 *)this)->_t; if (II == -EVENT_TRACE) boq = -1;#define continue { boq = oboq; return 0; }#define continue return 0#ifdef SEPARATE#include FORWARD_MOVESP999: if (II == -EVENT_TRACE) boq = oboq; return _m;#undef continuerequire(char tp, int qid) _tp = tp; _qid = qid; if (now._event != endevent) for (t = trans[EVENT_TRACE][now._event]; t; t = t->nxt) { if (do_transit(t, -EVENT_TRACE)) { now._event = t->st; reached[EVENT_TRACE][t->st] = 1; printf(" event_trace move to -> %%d\n", t->st);#ifndef BFS if (accpstate[EVENT_TRACE][now._event]) (trpt+1)->o_pm |= 2; if (progstate[EVENT_TRACE][now._event]) (trpt+1)->o_pm |= 4;#ifdef NEGATED_TRACE if (now._event == endevent) depth++; trpt++; uerror("event_trace error (all events matched)"); trpt--; depth--; for (t = t->nxt; t; t = t->nxt) { if (do_transit(t, -EVENT_TRACE)) Uerror("non-determinism in event-trace"); return; else printf(" event_trace miss '%%c' -- %%d, %%d, %%d\n", tp, qid, now._event, t->forw); now._event = endevent; /* only 1st try will count -- fixed 4.2.6 */ depth++; trpt++; uerror("event_trace error (no matching event)"); trpt--; depth--;enabled(int iam, int pid){ Trans *t; uchar *othis = this; int res = 0; int tt; uchar ot; /* if (pid > 0) */ pid++; if (pid == iam) Uerror("used: enabled(pid=thisproc)"); if (pid < 0 || pid >= (int) now._nr_pr) this = pptr(pid); TstOnly = 1; tt = (int) ((P0 *)this)->_p; ot = (uchar) ((P0 *)this)->_t; if (do_transit(t, (short) pid)) { res = 1; TstOnly = 0; return res;snap_time(void) stop_time = times(&stop_tm); stop_time = clock(); { printf("t= %%6.3g ", delta_time); printf("R= %%7.0g", nstates/delta_time); printf("\n"); if (quota > 0.1 && delta_time > quota) { printf("Time limit of %%6.3g minutes exceeded\n", quota/60.0); fflush(stdout); leave_critical(GLOBAL_LOCK); sudden_stop("time-limit"); exit(1);snapshot(void) enter_critical(GLOBAL_LOCK); /* snapshot */ printf("Depth= %%7ld States= %%8.3g ", (long) (nr_handoffs * z_handoff) + mreached, nstates); printf("Transitions= %%8.3g ", nstates+truncs); printf("Nodes= %%7d ", nr_states); printf("Memory= %%9.3f\t", memcnt/1048576.); snap_time();#ifdef SCstack2disk(void) if (!stackwrite && (stackwrite = creat(stackfile, TMODE)) < 0) Uerror("cannot create stackfile"); if (write(stackwrite, trail, DDD*sizeof(Trail)) != DDD*sizeof(Trail)) Uerror("stackfile write error -- disk is full?"); memmove(trail, &trail[DDD], (HHH-DDD+2)*sizeof(Trail)); memset(&trail[HHH-DDD+2], 0, (omaxdepth - HHH + DDD - 2)*sizeof(Trail)); CNT1++;disk2stack(void){ long have; CNT2++; memmove(&trail[DDD], trail, (HHH-DDD+2)*sizeof(Trail)); || lseek(stackwrite, -DDD* (off_t) sizeof(Trail), SEEK_CUR) == -1) Uerror("disk2stack lseek error"); Uerror("cannot open stackfile"); if (lseek(stackread, (CNT1-CNT2)*DDD* (off_t) sizeof(Trail), SEEK_SET) == -1) have = read(stackread, trail, DDD*sizeof(Trail)); if (have != DDD*sizeof(Trail)) Uerror("stackfile read error");uchar *Pptr(int x){ if (x < 0 || x >= MAXPROC || !proc_offset[x]) return noptr; else return (uchar *) pptr(x);int qs_empty(void);/* * new_state() is the main DFS search routine in the verifier * it has a lot of code ifdef-ed together to support * different search modes, which makes it quite unreadable. * if you are studying the code, first use the C preprocessor * to generate a specific version from the pan.c source, * e.g. by saying: * gcc -E -DNOREDUCE -DBITSTATE pan.c > ppan.c * and then study the resulting file, rather than this one */#if !defined(BFS) && (!defined(BITSTATE) || !defined(MA))#ifdef NSUCCint N_succ[512];tally_succ(int cnt){ if (cnt < 512) N_succ[cnt]++; else printf("tally_succ: cnt %%d exceeds range\n", cnt);dump_succ(void){ int i; double sum = 0.0; double w_avg = 0.0; printf("Successor counts:\n"); for (i = 0; i < 512; i++) { sum += (double) N_succ[i]; { if (N_succ[i] > 0) { printf("%%3d %%10d (%%.4g %%%% of total)\n", i, N_succ[i], (100.0 * (double) N_succ[i])/sum); w_avg += (double) i * (double) N_succ[i]; if (sum > N_succ[0]) printf("mean %%.4g (without 0: %%.4g)\n", w_avg / sum, w_avg / (sum - (double) N_succ[0]));#ifdef REVERSE #define FROM_P (BASE) #define UPTO_P (now._nr_pr-1) #define MORE_P (II <= To) #define INI_P (From-1) #define ALL_P (II = From; II <= To; II++) #define FROM_P (now._nr_pr-1) #define UPTO_P (BASE) #define MORE_P (II >= BASE) #define INI_P (From+1) #define ALL_P (II = From; II >= To; II--)new_state(void) uchar _n, _m, ot;#ifdef T_RAND short ooi, eoi; short II, JJ = 0, kk; int tt; short From = FROM_P, To = UPTO_P;#ifdef BCS trpt->sched_limit = 0; /* at depth=0 only */Down: cpu_printf("%%d: Down - %%s %%saccepting [pids %%d-%%d]\n", depth, (trpt->tau&4)?"claim":"program", (trpt->o_pm&2)?"":"non-", From, To);#ifdef P_RAND trpt->p_skip = -1; if (depth > hiwater) { stack2disk(); maxdepth += DDD; hiwater += DDD; trpt -= DDD; if(verbose) printf("zap %%d: %%d (maxdepth now %%d)\n", CNT1, hiwater, maxdepth); trpt->tau &= ~(16|32|64); /* make sure these are off */#if defined(FULLSTACK) && defined(MA) trpt->proviso = 0; trpt->n_succ = 0; if (mem_hand_off()) (trpt+1)->o_n = 1; /* not a deadlock: as below */#ifndef LOOPSTATE (trpt-1)->tau |= 16; /* worstcase guess: as below */#if NCORE>1 && defined(FULL_TRAIL) if (upto > 0) { Pop_Stack_Tree(); goto Up; if (depth >= maxdepth) { if (!warned) { warned = 1; printf("error: max search depth too small\n"); if (bounded) { uerror("depth limit reached"); truncs++; (trpt+1)->o_n = 1; /* not a deadlock */ (trpt-1)->tau |= 16; /* worstcase guess */AllOver:#if (defined(FULLSTACK) && !defined(MA)) || NCORE>1 /* if atomic or rv move, carry forward previous state */ trpt->ostate = (trpt-1)->ostate; if ((trpt->tau&4) || ((trpt-1)->tau&128)) if (boq == -1) { /* if not mid-rv */#ifndef SAFETY /* this check should now be redundant * because the seed state also appears * on the 1st dfs stack and would be * matched in hstore below */ if ((now._a_t&1) && depth > A_depth) { if (!memcmp((char *)&A_Root, (char *)&now, vsize)) depthfound = A_depth; printf("matches seed\n");#ifdef NP uerror("non-progress cycle"); uerror("acceptance cycle"); if (upto > 0) { Pop_Stack_Tree(); goto Up; printf("not seed\n"); if (!(trpt->tau&8)) /* if no atomic move */#if defined(BCS) && defined(NO_LAST) && defined(HAS_LAST) uchar was_last = now._last; now._last = 0; /* value not stored */ #if defined(BCS) && defined(STORE_CTX) { int xj; for (xj = trpt->sched_limit; xj <= sched_max; xj++) { now._ctx = xj; II = bstore((char *)&now, vsize); trpt->j6 = j1_spin; trpt->j7 = j2; JJ = LL[j1_spin] && LL[j2]; if (II != 0) { break; } now._ctx = 0; /* just in case */ #else II = bstore((char *)&now, vsize); trpt->j6 = j1_spin; trpt->j7 = j2; JJ = LL[j1_spin] && LL[j2]; #endif #ifdef FULLSTACK #if defined(BCS) && defined(STORE_CTX) { int xj; now._ctx = 0; JJ = onstack_now(); } #else #endif JJ = II; /* worstcase guess for p.o. - order corrected in 5.2.1 */ JJ = II; /* worstcase guess for p.o. - order corrected in 5.2.1 */ II = gstore((char *)&now, vsize, 0);#ifndef FULLSTACK JJ = II; JJ = (II == 2)?1:0; II = hstore((char *)&now, vsize); kk = (II == 1 || II == 2); now._last = was_last; /* restore value */#if NCORE==1 || defined (SEP_STATE) if (II == 2 && ((trpt->o_pm&2) || ((trpt-1)->o_pm&2))) #ifndef NOFAIR#if 0 if (!fairness || ((now._a_t&1) && now._cnt[1] == 1)) /* 5.1.4 */ if (a_cycles && !fairness) /* 5.1.6 -- example by Hirofumi Watanabe */ II = 3; /* Schwoon & Esparza 2005, Gastin&Moro 2004 */ printf("state match on dfs stack\n"); goto same_case; if (!JJ && (now._a_t&1) && depth > A_depth) { int oj1 = j1_spin; uchar o_a_t = now._a_t; now._a_t &= ~(1|16|32); if (onstack_now()) { II = 3; printf("state match on 1st dfs stack\n"); now._a_t = o_a_t; j1_spin = oj1; if (II == 3 && a_cycles && (now._a_t&1)) if (fairness && now._cnt[1] > 1) /* was != 0 */ { printf(" fairness count non-zero\n"); II = 0; } else#ifndef BITSTATE nShadow--;same_case: if (Lstate) depthfound = Lstate->D; uerror("non-progress cycle"); uerror("acceptance cycle"); if (upto > 0) { Pop_Stack_Tree(); goto Up; } #ifndef SAFETY #if NCORE>1 && !defined(SEP_STATE) && defined(V_PROVISO) if (II != 0 && (!Lstate || Lstate->cpu_id < core_id)) { (trpt-1)->tau |= 16; if ((II && JJ) || (II == 3)) { /* marker for liveness proviso */ #ifndef LOOPSTATE (trpt-1)->tau |= 16; truncs2++; if (!(II != 0 && (!Lstate || Lstate->cpu_id < core_id))) { /* treat as stack state */ { /* treat as non-stack state */ (trpt-1)->tau |= 64; if (!II || !JJ) { /* successor outside stack */#if defined(BCS) && (defined(NOREDUCE) || !defined(SAFETY)) { (trpt-1)->tau |= 64; if (II) if (depth == 0) { return; if (!kk)#if defined(ZAPH) && defined(BITSTATE) zstates += (double) hfns; if (ndone != sdone) if (nstates > ((double)(ONE_L<<(ssize+1)))) if (zstates > ((double)(ONE_L<<(ssize-2)))) { /* more than half the bits set */ void zap_hashtable(void); zap_hashtable(); zstates = 0;#ifdef SVDUMP if (vprefix > 0) #ifdef SHO /* always use the same hashfunction, for consistency across runs */ if (HASH_NR != 0) { int oh = HASH_NR; HASH_NR = 0; d_hash((char *) &now, vsize); /* set K1 */ HASH_NR = oh; if (write(svfd, (uchar *) &K1, sizeof(unsigned long)) != sizeof(unsigned long)) if (write(svfd, (uchar *) &now, vprefix) != vprefix) { fprintf(efd, "writing %%s.svd failed\n", PanSource); wrapup();#if defined(MA) && defined(W_XPT) if ((unsigned long) nstates%%W_XPT == 0) { void w_xpoint(void); w_xpoint();#if defined(FULLSTACK) || defined(CNTRSTACK) onstack_put();#ifdef DEBUG2#if defined(FULLSTACK) && !defined(MA) printf("%%d: putting %%u (%%d)\n", depth, trpt->ostate, (trpt->ostate)?trpt->ostate->tagged:0); printf("%%d: putting\n", depth); trpt->ostate = Lstate; if (depth > mreached) mreached = depth; if (trpt->tau&4) trpt->tau &= ~(1|2); /* timeout and -request off */ _n = 0; (trpt+1)->o_n = 0; if (now._nr_pr == 0) /* claim terminated */ uerror("end state in claim reached"); check_claim(((P0 *)pptr(0))->_p);Stutter: if (trpt->tau&4) /* must make a claimmove */ if ((now._a_t&2) /* A-bit set */ && now._cnt[now._a_t&1] == 1) { now._a_t &= ~2; now._cnt[now._a_t&1] = 0; trpt->o_pm |= 16; printf("%%3d: fairness Rule 3.: _a_t = %%d\n", depth, now._a_t); II = 0; /* never */ goto Veri0; /* Look for a process with only safe transitions */ /* (special rules apply in the 2nd dfs) */ if (boq == -1 && From != To#ifdef SAFETY #if NCORE>1 && (depth < z_handoff) #endif && ((a_cycles) || (!a_cycles && depth < z_handoff)) #ifdef BCS && (sched_max > 0 || depth > BASE) && (!(now._a_t&1) || (a_cycles && #ifndef BITSTATE !((trpt-1)->proviso)) !(trpt->proviso)) (trpt-1)->ostate && !(((char *)&((trpt-1)->ostate->state))[0] & 128)) !(((char *)&(trpt->ostate->state))[0] & 128)) #else (trpt-1)->ostate && (trpt-1)->ostate->proviso == 0) trpt->ostate->proviso == 0) )) /* attempt Partial Order Reduction as preselect moves */ if (trpt->sched_limit < sched_max)#if defined(BCS) && defined(BCS_STICK) if (depth > BASE) /* there is a prior move */ { II = now._last + BASE; /* check last process */ if (II >= now._nr_pr) /* process is gone */ { goto CheckAllPO; this = pptr(II); if (trans[ot][tt] && trans[ot][tt]->atom & 8) /* safe */ if (t->qu[0] != 0) /* conditional */ { /* try other safe moves */ goto CheckAllPO; /* else: BCS would also select it, but not as a po move */ goto SelectIt; /* if it fails, we continue at Resume, so we don't always try all safe moves in this case -- which is still sound */CheckAllPO: for ALL_PResume: /* pick up here if preselect fails */SelectIt: From = To = II; /* preselect process */#ifdef NIBIS t->om = 0; goto Again; trpt->tau &= ~32;#if !defined(NOREDUCE) || (defined(ETIM) && !defined(VERI))Again: trpt->o_pm &= ~(8|16|32|64); /* clear fairness-marks */ if (fairness && boq == -1 && (!(trpt->tau&4) && !((trpt-1)->tau&128)) && !(trpt->tau&8)) { /* A_bit = 1; Cnt = N in acc states with A_bit 0 */ if (!(now._a_t&2)) { if (a_cycles && (trpt->o_pm&2)) { /* Accepting state */ now._a_t |= 2; now._cnt[now._a_t&1] = now._nr_pr + 1; trpt->o_pm |= 8; printf("%%3ld: fairness Rule 1: cnt=%%d, _a_t=%%d\n", depth, now._cnt[now._a_t&1], now._a_t); { /* A_bit = 0 when Cnt 0 */ if (now._cnt[now._a_t&1] == 1) { now._a_t &= ~2; now._cnt[now._a_t&1] = 0; trpt->o_pm |= 16; printf("%%3ld: fairness Rule 3: _a_t = %%d\n", } } } trpt->bcs = trpt->b_pno = 0; /* initial */ if (From != To /* not a PO or atomic move */ && depth > BASE) /* there is a prior move */ { trpt->b_pno = now._last + BASE; trpt->bcs = B_PHASE1; #ifdef VERBOSE printf("%%3ld: BCS phase 1 proc %%d limit %%d\n", depth, trpt->b_pno, trpt->sched_limit); /* allow only process b_pno to move in this phase */c_switch: /* jumps here with bcs == B_PHASE2 with or wo B_FORCED added */ printf("%%3ld: BCS c_switch phase=%%d pno=%%d [forced %%d]\n", depth, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0); #ifdef REVERSE trpt->p_left = 1 + (To - From); trpt->p_left = 1 + (From - To); if (trpt->p_left > 1) { trpt->p_skip = rand() %% (trpt->p_left); { trpt->p_skip = -1;r_switch: printf("%%3ld: P_RAND r_switch p_skip=%%d p_left=%%d\n", depth, trpt->p_skip, trpt->p_left); /* Main Expansion Loop over Processes */ for ALL_P if (trpt->p_skip >= 0) { trpt->p_skip--; /* skip random nr of procs */ printf("%%3ld: P_RAND skipping %%d [new p_skip=%%d p_left=%%d]\n", depth, II, trpt->p_skip, trpt->p_left); if (trpt->p_left == 0) printf("%%3ld: P_RAND done at %%d\n", depth, II); break; /* done */ printf("%%3ld: P_RAND explore %%d [p_left=%%d]\n", depth, II, trpt->p_left); trpt->p_left--; /* no rendezvous with same proc */ if (boq != -1 && trpt->pr == II) continue; if ((trpt->bcs & B_PHASE1) && trpt->b_pno != II) printf("%%3ld: BCS NotPre II=%%d bcs=%%d pno=%%d [forced %%d]\n", depth, II, trpt->bcs, trpt->b_pno, (trpt->bcs&B_FORCED)?1:0); else if ((trpt->bcs & B_PHASE1) && trpt->b_pno == II) printf("%%3ld: BCS IsPre II=%%d bcs=%%d pno=%%d [forced %%d]\n", if (trpt->bcs & B_PHASE2) /* 2nd phase */ { if (trpt->b_pno == II) /* was already done in phase 1 */ printf("%%3ld: BCS NoRepeat II=%%d bcs=%%d pno=%%d [forced %%d]\n", continue; if (!(trpt->bcs & B_FORCED) /* unless forced */ && trpt->sched_limit >= sched_max) printf("%%3ld: BCS Bound II=%%d bcs=%%d pno=%%d [forced %%d]\n", continue; /* enforce bound */Veri0: tt = (int) ((P0 *)this)->_p; ot = (uchar) ((P0 *)this)->_t; /* don't repeat a previous preselected expansion */ /* could hit this if reduction proviso was false */ t = trans[ot][tt]; if (!(trpt->tau&4) && !(trpt->tau&1) && !(trpt->tau&32) && (t->atom & 8) && boq == -1 && From != To) { if (t->qu[0] == 0 || q_cond(II, t)) { _m = t->om; if (_m>_n||(_n>3&&_m!=0)) _n=_m; continue; /* did it before */ trpt->o_pm &= ~1; /* no move in this pid yet */ (trpt+1)->o_event = now._event; /* Fairness: Cnt++ when Cnt == II */ trpt->o_pm &= ~64; /* didn't apply rule 2 */ if (fairness && !(trpt->o_pm&32) && (now._a_t&2) && now._cnt[now._a_t&1] == II+2) { now._cnt[now._a_t&1] -= 1; /* claim need not participate */ if (II == 1) now._cnt[now._a_t&1] = 1; printf("%%3ld: proc %%d fairness ", depth, II); printf("Rule 2: --cnt to %%d (%%d)\n", now._cnt[now._a_t&1], now._a_t); trpt->o_pm |= (32|64); if (!provided(II, ot, tt, t)) continue; /* check all trans of proc II - escapes first */ trpt->e_state = 0; (trpt+1)->pr = (uchar) II; (trpt+1)->st = tt; for (ooi = eoi = 0, t = trans[ot][tt]; t; t = t->nxt, ooi++) { if (strcmp(t->tp, "else") == 0 || t->e_trans != 0 ) { eoi++; if (eoi > 0) { t = trans[ot][tt]; printf("randomizer: suppressed, saw else or escape\n"); { eoi = rand()%%ooi; printf("randomizer: skip %%d in %%d\n", eoi, ooi); if (eoi-- <= 0) break;domore: for ( ; t && ooi > 0; t = t->nxt, ooi--) for (t = trans[ot][tt]; t; t = t->nxt) /* exploring all transitions from * a single escape state suffices */ if (trpt->e_state > 0 && trpt->e_state != t->e_trans) printf("skip 2nd escape %%d (did %%d before)\n", t->e_trans, trpt->e_state); (trpt+1)->o_t = t;#ifdef INLINEP999: /* jumps here when move succeeds */ if (!(_m = do_transit(t, II))) continue; if (depth > BASE && II >= BASE && From != To #ifndef BCS_NOFIX /* added 5.2.5: prior move was not po */ && !((trpt-(BASE+1))->tau & 32) && boq == -1 && (trpt->bcs & B_PHASE2) && trpt->b_pno != II /* context switch */ && !(trpt->bcs & B_FORCED)) /* unless forced */ { (trpt+1)->sched_limit = 1 + trpt->sched_limit; printf("%%3ld: up sched count to %%d\n", depth, (trpt+1)->sched_limit); { (trpt+1)->sched_limit = trpt->sched_limit; printf("%%3ld: keep sched count at %%d\n", depth, (trpt+1)->sched_limit); if (boq == -1)#ifdef CTL /* for branching-time, can accept reduction only if */ /* the persistent set contains just 1 transition */ { if ((trpt->tau&32) && (trpt->o_pm&1)) trpt->tau |= 16; trpt->o_pm |= 1; /* we moved */#ifdef LOOPSTATE if (loopstate[ot][tt]) printf("exiting from loopstate:\n"); trpt->tau |= 16; cnt_loops++; peg[t->forw]++;#if defined(VERBOSE) || defined(CHECK)#if defined(SVDUMP) cpu_printf("%%3ld: proc %%d exec %%d \n", depth, II, t->t_id); cpu_printf("%%3ld: proc %%d exec %%d, %%d to %%d, %%s %%s %%s %%saccepting [tau=%%d]\n", depth, II, t->forw, tt, t->st, t->tp, (t->atom&2)?"atomic":"", (boq != -1)?"rendez-vous":"", (trpt->o_pm&2)?"":"non-", trpt->tau); if (t->e_trans) cpu_printf("\t(escape to state %%d)\n", t->st); cpu_printf("\t(randomizer %%d)\n", ooi);#ifdef HAS_LAST if (II != 0) now._last = II - BASE; trpt->e_state = t->e_trans; depth++; trpt++; trpt->pr = (uchar) II; trpt->st = tt; trpt->o_pm &= ~(2|4); if (t->st > 0) { ((P0 *)this)->_p = t->st;/* moved down reached[ot][t->st] = 1; */ if (a_cycles)#if (ACCEPT_LAB>0 && !defined(NP)) || (PROG_LAB>0 && defined(HAS_NP)) int ii;#define P__Q ((P0 *)pptr(ii))#if ACCEPT_LAB>0 /* state 1 of np_ claim is accepting */ if (((P0 *)pptr(0))->_p == 1) trpt->o_pm |= 2; for (ii = 0; ii < (int) now._nr_pr; ii++) { if (accpstate[P__Q->_t][P__Q->_p]) { trpt->o_pm |= 2; } }#if defined(HAS_NP) && PROG_LAB>0 { if (progstate[P__Q->_t][P__Q->_p]) { trpt->o_pm |= 4;#undef P__Q trpt->o_t = t; trpt->o_n = _n; trpt->o_ot = ot; trpt->o_tt = tt; trpt->o_To = To; trpt->o_m = _m; trpt->tau = 0; trpt->oo_i = ooi; if (boq != -1 || (t->atom&2)) { trpt->tau |= 8; /* atomic sequence in claim */ if((trpt-1)->tau&4) trpt->tau |= 4; trpt->tau &= ~4; { if ((trpt-1)->tau&4) /* if claim allowed timeout, so */ /* does the next program-step: */ if (((trpt-1)->tau&1) && !(trpt->tau&4)) trpt->tau |= 1; if (boq == -1 && (t->atom&2)) { From = To = II; nlinks++; { From = FROM_P; To = UPTO_P; { Push_Stack_Tree(II, t->t_id); goto Down; /* pseudo-recursion */Up: cpu_printf("%%d: Up - %%s\n", depth, (trpt->tau&4)?"claim":"program"); iam_alive(); #ifdef USE_DISK mem_drain();#if defined(MA) || NCORE>1 if (depth <= 0) return; /* e.g., if first state is old, after a restart */ if (CNT1 > CNT2 && depth < hiwater - (HHH-DDD) - 2) trpt += DDD; disk2stack(); maxdepth -= DDD; hiwater -= DDD; if(verbose) printf("unzap %%d: %%d\n", CNT2, hiwater); if ((now._a_t&1) && depth <= A_depth) return; /* to checkcycles() */ if (trpt->o_pm&128) /* fairness alg */ { now._cnt[now._a_t&1] = trpt->bup.oval; _n = 1; trpt->o_pm &= ~128; depth--; trpt--; printf("%%3ld: reversed fairness default move\n", depth); goto Q999; { int d; Trail *trl; now._last = 0; for (d = 1; d < depth; d++) { trl = getframe(depth-d); /* was (trpt-d) */ if (trl->pr != 0) { now._last = trl->pr - BASE; break; } } } now._last = (depth<1)?0:(trpt-1)->pr; now._event = trpt->o_event; t = trpt->o_t; _n = trpt->o_n; ot = trpt->o_ot; II = trpt->pr; tt = trpt->o_tt; this = pptr(II); To = trpt->o_To; _m = trpt->o_m; ooi = trpt->oo_i; _m = do_reverse(t, II, _m);R999: /* jumps here when done */ cpu_printf("%%3ld: proc %%d reverses %%d, %%d to %%d\n", depth, II, t->forw, tt, t->st); cpu_printf("\t%%s [abit=%%d,adepth=%%d,tau=%%d,%%d]\n", t->tp, now._a_t, A_depth, trpt->tau, (trpt-1)->tau); /* pass the proviso tags */ if ((trpt->tau&8) /* rv or atomic */ && (trpt->tau&16)) #ifdef SAFETY && (trpt->tau&64)) if ((trpt->tau&8) depth--; trpt--; trpt->n_succ++; (trans[ot][tt])->om = _m; /* head of list */ /* i.e., not set if rv fails */ if (_m)#if defined(VERI) && !defined(NP) if (II == 0 && verbose && !reached[ot][t->st]) { printf("depth %%ld: Claim reached state %%d (line %%d)\n", depth, t->st, src_claim [t->st]); fflush(stdout); else trpt->e_state = 0; /* undo */ if (_m>_n||(_n>3&&_m!=0)) _n=_m; ((P0 *)this)->_p = tt; } /* all options */ if (!t && ooi > 0) printf("randomizer: continue for %%d more\n", ooi); goto domore; else printf("randomizer: done\n"); /* Fairness: undo Rule 2 */ if ((trpt->o_pm&32) && (trpt->o_pm&64)) { if (trpt->o_pm&1) if (now._cnt[now._a_t&1] == 1) now._cnt[now._a_t&1] = 2; now._cnt[now._a_t&1] += 1; printf("undo Rule 2, cnt=%%d, _a_t=%%d\n", trpt->o_pm &= ~(32|64); { if (_n > 0) trpt->o_pm &= ~64; II = INI_P; if (II == 0) break; /* never claim */ } /* all processes */ tally_succ(trpt->n_succ); if (trpt->p_left > 0) { trpt->p_skip = -1; /* probably rendundant */ printf("%%3ld: P_RAND -- explore remainder\n", depth); goto r_switch; /* explore the remaining procs */ printf("%%3ld: P_RAND -- none left\n", depth); if (trpt->bcs & B_PHASE1) { trpt->bcs = B_PHASE2; /* start 2nd phase */ if (_n == 0 || !(trpt->tau&64)) /* pre-move unexecutable or led to stackstate */ { trpt->bcs |= B_FORCED; /* forced switch */ printf("%%3ld: BCS move to phase 2, _n=%%d %%s\n", depth, _n, (trpt->bcs & B_FORCED)?"forced":"free"); From = FROM_P; To = UPTO_P; goto c_switch; if (_n == 0 /* no process could move */ && II >= BASE /* not the never claim */ && trpt->sched_limit >= sched_max) { _n = 1; printf("%%3ld: BCS not a deadlock\n", depth); /* Fairness: undo Rule 2 */ if (trpt->o_pm&32) /* remains if proc blocked */ if (now._cnt[now._a_t&1] == 1) now._cnt[now._a_t&1] = 2; now._cnt[now._a_t&1] += 1; printf("%%3ld: proc -- fairness ", depth); trpt->o_pm &= ~32; && _n == 0 /* nobody moved */ && !(trpt->tau&4) /* in program move */ && !(trpt->tau&8) /* not an atomic one */#ifdef OTIM && ((trpt->tau&1) || endstate())#ifdef ETIM && (trpt->tau&1) /* already tried timeout */ /* see below */ && !((trpt->tau&32) && (_n == 0 || (trpt->tau&16))) && now._cnt[now._a_t&1] > 0) /* needed more procs */ { depth++; trpt++; trpt->o_pm |= 128 | ((trpt-1)->o_pm&(2|4)); trpt->bup.oval = now._cnt[now._a_t&1]; now._cnt[now._a_t&1] = 1; trpt->tau = 4; trpt->tau = 0; printf("%%3ld: fairness default move ", depth); printf("(all procs block)\n"); goto Down;Q999: /* returns here with _n>0 when done */; if (trpt->o_pm&8) { now._a_t &= ~2; now._cnt[now._a_t&1] = 0; trpt->o_pm &= ~8; printf("%%3ld: fairness undo Rule 1, _a_t=%%d\n", depth, now._a_t); if (trpt->o_pm&16) { now._a_t |= 2; trpt->o_pm &= ~16; printf("%%3ld: fairness undo Rule 3, _a_t=%%d\n", /* at least one move that was preselected at this */ /* level, blocked or was a loop control flow point */ if ((trpt->tau&32) && (_n == 0 || (trpt->tau&16))) /* preselected move - no successors outside stack */ if ((trpt->tau&32) && !(trpt->tau&64)) { From = FROM_P; To = UPTO_P; printf("%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\n", depth, II+1, _n, trpt->tau); _n = 0; trpt->tau &= ~(16|32|64); if (MORE_P) /* II already decremented */ goto Resume; else goto Again; /* level, blocked or truncated at the next level */ depth, II+1, (int) _n, trpt->tau); if (a_cycles && (trpt->tau&16)) { if (!(now._a_t&1)) printf("%%3ld: setting proviso bit\n", depth); (trpt-1)->proviso = 1; trpt->proviso = 1; if ((trpt-1)->ostate) ((char *)&((trpt-1)->ostate->state))[0] |= 128; ((char *)&(trpt->ostate->state))[0] |= 128; (trpt-1)->ostate->proviso = 1; trpt->ostate->proviso = 1; From = FROM_P; To = UPTO_P; _n = 0; trpt->tau &= ~(16|32|64); goto Again; /* do full search */ } /* else accept reduction */ { From = FROM_P; To = UPTO_P; _n = 0; trpt->tau &= ~(16|32|64); if (MORE_P) /* II already decremented */ goto Resume; if (_n == 0 || ((trpt->tau&4) && (trpt->tau&2))) cpu_printf("%%3ld: no move [II=%%d, tau=%%d, boq=%%d]\n", depth, II, trpt->tau, boq); /* ok if a rendez-vous fails: */ if (boq != -1) goto Done; /* ok if no procs or we're at maxdepth */ if ((now._nr_pr == 0 && (!strict || qs_empty())) || endstate() || depth >= maxdepth-1) goto Done; /* undo change from 5.2.3 */ if ((trpt->tau&8) && !(trpt->tau&4)) { trpt->tau &= ~(1|8); /* 1=timeout, 8=atomic */ From = FROM_P; To = UPTO_P; cpu_printf("%%3ld: atomic step proc %%d unexecutable\n", depth, II+1); trpt->tau |= 4; /* switch to claim */ goto AllOver; if (!(trpt->tau&1)) /* didn't try timeout yet */ if (trpt->tau&4)#ifndef NTIM if (trpt->tau&2) /* requested */ { trpt->tau |= 1; trpt->tau &= ~2; cpu_printf("%%d: timeout\n", depth); goto Stutter; { /* only claim can enable timeout */ if ((trpt->tau&8) && !((trpt-1)->tau&4))/* blocks inside an atomic */ goto BreakOut; cpu_printf("%%d: req timeout\n", depth); (trpt-1)->tau |= 2; /* request */ cpu_printf("%%d: timeout\n", depth); trpt->tau |= 1;BreakOut:#ifndef NOSTUTTER if (!(trpt->tau&4)) { trpt->tau |= 4; /* claim stuttering */ trpt->tau |= 128; /* stutter mark */ cpu_printf("%%d: claim stutter\n", depth); goto Stutter; ; if (!noends && !a_cycles && !endstate()) { depth--; trpt--; /* new 4.2.3 */ uerror("invalid end state"); else if (a_cycles && (trpt->o_pm&2)) /* new 4.2.4 */ { depth--; trpt--; uerror("accept stutter");Done: if (!(trpt->tau&8)) /* not in atomic seqs */#ifndef MA if (boq == -1 && (((trpt->tau&4) && !(trpt->tau&128)) || ( (trpt-1)->tau&128))) if (boq == -1)#if defined(FULLSTACK) printf("%%d: zapping %%u (%%d)\n", depth, trpt->ostate, (trpt->ostate)?trpt->ostate->tagged:0); onstack_zap(); printf("%%d: zapping\n", depth); if (trpt->proviso) gstore((char *) &now, vsize, 1); if (_n != 0 /* --after-- a program-step, i.e., */ /* after backtracking a claim-step */ && (trpt->tau&4) /* with at least one running process */ /* unless in a stuttered accept state */ && ((now._nr_pr > 1) || (trpt->o_pm&2)) && !(now._a_t&1)) if (fairness) cpu_printf("Consider check %%d %%d...\n", now._a_t, now._cnt[0]); if ((now._a_t&2) /* A-bit */ && (now._cnt[0] == 1)) checkcycles(); if (a_cycles && (trpt->o_pm&2)) checkcycles(); if (depth > 0)} void new_state(void) { /* place holder */ }assert(int a, char *s, int ii, int tt, Trans *t) if (!a && !noasserts) { char bad[1024]; strcpy(bad, "assertion violated "); if (strlen(s) > 1000) { strncpy(&bad[19], (const char *) s, 1000); bad[1019] = '\0'; strcpy(&bad[19], s); uerror(bad);#ifndef NOBOUNDCHECKBoundcheck(int x, int y, int a1, int a2, Trans *a3) assert((x >= 0 && x < y), "- invalid array index", a1, a2, a3); return x;wrap_stats(void) if (nShadow>0) printf("%%9.8g states, stored (%%g visited)\n", nstates - nShadow, nstates); printf("%%9.8g states, stored\n", nstates); printf(" %%8g nominal states (- rv and atomic)\n", nstates-midrv-nlinks+revrv); printf(" %%8g rvs succeeded\n", midrv-failedrv); printf(" %%8g nominal states (stored-atomic)\n", nstates-nlinks); printf(" %%8g midrv\n", midrv); printf(" %%8g failedrv\n", failedrv); printf(" %%8g revrv\n", revrv); printf("%%9.8g states, matched\n", truncs); printf("%%9.8g matches within stack\n",truncs2); printf("%%9.8g transitions (= visited+matched)\n", nstates+truncs); printf("%%9.8g transitions (= stored+matched)\n", printf("%%9.8g atomic steps\n", nlinks); if (nlost) printf("%%g lost messages\n", (double) nlost); #ifndef MA printf("hash conflicts: %%9.8g (resolved)\n", hcmp); #ifndef AUTO_RESIZE if (hcmp > (double) (1< 100.)\n\n", (double)(((double) udmem) * 8.0) / (double) nstates); (double)(1<<(ssize-8)) / (double) nstates * 256.0); printf("bits set per state: %%u (-k%%u)\n", hfns, hfns); #if 0 { printf("total bits available: %%8g (-M%%ld)\n", ((double) udmem) * 8.0, udmem/(1024L*1024L)); printf("total bits available: %%8g (-w%%d)\n", ((double) (ONE_L << (ssize-4)) * 16.0), ssize); printf("bfs disk reads: %%ld writes %%ld -- diff %%ld\n", bfs_dsk_reads, bfs_dsk_writes, bfs_dsk_writes-bfs_dsk_reads); if (bfs_dsk_read >= 0) (void) close(bfs_dsk_read); if (bfs_dsk_write >= 0) (void) close(bfs_dsk_write); (void) unlink("pan_bfs_dsk.tmp");wrapup(void)#if 1 double nr1, nr2, nr3 = 0.0, nr4, nr5 = 0.0; #if !defined(MA) && (defined(MEMCNT) || defined(MEMLIM)) int mverbose = 1; int mverbose = verbose; if (verbose) cpu_printf("wrapup -- %%d error(s)\n", errors); if (core_id != 0) void dsk_stats(void); if (search_terminated != NULL) { *search_terminated |= 2; /* wrapup */ exit(0); /* normal termination, not an error */ signal(SIGINT, SIG_DFL); printf("\n(%%s)\n", SpinVersion); if (!done) printf("Warning: Search not completed\n"); (void) unlink((const char *)stackfile); if (a_cycles) { printf(" + Multi-Core (NCORE=%%d)\n", NCORE); { printf(" + Multi-Core (NCORE=%%d -z%%d)\n", NCORE, z_handoff); printf(" + Using Breadth-First Search\n"); printf(" + Partial Order Reduction\n"); printf(" + Reverse Depth-First Search Order\n");#ifdef T_REVERSE printf(" + Reverse Transition Ordering\n"); printf(" + Randomized Transition Ordering\n"); printf(" + Randomized Process Ordering\n"); printf(" + Scheduling Restriction (-L%%d)\n", sched_max);#ifdef COLLAPSE printf(" + Compression\n"); printf(" + Graph Encoding (-DMA=%%d)\n", MA); #ifdef R_XPT printf(" Restarted from checkpoint %%s.xpt\n", PanSource); #endif #ifdef FULLSTACK printf(" + FullStack Matching\n"); #ifdef CNTRSTACK printf(" + CntrStack Matching\n"); printf("\nBit statespace search for:\n");#ifdef HC printf("\nHash-Compact %%d search for:\n", HC); printf("\nFull statespace search for:\n"); printf(" notrace assertion +\n"); printf(" trace assertion +\n"); printf(" never claim +\n"); printf(" assertion violations "); if (noasserts) printf("- (disabled by -A flag)\n"); printf("+ (if within scope of claim)\n");#ifdef NOCLAIM printf(" never claim - (not selected)\n"); printf(" never claim - (none specified)\n"); printf("+\n"); printf(" non-progress cycles "); printf(" acceptance cycles "); printf("+ (fairness %%sabled)\n", fairness?"en":"dis"); else printf("- (not selected)\n"); printf(" cycle checks - (disabled by -DSAFETY)\n"); printf(" invalid end states - "); printf("(disabled by "); if (noends) printf("-E flag)\n\n"); printf("never claim)\n\n"); printf(" invalid end states "); printf("- (disabled by -E flag)\n\n"); printf("+\n\n"); printf("State-vector %%d byte, depth reached %%ld", hmax, (nr_handoffs * z_handoff) + mreached); printf(", errors: %%d\n", errors); if (done) { extern void dfa_stats(void); if (maxgs+a_cycles+2 < MA) printf("MA stats: -DMA=%%d is sufficient\n", maxgs+a_cycles+2); dfa_stats(); wrap_stats(); printf("stackframes: %%d/%%d\n\n", smax, svmax); printf("stats: fa %%ld, fh %%ld, zh %%ld, zn %%ld - ", Fa, Fh, Zh, Zn); printf("check %%ld holds %%ld\n", Ccheck, Cholds); printf("stack stats: puts %%ld, probes %%ld, zaps %%ld\n", PUT, PROBE, ZAPS);#if !defined(BITSTATE) && defined(NOCOMP) if (!verbose) { goto jump_here; } nr1 = (nstates-nShadow)* (double)(hmax+sizeof(struct H_el)-sizeof(unsigned)); #ifdef BFS nr2 = 0.0; nr2 = (double) ((maxdepth+3)*sizeof(Trail)); #ifndef BITSTATE#if !defined(MA) || defined(COLLAPSE) nr3 = (double) (ONE_L<1 && !defined(SEP_STATE) tmp_nr -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE; if (tmp_nr < 0.0) tmp_nr = 0.; printf("Stats on memory usage (in Megabytes):\n"); printf("%%9.3f equivalent memory usage for states", nr1/1048576.); /* 1024*1024=1048576 */ printf(" (stored*(State-vector + overhead))\n"); #if NCORE>1 && !defined(WIN32) && !defined(WIN64) printf("%%9.3f shared memory reserved for state storage\n", mem_reserved/1048576.); #ifdef SEP_HEAP printf(" in %%d local heaps of %%7.3f MB each\n", NCORE, mem_reserved/(NCORE*1048576.)); if (udmem) printf("%%9.3f memory used for hash array (-M%%ld)\n", nr3/1048576., udmem/(1024L*1024L)); printf("%%9.3f memory used for hash array (-w%%d)\n", nr3/1048576., ssize); if (nr5 > 0.0) printf("%%9.3f memory used for bit stack\n", nr5/1048576.); remainder = remainder - nr3 - nr5; printf("%%9.3f actual memory usage for states", tmp_nr/1048576.); remainder -= tmp_nr; printf(" ("); if (tmp_nr > 0.) { if (tmp_nr > nr1) printf("unsuccessful "); printf("compression: %%.2f%%%%)\n", (100.0*tmp_nr)/nr1); printf("less than 1k)\n"); { printf(" state-vector as stored = %%.0f byte", (tmp_nr)/(nstates-nShadow) - (double) (sizeof(struct H_el) - sizeof(unsigned))); printf(" + %%ld byte overhead\n", (long int) sizeof(struct H_el)-sizeof(unsigned)); printf("%%9.3f memory used for hash table (-w%%d)\n", remainder -= nr3; printf("%%9.3f memory used for DFS stack (-m%%ld)\n", nr2/1048576., maxdepth); remainder -= nr2; remainder -= ((double) NCORE * LWQ_SIZE) + GWQ_SIZE; printf("%%9.3f shared memory used for work-queues\n", (GWQ_SIZE + (double) NCORE * LWQ_SIZE) /1048576.); printf(" in %%d queues of %%7.3f MB each", NCORE, (double) LWQ_SIZE /1048576.); #ifndef NGQ printf(" + a global q of %%7.3f MB\n", (double) GWQ_SIZE / 1048576.); if (remainder - fragment > 1048576.) printf("%%9.3f other (proc and chan stacks)\n", (remainder-fragment)/1048576.); if (fragment > 1048576.) printf("%%9.3f memory lost to fragmentation\n", fragment/1048576.); printf("%%9.3f total actual memory usage\n\n", memcnt/1048576.);jump_here: printf("%%9.3f memory usage (Mbyte)\n\n", printf("nr of templates: [ globals chans procs ]\n"); printf("collapse counts: [ "); { int i; for (i = 0; i < 256+2; i++) if (ncomps[i] != 0) printf("%%d ", ncomps[i]); printf("]\n"); if ((done || verbose) && !no_rck) do_reach(); { int i; printf("\nPeg Counts (transitions executed):\n"); for (i = 1; i < NTRANS; i++) { if (peg[i]) putpeg(i, peg[i]); } }#ifdef VAR_RANGES dumpranges(); if (vprefix > 0) close(svfd); printf("%%g loopstates hit\n", cnt_loops); dump_succ();#if NCORE>1 && defined(T_ALERT) crash_report();stopped(int arg){ printf("Interrupted\n"); was_interrupted = 1; wrapup();#ifdef SFH * super fast hash, based on Paul Hsieh's function * http://www.azillionmonkeys.com/qed/hash.html#include #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) #define get16bits(d) (*((const uint16_t *) (d))) #ifndef get16bits #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ +(uint32_t)(((const uint8_t *)(d))[0]) )d_sfh(const char *s, int len){ uint32_t h = len, tmp; int rem; rem = len & 3; len >>= 2; for ( ; len > 0; len--) { h += get16bits(s); tmp = (get16bits(s+2) << 11) ^ h; h = (h << 16) ^ tmp; s += 2*sizeof(uint16_t); h += h >> 11; switch (rem) { case 3: h += get16bits(s); h ^= h << 16; h ^= s[sizeof(uint16_t)] << 18; h += h >> 11; break; case 2: h += get16bits(s); h ^= h << 11; h += h >> 17; case 1: h += *s; h ^= h << 10; h += h >> 1; h ^= h << 3; h += h >> 5; h ^= h << 4; h += h >> 17; h ^= h << 25; h += h >> 6; K1 = h;#if defined(HASH64) || defined(WIN64)/* 64-bit Jenkins hash, 1997 * http://burtleburtle.net/bob/c/lookup8.c#define mix(a,b,c) \{ a -= b; a -= c; a ^= (c>>43); \ b -= c; b -= a; b ^= (a<<9); \ c -= a; c -= b; c ^= (b>>8); \ a -= b; a -= c; a ^= (c>>38); \ b -= c; b -= a; b ^= (a<<23); \ c -= a; c -= b; c ^= (b>>5); \ a -= b; a -= c; a ^= (c>>35); \ b -= c; b -= a; b ^= (a<<49); \ c -= a; c -= b; c ^= (b>>11); \ a -= b; a -= c; a ^= (c>>12); \ b -= c; b -= a; b ^= (a<<18); \ c -= a; c -= b; c ^= (b>>22); \/* 32-bit Jenkins hash, 2006 * http://burtleburtle.net/bob/c/lookup3.c#define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))){ a -= c; a ^= rot(c, 4); c += b; \ b -= a; b ^= rot(a, 6); a += c; \ c -= b; c ^= rot(b, 8); b += a; \ a -= c; a ^= rot(c,16); c += b; \ b -= a; b ^= rot(a,19); a += c; \ c -= b; c ^= rot(b, 4); b += a; \#define final(a,b,c) \{ c ^= b; c -= rot(b,14); \ a ^= c; a -= rot(c,11); \ b ^= a; b -= rot(a,25); \ c ^= b; c -= rot(b,16); \ a ^= c; a -= rot(c,4); \ b ^= a; b -= rot(a,14); \ c ^= b; c -= rot(b,24); \d_hash(uchar *kb, int nbytes){ uint8_t *bp; uint64_t a = 0, b, c, n; uint64_t *k = (uint64_t *) kb; uint32_t a, b, c, n; uint32_t *k = (uint32_t *) kb; /* extend to multiple of words, if needed */ n = nbytes/WS; /* nr of words */ a = nbytes - (n*WS); if (a > 0) { n++; bp = kb + nbytes; switch (a) { case 3: *bp++ = 0; /* fall thru */ case 2: *bp++ = 0; /* fall thru */ case 1: *bp = 0; case 0: break; b = HASH_CONST[HASH_NR]; c = 0x9e3779b97f4a7c13LL; /* arbitrary value */ while (n >= 3) { a += k[0]; b += k[1]; c += k[2]; mix(a,b,c); n -= 3; k += 3; c += (((uint64_t) nbytes)<<3); switch (n) { case 2: b += k[1]; case 1: a += k[0]; case 0: break; mix(a,b,c); a = c = 0xdeadbeef + (n<<2); while (n > 3) switch (n) { case 3: c += k[2]; final(a,b,c); j1_spin = c&nmask; j3 = a&7; /* 1st bit */ j2 = b&nmask; j4 = (a>>3)&7; /* 2nd bit */ K1 = c; K2 = b;s_hash(uchar *cp, int om)#if defined(SFH) d_sfh((const char *) cp, om); /* sets K1 */ d_hash(cp, om); /* sets K1 etc */ if (S_Tab == H_tab) j1_spin = K1 %% omaxdepth; if (ssize < 8*WS) j1_spin = K1&mask; j1_spin = K1;#ifndef RANDSTORint *prerand;inirand(void) srand(123); /* fixed startpoint */ prerand = (int *) emalloc((omaxdepth+3)*sizeof(int)); for (i = 0; i < omaxdepth+3; i++) prerand[i] = rand();pan_rand(void){ if (!prerand) inirand(); return prerand[depth];set_masks(void) /* 4.2.5 */ if (WS == 4 && ssize >= 32) { mask = 0xffffffff; switch (ssize) { case 34: nmask = (mask>>1); break; case 33: nmask = (mask>>2); break; default: nmask = (mask>>3); break; nmask = mask; } else if (WS == 8) { mask = ((ONE_L<>3; } else if (WS != 4) { fprintf(stderr, "pan: wordsize %%ld not supported\n", (long int) WS); } else /* WS == 4 and ssize < 32 */ nmask = (mask>>3);static long reclaim_size;static char *reclaim_mem; #error cannot combine AUTO_RESIZE with NCORE>1 yetstatic struct H_el **N_tab;reverse_capture(struct H_el *p){ if (!p) return; reverse_capture(p->nxt); /* last element of list moves first */ /* to preserve list-order */ j2 = p->m_K1; if (ssize < 8*WS) /* probably always true */ { j2 &= mask; p->nxt = N_tab[j2]; N_tab[j2] = p;resize_hashtable(void) if (WS == 4 && ssize >= 27 - 1) { return; /* canot increase further */ ssize += 2; /* 4x size */ printf("pan: resizing hashtable to -w%%d.. ", ssize); N_tab = (struct H_el **) emalloc((ONE_L<0) s_rand = T_RAND;#elif defined(P_RAND) && (P_RAND>0) s_rand = P_RAND; { char *ptr = strrchr(argv[0], '/'); if (ptr == NULL) { ptr = argv[0]; { ptr++; progname = emalloc(strlen(ptr)); strcpy(progname, ptr); /* printf("progname: %%s\n", progname); */ bstore = bstore_reg; /* default */ { int i, j; strcpy(o_cmdline, ""); for (j = 1; j < argc; j++) { strcat(o_cmdline, argv[j]); strcat(o_cmdline, " "); /* printf("Command Line: %%s\n", o_cmdline); */ if (strlen(o_cmdline) >= sizeof(o_cmdline)) { Uerror("option list too long"); while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { case 'a': fprintf(efd, "error: -a disabled"); usage(efd); break; case 'a': a_cycles = 1; break; case 'A': noasserts = 1; break; case 'b': bounded = 1; break; case 'C': coltrace = 1; goto samething; case 'c': upto = atoi(&argv[1][2]); break; case 'd': state_tables++; break; case 'e': every_error = 1; upto = 0; Nr_Trails = 1; break; case 'E': noends = 1; break; case 'F': if (strlen(argv[1]) > 2) stackfile = &argv[1][2]; break;#if !defined(SAFETY) && !defined(NOFAIR) case 'f': fairness = 1; break; case 'g': gui = 1; goto samething; case 'h': if (!argv[1][2]) usage(efd); else HASH_NR = atoi(&argv[1][2])%%100; break; case 'I': iterative = 2; every_error = 1; break; case 'i': iterative = 1; every_error = 1; break; case 'J': like_java = 1; break; /* Klaus Havelund */ case 'k': hfns = atoi(&argv[1][2]); break; case 'L': sched_max = atoi(&argv[1][2]); if (sched_max > 255) /* stored as one byte */ { fprintf(efd, "warning: using max bound (255)\n"); sched_max = 255; #ifndef NOREDUCE if (sched_max == 0) { fprintf(efd, "warning: with (default) bound -L0, "); fprintf(efd, "using -DNOREDUCE performs better\n"); case 'l': a_cycles = 1; break; case 'l': fprintf(efd, "error: -l disabled"); case 'M': udmem = atoi(&argv[1][2]); break; case 'G': udmem = atoi(&argv[1][2]); udmem *= 1024; break; case 'M': case 'G': fprintf(stderr, "-M and -G affect only -DBITSTATE\n"); case 'm': maxdepth = atoi(&argv[1][2]); break; case 'n': no_rck = 1; break; case 'P': readtrail = 1; onlyproc = atoi(&argv[1][2]); if (argv[2][0] != '-') /* check next arg */ { trailfilename = argv[2]; argc--; argv++; /* skip next arg */ } case 'p': vprefix = atoi(&argv[1][2]); break;#if NCORE==1 case 'Q': quota = (double) 60.0 * (double) atoi(&argv[1][2]); #ifndef FREQ freq /= 10.; /* for better resolution */ case 'q': strict = 1; break; case 'R':#if defined(T_RAND) || defined(P_RAND) || defined(RANDSTOR) if (argv[1][2] == 'S') /* e.g., -RS76842 */ { s_rand = atoi(&argv[1][3]); { Nrun = atoi(&argv[1][2]); case 'r':samething: readtrail = 1; if (isdigit(argv[1][2])) whichtrail = atoi(&argv[1][2]); else if (argc > 2 && argv[2][0] != '-') /* check next arg */ case 'S': silent = 1; goto samething; case 's': hfns = 1; break; case 'T': TMODE = 0444; break; case 't': if (argv[1][2]) tprefix = &argv[1][2]; break; case 'V': start_timer(); printf("Generated by %%s\n", SpinVersion); to_compile(); pan_exit(2); break; case 'v': verbose++; break; case 'w': ssize = atoi(&argv[1][2]); break; case 'Y': signoff = 1; break; case 'X': efd = stdout; break; case 'x': exclusive = 1; break; /* -B ip is passthru to proxy of remote ip address: */ case 'B': argc--; argv++; break; case 'Q': worker_pids[0] = atoi(&argv[1][2]); break; /* -Un means that the nth worker should be instantiated as a proxy */ case 'U': proxy_pid = atoi(&argv[1][2]); break; /* -W means that this copy is started by a cluster-server as a remote */ /* this flag is passed to ./pan_proxy, which interprets it */ case 'W': remote_party++; break; case 'Z': core_id = atoi(&argv[1][2]); if (verbose) { printf("cpu%%d: pid %%d parent %%d\n", core_id, getpid(), worker_pids[0]); case 'z': z_handoff = atoi(&argv[1][2]); break; case 'z': break; /* ignored for single-core */ default : fprintf(efd, "saw option -%%c\n", argv[1][1]); usage(efd); break; argc--; argv++; if (iterative && TMODE != 0666) { TMODE = 0666; fprintf(efd, "warning: -T ignored when -i or -I is used\n");#if defined(HASH32) && !defined(SFH) if (WS > 4) { fprintf(efd, "strong warning: compiling -DHASH32 on a 64-bit machine\n"); fprintf(efd, " without -DSFH can slow down performance a lot\n"); if (TMODE == 0666) TMODE = _S_IWRITE | _S_IREAD; TMODE = _S_IREAD; store_proxy_pid = proxy_pid; /* for checks in mem_file() and someone_crashed() */ if (core_id != 0) { proxy_pid = 0; } #ifndef SEP_STATE if (core_id == 0 && a_cycles) { fprintf(efd, "hint: this search may be more efficient "); fprintf(efd, "if pan.c is compiled -DSEP_STATE\n"); if (z_handoff < 0) { z_handoff = 20; /* conservative default - for non-liveness checks */#if defined(NGQ) || defined(LWQ_FIXED) LWQ_SIZE = (double) (128.*1048576.); LWQ_SIZE = (double) ( z_handoff + 2.) * (double) sizeof(SM_frame); #if NCORE>2 { fprintf(efd, "warning: the intended nr of cores to be used in liveness mode is 2\n"); #ifndef SEP_STATE fprintf(efd, "warning: without -DSEP_STATE there is no guarantee that all liveness violations are found\n"); #ifdef HAS_HIDDEN #error cannot use hidden variables when compiling multi-core if (hfns <= 0) { hfns = 1; fprintf(efd, "warning: using -k%%d as minimal usable value\n", hfns); omaxdepth = maxdepth; if (WS == 4 && ssize > 34) { ssize = 34; fprintf(efd, "warning: using -w%%d as max usable value\n", ssize); * -w35 would not work: 35-3 = 32 but 1^31 is the largest * power of 2 that can be represented in an unsigned long if (WS == 4 && ssize > 27) { ssize = 27; * for emalloc, the lookup table size multiplies by 4 for the pointers * the largest power of 2 that can be represented in a ulong is 1^31 * hence the largest number of lookup table slots is 31-4 = 27 hiwater = HHH = maxdepth-10; DDD = HHH/2; if (!stackfile) { stackfile = (char *) emalloc(strlen(PanSource)+4+1); sprintf(stackfile, "%%s._s_", PanSource); if (iterative) { fprintf(efd, "error: cannot use -i or -I with -DSC\n");#if (defined(R_XPT) || defined(W_XPT)) && !defined(MA) #warning -DR_XPT and -DW_XPT assume -DMA (ignored) if (iterative && a_cycles) fprintf(efd, "warning: -i or -I work for safety properties only\n"); #ifdef SC #error -DBFS not compatible with -DSC #ifdef HAS_LAST #error -DBFS not compatible with _last #ifdef HAS_STACK #error cannot use c_track UnMatched with BFS #ifdef BCS #error -DBFS not compatible with -DBCS #ifdef REACH #warning -DREACH is redundant when -DBFS is used #ifdef P_RAND #error cannot combine -DBCS and -DP_RAND #error cannot combine -DBCS and -DBFS#if defined(MERGED) && defined(PEG) #error to use -DPEG use: spin -o3 -a #ifdef SFH #error cannot combine -DHC and -DSFH /* use of NOCOMP is the real reason */ #ifdef NOCOMP #error cannot combine -DHC and -DNOCOMP #ifdef BITSTATE #error cannot combine -DHC and -DBITSTATE#if defined(SAFETY) && defined(NP) #error cannot combine -DNP and -DBFS or -DSAFETY #error cannot combine -DMA and -DBITSTATE #if MA <= 0 #error usage: -DMA=N with N > 0 and N < VECTORSZ #error cannot combine -DBITSTATE and -DCOLLAPSE #error cannot combine -DCOLLAPSE and -DSFH #error cannot combine -DCOLLAPSE and -DNOCOMP if (maxdepth <= 0 || ssize <= 1) usage(efd);#if SYNC>0 && !defined(NOREDUCE) if (a_cycles && fairness) { fprintf(efd, "error: p.o. reduction not compatible with "); fprintf(efd, "fairness (-f) in models\n"); fprintf(efd, " with rendezvous operations: "); fprintf(efd, "recompile with -DNOREDUCE\n"); pan_exit(1);#if defined(REM_VARS) && !defined(NOREDUCE) #warning p.o. reduction not compatible with remote varrefs (use -DNOREDUCE)#if defined(NOCOMP) && !defined(BITSTATE) { fprintf(efd, "error: use of -DNOCOMP voids -l and -a\n");#ifdef MEMLIM memlim = ((double) MEMLIM) * (double) (1<<20); /* size in Mbyte */ if (Nrun > 1) HASH_NR = Nrun - 1; if (Nrun < 1 || Nrun > 32) { fprintf(efd, "error: invalid arg for -R\n"); usage(efd); if (fairness && !a_cycles) { fprintf(efd, "error: -f requires -a or -l\n"); #if ACCEPT_LAB==0 { fprintf(efd, "error: no accept labels defined "); fprintf(efd, "in model (for option -a)\n"); #ifdef HAS_ENABLED #error use of enabled() requires -DNOREDUCE #ifdef HAS_PCVALUE #error use of pcvalue() requires -DNOREDUCE #ifdef HAS_BADELSE #error use of 'else' combined with i/o stmnts requires -DNOREDUCE #if defined(HAS_LAST) && !defined(BCS) #error use of _last requires -DNOREDUCE #ifdef HAS_UNLESS fprintf(efd, "warning: use of a rendezvous stmnts in the escape\n"); fprintf(efd, " of an unless clause, if present, could make p.o. reduction\n"); fprintf(efd, " invalid (use -DNOREDUCE to avoid this)\n"); #ifdef BFS fprintf(efd, " (this type of rv is also not compatible with -DBFS)\n");#if SYNC>0 && defined(BFS) #warning use of rendezvous with BFS does not preserve all invalid endstates#if !defined(REACH) && !defined(BITSTATE) if (iterative != 0 && a_cycles == 0) { fprintf(efd, "warning: -i and -I need -DREACH to work accurately\n");#if defined(BITSTATE) && defined(REACH) #warning -DREACH is voided by -DBITSTATE#if defined(MA) && defined(REACH) #warning -DREACH is voided by -DMA#if defined(FULLSTACK) && defined(CNTRSTACK) #error cannot combine -DFULLSTACK and -DCNTRSTACK#if defined(VERI) #if ACCEPT_LAB>0 #ifndef BFS if (!a_cycles #ifdef HAS_CODE && !readtrail #endif #if NCORE>1 && core_id == 0 && !state_tables) { fprintf(efd, "warning: never claim + accept labels "); fprintf(efd, "requires -a flag to fully verify\n"); if (!state_tables { fprintf(efd, "warning: verification in BFS mode "); fprintf(efd, "is restricted to safety properties\n"); if (!a_cycles #ifdef HAS_CODE && !state_tables) { fprintf(efd, "hint: this search is more efficient "); fprintf(efd, "if pan.c is compiled -DSAFETY\n"); #ifndef NOCOMP { S_A = 0; { if (!fairness) { S_A = 1; /* _a_t */ } else /* _a_t and _cnt[NFAIR] */ { S_A = (&(now._cnt[0]) - (uchar *) &now) + NFAIR - 2; /* -2 because first two uchars in now are masked */ signal(SIGINT, stopped); set_masks(); trail = (Trail *) emalloc(6*sizeof(Trail)); trail += 3; trail = (Trail *) emalloc((maxdepth+3)*sizeof(Trail)); trail++; /* protect trpt-1 refs at depth 0 */ { char nm[64]; sprintf(nm, "%%s.svd", PanSource); if ((svfd = creat(nm, TMODE)) < 0) { fprintf(efd, "couldn't create %%s\n", nm); vprefix = 0;#if SYNC>0 && ASYNC==0 set_recvs(); run(); done = 1;usage(FILE *fd) fprintf(fd, "%%s\n", SpinVersion); fprintf(fd, "Valid Options are:\n"); fprintf(fd, " -a -> is disabled by -DNP "); fprintf(fd, "(-DNP compiles for -l only)\n"); fprintf(fd, " -a find acceptance cycles\n"); fprintf(fd, " -a,-l,-f -> are disabled by -DSAFETY\n"); fprintf(fd, " -A ignore assert() violations\n"); fprintf(fd, " -b consider it an error to exceed the depth-limit\n"); fprintf(fd, " -cN stop at Nth error "); fprintf(fd, "(defaults to -c1)\n"); fprintf(fd, " -d print state tables and stop\n"); fprintf(fd, " -e create trails for all errors\n"); fprintf(fd, " -E ignore invalid end states\n"); fprintf(fd, " -Ffile use 'file' to store disk-stack\n"); fprintf(fd, " -f add weak fairness (to -a or -l)\n"); fprintf(fd, " -hN use different hash-seed N:1..32\n"); fprintf(fd, " -i search for shortest path to error\n"); fprintf(fd, " -I like -i, but approximate and faster\n"); fprintf(fd, " -J reverse eval order of nested unlesses\n"); fprintf(fd, " -kN set N bits per state (defaults to 3)\n"); fprintf(fd, " -LN set scheduling restriction to N (default 10)\n"); fprintf(fd, " -l find non-progress cycles\n"); fprintf(fd, " -l find non-progress cycles -> "); fprintf(fd, "disabled, requires "); fprintf(fd, "compilation with -DNP\n"); fprintf(fd, " -MN use N Megabytes for bitstate hash array\n"); fprintf(fd, " -GN use N Gigabytes for bitstate hash array\n"); fprintf(fd, " -mN max depth N steps (default=10k)\n"); fprintf(fd, " -n no listing of unreached states\n"); fprintf(fd, " -pN create svfile (save N bytes per state)\n"); fprintf(fd, " -QN set time-limit on execution of N minutes\n"); fprintf(fd, " -q require empty chans in valid end states\n"); fprintf(fd, " -r read and execute trail - can add -v,-n,-PN,-g,-C\n"); fprintf(fd, " -rN read and execute N-th error trail\n"); fprintf(fd, " -C read and execute trail - columnated output (can add -v,-n)\n"); fprintf(fd, " -PN read and execute trail - restrict trail output to proc N\n"); fprintf(fd, " -g read and execute trail + msc gui support\n"); fprintf(fd, " -S silent replay: only user defined printfs show\n"); fprintf(fd, " -RSN use randomization seed N\n"); fprintf(fd, " -RN repeat run Nx with N "); fprintf(fd, "[1..32] independent hash functions\n"); fprintf(fd, " -s same as -k1 (single bit per state)\n"); fprintf(fd, " -T create trail files in read-only mode\n"); fprintf(fd, " -tsuf replace .trail with .suf on trailfiles\n"); fprintf(fd, " -V print SPIN version number\n"); fprintf(fd, " -v verbose -- filenames in unreached state listing\n"); fprintf(fd, " -wN hashtable of 2^N entries "); fprintf(fd, "(defaults to -w%%d)\n", ssize); fprintf(fd, " -x do not overwrite an existing trail file\n"); fprintf(fd, " -zN handoff states below depth N to 2nd cpu (multi_core)\n"); fprintf(fd, "\n options -r, -C, -PN, -g, and -S can optionally be followed by\n"); fprintf(fd, " a filename argument, as in '-r filename', naming the trailfile\n"); multi_usage(fd); exit(1);Malloc(unsigned long n){ char *tmp; if (memcnt+ (double) n > memlim) goto err; tmp = (char *) malloc(n); if (!tmp) /* on linux machines, a large amount of memory is set aside * for malloc, whether it is used or not * using sbrk would make this memory arena inaccessible * the reason for using sbrk was originally to provide a * small additional speedup (since this memory is never released) tmp = (char *) sbrk(n); if (tmp == (char *) -ONE_L)err: printf("pan: out of memory\n"); printf(" %%g bytes used\n", memcnt); printf(" %%g bytes more needed\n", (double) n); printf(" %%g bytes limit\n", memlim); printf("hint: to reduce memory, recompile with\n"); printf(" -DMA=%%d # better/slower compression, or\n", hmax); printf(" -DBITSTATE # supertrace, approximation\n");#ifndef HC printf(" -DCOLLAPSE # good, fast compression, or\n"); printf(" -DHC # hash-compaction, approximation\n"); #ifdef FULL_TRAIL printf(" omit -DFULL_TRAIL or use pan -c0 to reduce memory\n"); #ifdef SEP_STATE printf("hint: to reduce memory, recompile without\n"); printf(" -DSEP_STATE # may be faster, but uses more memory\n"); memcnt += (double) n; return tmp;#define CHUNK (100*VECTORSZ)emalloc(unsigned long n) /* never released or reallocated */ if (n == 0) return (char *) NULL; if (n&(sizeof(void *)-1)) /* for proper alignment */ n += sizeof(void *)-(n&(sizeof(void *)-1)); if ((unsigned long) left < n) { grow = (n < CHUNK) ? CHUNK : n; have = Malloc(grow); fragment += (double) left; left = grow; tmp = have; have += (long) n; left -= (long) n; memset(tmp, 0, n);Uerror(char *str){ /* always fatal */ uerror(str); sudden_stop("Uerror");#if defined(MA) && !defined(SAFETY)Unwind(void){ Trans *t; uchar ot, _m; int tt; short II; int i; uchar oat = now._a_t; now._a_t &= ~(1|16|32); memcpy((char *) &comp_now, (char *) &now, vsize); now._a_t = oat; trpt = getframe(depth); printf("%%d State: ", depth); for (i = 0; i < vsize; i++) printf("%%d%%s,", ((char *)&now)[i], Mask[i]?"*":""); if (trpt->o_pm&128) /* fairness alg */ { now._cnt[now._a_t&1] = trpt->bup.oval; depth--; trpt = getframe(depth); trpt--; goto Q999; { int d; Trail *trl; now._last = 0; for (d = 1; d < depth; d++) { trl = getframe(depth-d); /* was trl = (trpt-d); */ if (trl->pr != 0) { now._last = trl->pr - BASE; break; } } } now._last = (depth<1)?0:(trpt-1)->pr; now._event = trpt->o_event; if ((now._a_t&1) && depth <= A_depth) { now._a_t &= ~(1|16|32); if (fairness) now._a_t |= 2; /* ? */ A_depth = 0; goto CameFromHere; /* checkcycles() */ t = trpt->o_t; ot = trpt->o_ot; II = trpt->pr; tt = trpt->o_tt; this = pptr(II); _m = do_reverse(t, II, trpt->o_m); printf("%%3ld: proc %%d ", depth, II); printf("reverses %%d, %%d to %%d,", t->forw, tt, t->st); printf(" %%s [abit=%%d,adepth=%%d,", t->tp, now._a_t, A_depth); printf("tau=%%d,%%d] \n", trpt->tau, (trpt-1)->tau); depth--; trpt--; /* reached[ot][t->st] = 1; 3.4.13 */ ((P0 *)this)->_p = tt; if ((trpt->o_pm&32)) if (now._cnt[now._a_t&1] == 0) now._cnt[now._a_t&1] = 1;Q999: now._a_t |= 2;CameFromHere: if (memcmp((char *) &now, (char *) &comp_now, vsize) == 0) return depth; if (depth > 0) goto Up;static char unwinding;uerror(char *str){ static char laststr[256]; int is_cycle; if (unwinding) return; /* 1.4.2 */ if (strncmp(str, laststr, 254)) cpu_printf("pan:%%d: %%s (at depth %%ld)\n", errors+1, str, printf("pan:%%d: %%s (at depth %%ld)\n", errors+1, str, (nr_handoffs * z_handoff) + ((depthfound==-1)?depth:depthfound)); strncpy(laststr, str, 254); errors++; if (readtrail) { wrap_trail(); return; } is_cycle = (strstr(str, " cycle") != (char *) 0); if (!is_cycle) if ((every_error != 0) || errors == upto) if (is_cycle) { int od = depth; unwinding = 1; depthfound = Unwind(); unwinding = 0; depth = od; writing_trail = 1; if (depth > 1) trpt--; nuerror(str); if (depth > 1) trpt++; putrail(); if (strstr(str, " cycle")) { if (every_error) printf("sorry: MA writes 1 trail max\n"); wrapup(); /* no recovery from unwind */ { *search_terminated |= 4; /* uerror */ writing_trail = 0; { depth--; trpt--; /* undo */ if (iterative != 0 && maxdepth > 0) { if (maxdepth > depth) { maxdepth = (iterative == 1)?(depth+1):(depth/2); /* was ...?(depth-1):... GH 5.2.3 */ warned = 1; printf("pan: reducing search depth to %%ld\n", maxdepth); sudden_stop("uerror"); depthfound = -1;xrefsrc(int lno, S_F_MAP *mp, int M, int i){ Trans *T; int j, retval=1; for (T = trans[M][i]; T; T = T->nxt) if (T && T->tp) { if (strcmp(T->tp, ".(goto)") == 0 || strncmp(T->tp, "goto :", 6) == 0) return 1; /* not reported */ printf("\tline %%d", lno); for (j = 0; j < sizeof(mp); j++) if (i >= mp[j].from && i <= mp[j].upto) { printf(", \"%%s\"", mp[j].fnm); printf(", state %%d", i); if (strcmp(T->tp, "") != 0) { char *q; q = transmognify(T->tp); printf(", \"%%s\"", q?q:""); } else if (stopstate[M][i]) printf(", -end state-"); retval = 0; /* reported */ return retval;r_ck(uchar *which, int N, int M, short *src, S_F_MAP *mp){ int i, m=0; if (M == VERI && !verbose) return; printf("unreached in proctype %%s\n", procname[M]); for (i = 1; i < N; i++) if (which[i] == 0 && (mapstate[M][i] == 0 || which[mapstate[M][i]] == 0)) m += xrefsrc((int) src[i], mp, M, i); else m++; printf(" (%%d of %%d states)\n", N-1-m, N-1);#if NCORE>1 && !defined(SEP_STATE)static long rev_trail_cnt;#ifdef FULL_TRAILrev_trail(int fd, volatile Stack_Tree *st_tr){ long j; char snap[64]; if (!st_tr) { return; rev_trail(fd, st_tr->prv); printf("%%d (%%d) LRT [%%d,%%d] -- %%9u (root %%9u)\n", depth, rev_trail_cnt, st_tr->pr, st_tr->t_id, st_tr, stack_last[core_id]); if (st_tr->pr != 255) { sprintf(snap, "%%ld:%%d:%%d\n", rev_trail_cnt++, st_tr->pr, st_tr->t_id); { printf("pan: error writing trailfile\n"); close(fd); wrapup(); } else /* handoff point */ { if (a_cycles) { (void) write(fd, "-1:-1:-1\n", 9);putrail(void)#if defined VERI || defined(MERGED) char snap[64];#if NCORE==1 || defined(SEP_STATE) || !defined(FULL_TRAIL) long i, j; Trail *trl; fd = make_trail(); if (write(fd, snap, strlen(snap)) < 0) return;#if NCORE>1 && !defined(SEP_STATE) && defined(FULL_TRAIL) rev_trail_cnt = 1; enter_critical(GLOBAL_LOCK); rev_trail(fd, stack_last[core_id]); i = 1; /* trail starts at position 1 */ #if NCORE>1 && defined(SEP_STATE) if (cur_Root.m_vsize > 0) { i++; depth++; } for ( ; i <= depth; i++) { if (i == depthfound+1) { if (write(fd, "-1:-1:-1\n", 9) != 9) { goto notgood; trl = getframe(i); if (!trl->o_t) continue; if (trl->o_pm&128) continue; sprintf(snap, "%%ld:%%d:%%d\n", i, trl->pr, trl->o_t->t_id);notgood: printf("pan: error writing trailfile\n"); cpu_printf("pan: wrote trailfile\n");sv_save(void) /* push state vector onto save stack */{ if (!svtack->nxt) { svtack->nxt = (Svtack *) emalloc(sizeof(Svtack)); svtack->nxt->body = emalloc(vsize*sizeof(char)); svtack->nxt->lst = svtack; svtack->nxt->m_delta = vsize; svmax++; } else if (vsize > svtack->nxt->m_delta) { svtack->nxt->body = emalloc(vsize*sizeof(char)); svtack = svtack->nxt; svtack->o_boq = boq; svtack->o_delta = vsize; /* don't compress */ memcpy((char *)(svtack->body), (char *) &now, vsize); cpu_printf("%%d: sv_save\n", depth);sv_restor(void) /* pop state vector from save stack */ memcpy((char *)&now, svtack->body, svtack->o_delta); boq = svtack->o_boq;#ifdef HAS_STACK c_unstack((uchar *) &(svtack->c_stack[0])); c_revert((uchar *) &(now.c_state[0])); if (vsize != svtack->o_delta) Uerror("sv_restor"); if (!svtack->lst) Uerror("error: v_restor"); svtack = svtack->lst; cpu_printf(" sv_restor\n");p_restor(int h){ int i; char *z = (char *) &now; proc_offset[h] = stack->o_offset; proc_skip[h] = (uchar) stack->o_skip;#ifndef XUSAFE p_name[h] = stack->o_name; for (i = vsize + stack->o_skip; i > vsize; i--) Mask[i-1] = 1; /* align */ vsize += stack->o_skip; memcpy(z+vsize, stack->body, stack->o_delta); vsize += stack->o_delta; now._vsz = vsize; for (i = 1; i <= Air[((P0 *)pptr(h))->_t]; i++) Mask[vsize - i] = 1; /* pad */ Mask[proc_offset[h]] = 1; /* _pid */ if (BASE > 0 && h > 0) ((P0 *)pptr(h))->_pid = h-BASE; ((P0 *)pptr(h))->_pid = h; i = stack->o_delqs; now._nr_pr += 1; if (!stack->lst) /* debugging */ Uerror("error: p_restor"); stack = stack->lst; this = pptr(h); while (i-- > 0) q_restor();q_restor(void){ char *z = (char *) &now; int k, k_end; q_offset[now._nr_qs] = stack->o_offset; q_skip[now._nr_qs] = (uchar) stack->o_skip; q_name[now._nr_qs] = stack->o_name; now._nr_qs += 1; k_end = stack->o_offset; k = k_end - stack->o_skip; if (q_zero(now._nr_qs)) k_end += stack->o_delta; for ( ; k < k_end; k++) Mask[k] = 1; Uerror("error: q_restor");typedef struct IntChunks { int *ptr; struct IntChunks *nxt;} IntChunks;IntChunks *filled_chunks[512];IntChunks *empty_chunks[512];int *grab_ints(int nr){ IntChunks *z; if (nr >= 512) Uerror("cannot happen grab_int"); if (filled_chunks[nr]) { z = filled_chunks[nr]; filled_chunks[nr] = filled_chunks[nr]->nxt; } else { z = (IntChunks *) emalloc(sizeof(IntChunks)); z->ptr = (int *) emalloc(nr * sizeof(int)); z->nxt = empty_chunks[nr]; empty_chunks[nr] = z; return z->ptr;ungrab_ints(int *p, int nr) if (!empty_chunks[nr]) Uerror("cannot happen ungrab_int"); z = empty_chunks[nr]; empty_chunks[nr] = empty_chunks[nr]->nxt; z->ptr = p; z->nxt = filled_chunks[nr]; filled_chunks[nr] = z;delproc(int sav, int h){ int d, i=0; int o_vsize = vsize; if (h+1 != (int) now._nr_pr) return 0; while (now._nr_qs && q_offset[now._nr_qs-1] > proc_offset[h]) { delq(sav); d = vsize - proc_offset[h]; if (sav) { if (!stack->nxt) { stack->nxt = (Stack *) emalloc(sizeof(Stack)); stack->nxt->body = emalloc(Maxbody*sizeof(char)); stack->nxt->lst = stack; smax++; stack = stack->nxt; stack->o_offset = proc_offset[h]; stack->o_skip = (int) proc_skip[h]; stack->o_skip = (short) proc_skip[h]; stack->o_name = p_name[h]; stack->o_delta = d; stack->o_delqs = i; memcpy(stack->body, (char *)pptr(h), d); vsize = proc_offset[h]; now._nr_pr = now._nr_pr - 1; memset((char *)pptr(h), 0, d); vsize -= (int) proc_skip[h]; for (i = vsize; i < o_vsize; i++) Mask[i] = 0; /* reset */delq(int sav){ int h = now._nr_qs - 1; int d = vsize - q_offset[now._nr_qs - 1]; int k, o_vsize = vsize; stack->o_offset = q_offset[h]; stack->o_skip = (int) q_skip[h]; stack->o_skip = (short) q_skip[h]; stack->o_name = q_name[h]; memcpy(stack->body, (char *)qptr(h), d); vsize = q_offset[h]; now._nr_qs = now._nr_qs - 1; memset((char *)qptr(h), 0, d); vsize -= (int) q_skip[h]; for (k = vsize; k < o_vsize; k++) Mask[k] = 0; /* reset */qs_empty(void) for (i = 0; i < (int) now._nr_qs; i++) { if (q_sz(i) > 0) return 0;endstate(void){ int i; P0 *ptr; for (i = BASE; i < (int) now._nr_pr; i++) { ptr = (P0 *) pptr(i); if (!stopstate[ptr->_t][ptr->_p]) if (strict) return qs_empty();#if defined(EVENT_TRACE) && !defined(OTIM) if (!stopstate[EVENT_TRACE][now._event] && !a_cycles) { printf("pan: event_trace not completed\n");checkcycles(void){ uchar o_a_t = now._a_t; uchar o_cnt = now._cnt[1]; struct H_el *sv = trpt->ostate; /* save */ uchar prov = trpt->proviso; /* save */ { int i; uchar *v = (uchar *) &now; printf(" set Seed state "); if (fairness) printf("(cnt = %%d:%%d, nrpr=%%d) ", now._cnt[0], now._cnt[1], now._nr_pr); /* for (i = 0; i < n; i++) printf("%%d,", v[i]); */ printf("\n"); printf("%%ld: cycle check starts\n", depth); now._a_t |= (1|16|32); /* 1 = 2nd DFS; (16|32) to help hasher */ now._cnt[1] = now._cnt[0]; memcpy((char *)&A_Root, (char *)&now, vsize); A_depth = depthfound = depth; mem_put_acc(); new_state(); /* start 2nd DFS */ now._a_t = o_a_t; now._cnt[1] = o_cnt; A_depth = 0; depthfound = -1; printf("%%ld: cycle check returns\n", depth); trpt->ostate = sv; /* restore */ trpt->proviso = prov;#endif struct H_el *Free_list = (struct H_el *) 0;onstack_init(void) /* to store stack states in a bitstate search */{ S_Tab = (struct H_el **) emalloc(maxdepth*sizeof(struct H_el *));struct H_el *grab_state(int n){ struct H_el *v, *last = 0; if (H_tab == S_Tab) { for (v = Free_list; v && ((int) v->tagged >= n); v=v->nxt) { if ((int) v->tagged == n) { if (last) last->nxt = v->nxt;gotcha: Free_list = v->nxt; v->tagged = 0; v->nxt = 0; v->ln = 0; return v; Fh++; last=v; /* new: second try */ v = Free_list; if (v && ((int) v->tagged >= n)) goto gotcha; ngrabs++; return (struct H_el *) emalloc(sizeof(struct H_el)+n-sizeof(unsigned));{ struct H_el *grab_shared(int); return grab_shared(sizeof(struct H_el)+n-sizeof(unsigned)); #ifndef AUTO_RESIZE #define grab_state(n) (struct H_el *) \ emalloc(sizeof(struct H_el)+n-sizeof(unsigned long)); struct H_el * grab_state(int n) { struct H_el *p; int cnt = sizeof(struct H_el)+n-sizeof(unsigned long); if (reclaim_size >= cnt+WS) { if ((cnt & (WS-1)) != 0) /* alignment */ { cnt += WS - (cnt & (WS-1)); p = (struct H_el *) reclaim_mem; reclaim_mem += cnt; reclaim_size -= cnt; memset(p, 0, cnt); { p = (struct H_el *) emalloc(cnt); return p; }unsigned longordinal(char *v, long n, short tp){ struct H_el *tmp, *ntmp; long m; struct H_el *olst = (struct H_el *) 0; s_hash((uchar *)v, n); enter_critical(CS_ID); /* uses spinlock - 1..128 */ tmp = H_tab[j1_spin]; { tmp = grab_state(n); H_tab[j1_spin] = tmp; for ( ;; olst = tmp, tmp = tmp->nxt) { m = memcmp(((char *)&(tmp->state)), v, n); if (n == tmp->ln) if (m == 0) goto done; if (m < 0)Insert: ntmp = grab_state(n); ntmp->nxt = tmp; if (!olst) H_tab[j1_spin] = ntmp; olst->nxt = ntmp; tmp = ntmp; } else if (!tmp->nxt)Append: tmp->nxt = grab_state(n); tmp = tmp->nxt; if (n < tmp->ln) goto Insert; else if (!tmp->nxt) goto Append; m = ++ncomps[tp]; tmp->tagged = m; tmp->st_id = m;#if defined(AUTO_RESIZE) && !defined(BITSTATE) tmp->m_K1 = K1; memcpy(((char *)&(tmp->state)), v, n); tmp->ln = n;done: leave_critical(CS_ID); /* uses spinlock */ return tmp->tagged; return tmp->st_id;compress(char *vin, int nin) /* collapse compression */{ char *w, *v = (char *) &comp_now; int i, j; unsigned long n; static char *x; static uchar nbytes[513]; /* 1 + 256 + 256 */ static unsigned short nbytelen; long col_q(int, char *); long col_p(int, char *); *v++ = now._a_t; if (fairness) for (i = 0; i < NFAIR; i++) *v++ = now._cnt[i]; nbytelen = 0;#ifndef JOINPROCS { n = col_p(i, (char *) 0);#ifdef NOFIX nbytes[nbytelen] = 0; nbytes[nbytelen] = 1; *v++ = ((P0 *) pptr(i))->_t; *v++ = n&255; if (n >= (1<<8)) { nbytes[nbytelen]++; *v++ = (n>>8)&255; if (n >= (1<<16)) *v++ = (n>>16)&255; if (n >= (1<<24)) *v++ = (n>>24)&255; nbytelen++; x = scratch; x += col_p(i, x); n = ordinal(scratch, x-scratch, 2); /* procs */ *v++ = n&255; nbytes[nbytelen] = 0; if (n >= (1<<8)) { nbytes[nbytelen]++; *v++ = (n>>8)&255; if (n >= (1<<16)) *v++ = (n>>16)&255; if (n >= (1<<24)) *v++ = (n>>24)&255; nbytelen++;#ifdef SEPQS { n = col_q(i, (char *) 0);#ifdef NOVSZ /* 3 = _a_t, _nr_pr, _nr_qs */ w = (char *) &now + 3 * sizeof(uchar); w += NFAIR;#if VECTORSZ<65536 w = (char *) &(now._vsz) + sizeof(unsigned short); w = (char *) &(now._vsz) + sizeof(unsigned long); *x++ = now._nr_pr; *x++ = now._nr_qs; if (now._nr_qs > 0 && qptr(0) < pptr(0)) n = qptr(0) - (uchar *) w; n = pptr(0) - (uchar *) w; j = w - (char *) &now; for (i = 0; i < (int) n; i++, w++) if (!Mask[j++]) *x++ = *w;#ifndef SEPQS x += col_q(i, x); x--; for (i = 0, j = 6; i < nbytelen; i++) { if (j == 6) { j = 0; *(++x) = 0; j += 2; *x |= (nbytes[i] << j); x++; for (j = 0; j < WS-1; j++) *x++ = 0; x -= j; j = 0; n = ordinal(scratch, x-scratch, 0); /* globals */ if (n >= (1<< 8)) { *v++ = (n>> 8)&255; j++; } if (n >= (1<<16)) { *v++ = (n>>16)&255; j++; } if (n >= (1<<24)) { *v++ = (n>>24)&255; j++; } *v++ = j; /* add last count as a byte */ for (i = 0; i < WS-1; i++) *v++ = 0; v -= i; printf("collapse %%d -> %%d\n", vsize, v - (char *)&comp_now); return v - (char *)&comp_now;#if !defined(NOCOMP)compress(char *vin, int n) /* default compression */ int delta = 0; s_hash((uchar *)vin, n); /* sets K1 and K2 */ if (S_A) { delta++; /* _a_t */ if (S_A > NFAIR) delta += NFAIR; /* _cnt[] */ memcpy((char *) &comp_now + delta, (char *) &K1, WS); delta += WS;#if HC>0 memcpy((char *) &comp_now + delta, (char *) &K2, HC); delta += HC; return delta; char *vv = vin; char *v = (char *) &comp_now; #ifndef NO_FAST_C int r = 0, unroll = n/8; if (unroll > 0) { i = 0; while (r++ < unroll) { /* unroll 8 times, avoid ifs */ /* 1 */ *v = *vv++; v += 1 - Mask[i++]; /* 2 */ *v = *vv++; /* 3 */ *v = *vv++; /* 4 */ *v = *vv++; /* 5 */ *v = *vv++; /* 6 */ *v = *vv++; /* 7 */ *v = *vv++; /* 8 */ *v = *vv++; r = n - i; /* the rest, at most 7 */ switch (r) { case 7: *v = *vv++; v += 1 - Mask[i++]; case 6: *v = *vv++; v += 1 - Mask[i++]; case 5: *v = *vv++; v += 1 - Mask[i++]; case 4: *v = *vv++; v += 1 - Mask[i++]; case 3: *v = *vv++; v += 1 - Mask[i++]; case 2: *v = *vv++; v += 1 - Mask[i++]; case 1: *v = *vv++; v += 1 - Mask[i++]; r = (n+WS-1)/WS; /* words rounded up */ r *= WS; /* bytes */ i = r - i; /* remainder */ switch (i) { case 7: *v++ = 0; /* fall thru */ case 6: *v++ = 0; case 5: *v++ = 0; case 4: *v++ = 0; case 3: *v++ = 0; case 2: *v++ = 0; case 1: *v++ = 0; default: Uerror("unexpected wordsize"); v -= i; { for (i = 0; i < n; i++, vv++) if (!Mask[i]) *v++ = *vv; for (i = 0; i < WS-1; i++) *v++ = 0; printf("compress %%d -> %%d\n", n, v - (char *)&comp_now);#if defined(MA)#if !defined(onstack_now)int onstack_now(void) {}#if !defined(onstack_put)void onstack_put(void) {}#if !defined(onstack_zap)void onstack_zap(void) {}onstack_zap(void){ struct H_el *v, *w, *last = 0; struct H_el **tmp = H_tab; char *nv; int n, m; static char warned = 0; uchar was_last = now._last; now._last = 0; H_tab = S_Tab; nv = (char *) &comp_now; n = compress((char *)&now, vsize);#if defined(BITSTATE) && defined(LC) n = compact_stack((char *)&now, vsize); nv = (char *) &now; n = vsize;#if !defined(HC) && !(defined(BITSTATE) && defined(LC)) s_hash((uchar *)nv, n); H_tab = tmp; for (v = S_Tab[j1_spin]; v; Zh++, last=v, v=v->nxt) { m = memcmp(&(v->state), nv, n); if (m == 0) goto Found; if (m < 0)/* NotFound: */#ifndef ZAPH /* seen this happen, likely harmless in multicore */ if (warned == 0) { /* Uerror("stack out of wack - zap"); */ cpu_printf("pan: warning, stack incomplete\n"); goto done;Found: ZAPS++; if (last) last->nxt = v->nxt; S_Tab[j1_spin] = v->nxt; v->tagged = (unsigned) n;#if !defined(NOREDUCE) && !defined(SAFETY) v->proviso = 0; v->nxt = last = (struct H_el *) 0; for (w = Free_list; w; Fa++, last=w, w = w->nxt) { if ((int) w->tagged <= n) { if (last) { v->nxt = w; last->nxt = v; { v->nxt = Free_list; Free_list = v; goto done; if (!w->nxt) { w->nxt = v; Free_list = v; now._last = was_last; return;onstack_put(void){ struct H_el **tmp = H_tab; if (hstore((char *)&now, vsize) != 0) printf("pan: warning, double stack entry\n"); #ifndef ZAPH Uerror("cannot happen - unstack_put"); trpt->ostate = Lstate; PUT++;onstack_now(void){ struct H_el *tmp; struct H_el **tmp2 = H_tab; char *v; int n, m = 1; #ifdef NOCOMP v = (char *) &comp_now; v = (char *) &now; H_tab = tmp2; for (tmp = S_Tab[j1_spin]; tmp; Zn++, tmp = tmp->nxt) { m = memcmp(((char *)&(tmp->state)),v,n); if (m <= 0) { Lstate = (struct H_el *) tmp; PROBE++; return (m == 0);hinit(void) #ifdef MA#ifdef R_XPT { void r_xpoint(void); r_xpoint(); dfa_init((unsigned short) (MA+a_cycles));#if NCORE>1 && !defined(COLLAPSE) if (!readtrail) { void init_HT(unsigned long); init_HT(0L); #if !defined(MA) || defined(COLLAPSE) init_HT((unsigned long) (ONE_L<= MA) { printf("pan: error, MA too small, recompile pan.c"); printf(" with -DMA=N with N>%%d\n", n); Uerror("aborting"); if (n > (int) maxgs) { maxgs = (unsigned int) n; for (i = 0; i < n; i++) { Info[i] = v[i]; for ( ; i < MA-1; i++) { Info[i] = 0; Info[MA-1] = pbit; if (a_cycles) /* place _a_t at the end */ { Info[MA] = Info[0]; Info[0] = 0; enter_critical(GLOBAL_LOCK); /* crude, but necessary */ /* to make this mode work, also replace emalloc with grab_shared inside store MA routines */ if (!dfa_store(Info)) { if (pbit == 0 && (now._a_t&1) && depth > A_depth) { Info[MA] &= ~(1|16|32); /* _a_t */ if (dfa_member(MA)) { Info[MA-1] = 4; /* off-stack bit */ nShadow++; if (!dfa_member(MA-1)) { ret_val = 3; #ifdef VERBOSE printf("intersected 1st dfs stack\n"); goto done; ret_val = 0; printf("new state\n"); goto done; if (pbit == 0) { Info[MA-1] = 1; /* proviso bit */ trpt->proviso = dfa_member(MA-1); Info[MA-1] = 4; /* off-stack bit */ if (dfa_member(MA-1)) { ret_val = 1; /* off-stack */ printf("old state\n"); { ret_val = 2; /* on-stack */ printf("on-stack\n"); ret_val = 1; printf("old state\n"); return ret_val; /* old state */compact_stack(char *vin, int n){ int delta = 0; delta++; /* room for state[0] |= 128 */ memcpy((char *) &comp_now + delta, (char *) &K2, WS); delta += WS; /* use all available bits */hstore(char *vin, int nin) /* hash table storage */{ struct H_el *ntmp; struct H_el *tmp, *olst = (struct H_el *) 0; char *v; int n, m=0; uchar rem_a; { v = (char *) &comp_now; n = compact_stack(vin, nin); { v = vin; n = nin; v = vin; n = nin; #ifdef HC rem_a = now._a_t; now._a_t = 0; now._a_t = rem_a; { v[0] = 0; /* _a_t */ for (m = 0; m < NFAIR; m++) v[m+1] = 0; /* _cnt[] */ m = 0;#if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE) enter_critical(CS_ID); /* uses spinlock */ { tmp = grab_state(n); if (!tmp) { /* if we get here -- we've already issued a warning */ /* but we want to allow the normal distributed termination */ /* to collect the stats on all cpus in the wrapup */ #if !defined(SEP_STATE) && !defined(BITSTATE) leave_critical(CS_ID); return 1; /* allow normal termination */ } H_tab[j1_spin] = tmp; { for (;; hcmp++, olst = tmp, tmp = tmp->nxt) { /* skip the _a_t and the _cnt bytes */ if (tmp->ln != 0) { if (!tmp->nxt) goto Append; m = memcmp(((char *)&(tmp->state)) + S_A, v + S_A, n - S_A); if (m == 0) {#define wasnew 0 int wasnew = 0; if (S_A) { if ((((char *)&(tmp->state))[0] & V_A) != V_A) { wasnew = 1; nShadow++; ((char *)&(tmp->state))[0] |= V_A; } if (S_A > NFAIR) { /* 0 <= now._cnt[now._a_t&1] < MAXPROC */ unsigned ci, bp; /* index, bit pos */ ci = (now._cnt[now._a_t&1] / 8); bp = (now._cnt[now._a_t&1] - 8*ci); if (now._a_t&1) /* use tail-bits in _cnt */ { ci = (NFAIR - 1) - ci; bp = 7 - bp; /* bp = 0..7 */ ci++; /* skip over _a_t */ bp = 1 << bp; /* the bit mask */ if ((((char *)&(tmp->state))[ci] & bp)==0) { if (!wasnew) { wasnew = 1; nShadow++; ((char *)&(tmp->state))[ci] |= bp; /* else: wasnew == 0, i.e., old state */ Lstate = (struct H_el *) tmp; if (wasnew) tmp->tagged |= V_A; if ((now._a_t&1) && (tmp->tagged&A_V) && depth > A_depth)intersect: printf("1st dfs-stack intersected on state %%d+\n", (int) tmp->st_id); leave_critical(CS_ID); return 3; printf(" New state %%d+\n", (int) tmp->st_id); dumpstate(1, (char *)&(tmp->state),n,tmp->tagged); leave_critical(CS_ID); if ((S_A)?(tmp->tagged&V_A):tmp->tagged) /* already on current dfs stack */ /* but may also be on 1st dfs stack */ && depth > A_depth && (!fairness || now._cnt[1] <= 1) goto intersect; printf(" Stack state %%d\n", (int) tmp->st_id); dumpstate(0, (char *)&(tmp->state),n,tmp->tagged); return 2; /* match on stack */ dumpstate(1, (char *)&(tmp->state), n, 0); printf(" Old state %%d\n", (int) tmp->st_id); dumpstate(0, (char *)&(tmp->state), n, 0);#if defined(BCS) #ifdef CONSERVATIVE if (tmp->ctx_low > trpt->sched_limit) { tmp->ctx_low = trpt->sched_limit; tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%8); /* new */ #ifdef CHECK #if NCORE>1 printf("cpu%%d: ", core_id); printf(" Revisit with fewer context switches\n"); nstates--; #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE) } else if ((tmp->ctx_low == trpt->sched_limit && (tmp->ctx_pid[(now._last)/8] & ( 1 << ((now._last)%8) )) == 0 )) { tmp->ctx_pid[(now._last)/8] |= 1 << ((now._last)%8); /* add */ printf(" Revisit with same nr of context switches\n");#ifdef REACH if (tmp->D > depth) { tmp->D = depth; printf(" ReVisiting (from smaller depth)\n"); #if NCORE>1 && !defined(SEP_STATE) && !defined(BITSTATE)#if (defined(BFS) && defined(Q_PROVISO)) || NCORE>1 return 1; /* match outside stack */ } else if (m < 0) { /* insert state before tmp */ ntmp = grab_state(n); if (!ntmp) return 1; /* allow normal termination */ ntmp->nxt = tmp; if (!olst) H_tab[j1_spin] = ntmp; olst->nxt = ntmp; tmp = ntmp; } else if (!tmp->nxt) { /* append after tmp */Append: tmp->nxt = grab_state(n); if (!tmp->nxt) tmp = tmp->nxt; } } tmp->st_id = (unsigned) nstates; printf(" Push state %%d\n", ((int) nstates) - 1); printf(" New state %%d\n", (int) nstates); tmp->ctx_low = trpt->sched_limit; #ifdef CONSERVATIVE tmp->ctx_pid[(now._last)/8] = 1 << ((now._last)%8); /* new limit */#if !defined(SAFETY) || defined(REACH) tmp->D = depth; { v[0] = V_A; { unsigned ci, bp; /* as above */ if (now._a_t&1) v[1+ci] = 1 << bp; tmp->tagged = (S_A)?V_A:(depth+1); dumpstate(-1, v, n, tmp->tagged); Lstate = (struct H_el *) tmp; #ifdef DEBUG dumpstate(-1, v, n, 0);/* #if NCORE>1 && !defined(SEP_STATE) */ #ifdef V_PROVISO tmp->cpu_id = core_id;#include TRANSITIONSdo_reach(void)#if defined(BFS) && defined(REACH)#undef REACH#define BASE 1#define BASE 0typedef struct Trans { short atom; /* if &2 = atomic trans; if &8 local */ short escp[HAS_UNLESS]; /* lists the escape states */ short e_trans; /* if set, this is an escp-trans */ short tpe[2]; /* class of operation (for reduction) */ short qu[6]; /* for conditional selections: qid's */ uchar ty[6]; /* ditto: type's */ short om; /* completion status of preselects */ char *tp; /* src txt of statement */ int st; /* the nextstate */ int t_id; /* transition id, unique within proc */ int forw; /* index forward transition */ int back; /* index return transition */ struct Trans *nxt;} Trans; #define qptr(x) (((uchar *)&now)+(int)q_offset[x])#define pptr(x) (((uchar *)&now)+(int)proc_offset[x])extern uchar *Pptr(int);#define q_sz(x) (((Q0 *)qptr(x))->Qlen) #ifndef VECTORSZ#define VECTORSZ 1024 /* sv size in bytes */#ifndef CHECK#define CHECK#ifndef DEBUG#define DEBUG#define NOFAIR#ifdef NOREDUCE#define XUSAFE#if !defined(SAFETY) && !defined(MA)#define FULLSTACK#if defined(SAFETY) && !defined(HASH64)#define CNTRSTACK#define NOCOMP#if !defined(LC) && defined(SC)#define LC#if defined(COLLAPSE2) || defined(COLLAPSE3) || defined(COLLAPSE4)/* accept the above for backward compatibility */#define COLLAPSE#undef HC#define HC4#ifdef HC0#define HC 0#ifdef HC1#define HC 1#ifdef HC2#define HC 2#ifdef HC3#define HC 3#ifdef HC4#define HC 4unsigned long *ncomps; /* in shared memory */unsigned long ncomps[256+2];#define MAXQ 255#define MAXPROC 255typedef struct Stack { /* for queues and processes */ int o_delta; int o_offset; int o_skip; int o_delqs; short o_delta; short o_offset; short o_skip; short o_delqs; short o_boq; char *o_name; char *body; struct Stack *nxt; struct Stack *lst;} Stack; typedef struct Svtack { /* for complete state vector */ int m_delta; short o_delta; /* current size of frame */ short m_delta; /* maximum size of frame */ struct Svtack *nxt; struct Svtack *lst;} Svtack; Trans ***trans; /* 1 ptr per state per proctype */ struct H_el *Lstate;int depthfound = -1; /* loop detection */int proc_offset[MAXPROC];int q_offset[MAXQ];short proc_offset[MAXPROC];short q_offset[MAXQ];uchar proc_skip[MAXPROC];uchar q_skip[MAXQ];unsigned long vsize; /* vector size in bytes */int vprefix=0, svfd; /* runtime option -pN */char *tprefix = "trail"; /* runtime option -tsuffix */short boq = -1; /* blocked_on_queue status */typedef struct State { uchar _nr_pr; uchar _nr_qs; uchar _a_t; /* cycle detection */ uchar _cnt[NFAIR]; /* counters, weak fairness */ unsigned short _vsz; unsigned long _vsz; uchar _last; /* pid executed in last step */#if defined(BITSTATE) && defined(BCS) && defined(STORE_CTX) uchar _ctx; /* nr of context switches so far */#if nstates_event<256 uchar _event; unsigned short _event;){ int j, h = now._nr_pr; int k; uchar *o_this = this; if (TstOnly) return (h < MAXPROC);/* redefine Index only within this procedure */#undef Index#define Index(x, y) Boundcheck(x, y, 0, 0, 0) if (h >= MAXPROC) Uerror("too many processes"); case 0: j = sizeof(P0); break; default: Uerror("bad proc - addproc"); if (vsize%%WS) proc_skip[h] = WS-(vsize%%WS); proc_skip[h] = 0; for (k = vsize + (int) proc_skip[h]; k > vsize; k--) Mask[k-1] = 1; /* align */ vsize += (int) proc_skip[h]; proc_offset[h] = vsize; { int dummy = 0; write(svfd, (uchar *) &dummy, sizeof(int)); /* mark */ write(svfd, (uchar *) &h, sizeof(int)); write(svfd, (uchar *) &n, sizeof(int)); write(svfd, (uchar *) &proc_offset[h], sizeof(int)); write(svfd, (uchar *) &now, vprefix-4*sizeof(int)); /* padd */ write(svfd, (uchar *) &proc_offset[h], sizeof(short)); write(svfd, (uchar *) &now, vprefix-3*sizeof(int)-sizeof(short)); /* padd */#if defined(BCS) && defined(CONSERVATIVE) if (now._nr_pr >= CONSERVATIVE*8) { printf("pan: error: too many processes -- recompile with "); printf("-DCONSERVATIVE=%%d\n", CONSERVATIVE+1); if (fairness && ((int) now._nr_pr + 1 >= (8*NFAIR)/2)) { printf("pan: error: too many processes -- current"); printf(" max is %%d procs (-DNFAIR=%%d)\n", (8*NFAIR)/2 - 2, NFAIR); printf("\trecompile with -DNFAIR=%%d\n", NFAIR+1); vsize += j; for (k = 1; k <= Air[n]; k++) Mask[vsize - k] = 1; /* pad */ Mask[vsize-j] = 1; /* _pid */ hmax = max(hmax, vsize); if (vsize >= VECTORSZ) { printf("pan: error, VECTORSZ too small, recompile pan.c"); printf(" with -DVECTORSZ=N with N>%%d\n", (int) vsize); memset((char *)pptr(h), 0, j); ((P0 *)this)->_pid = h-BASE; ((P0 *)this)->_pid = h;addqueue(int n, int is_rv){ int j=0, i = now._nr_qs; if (i >= MAXQ) Uerror("too many queues"); default: Uerror("bad queue - addqueue"); q_skip[i] = WS-(vsize%%WS); q_skip[i] = 0; k = vsize; if (is_rv) k += j; for (k += (int) q_skip[i]; k > vsize; k--) Mask[k-1] = 1; vsize += (int) q_skip[i]; q_offset[i] = vsize; Uerror("VECTORSZ is too small, edit pan.h"); if (j > 0) { memset((char *)qptr(i), 0, j); ((Q0 *)qptr(i))->_t = n; return i+1;{ int j; uchar *z; #ifdef HAS_SORTED if (!into--) uerror("ref to uninitialized chan name (sending)"); if (into >= (int) now._nr_qs || into < 0) Uerror("qsend bad queue#"); z = qptr(into); j = ((Q0 *)qptr(into))->Qlen; switch (((Q0 *)qptr(into))->_t) { case 0: printf("queue %%d was deleted\n", into+1); default: Uerror("bad queue - qsend"); if (in_s_scope(into+1)) require('s', into);q_zero(int from){ if (!from--) { uerror("ref to uninitialized chan name (q_zero)"); switch(((Q0 *)qptr(from))->_t) { case 0: printf("queue %%d was deleted\n", from+1); Uerror("bad queue q-zero");not_RV(int from){ if (q_zero(from)) { printf("==>> a test of the contents of a rv "); printf("channel always returns FALSE\n"); uerror("error to poll rendezvous channel");setq_claim(int x, int m, char *s, int y, char *p){ if (x == 0) uerror("x[rs] claim on uninitialized channel"); if (x < 0 || x > MAXQ) Uerror("cannot happen setq_claim"); q_claim[x] |= m; p_name[y] = p; q_name[x] = s; if (m&2) q_S_check(x, y); if (m&1) q_R_check(x, y);short q_sender[MAXQ+1];q_S_check(int x, int who){ if (!q_sender[x]) { q_sender[x] = who+1; if (q_zero(x)) { printf("chan %%s (%%d), ", q_name[x], x-1); printf("sndr proc %%s (%%d)\n", p_name[who], who); uerror("xs chans cannot be used for rv"); if (q_sender[x] != who+1) { printf("pan: xs assertion violated: "); printf("access to chan <%%s> (%%d)\npan: by ", q_name[x], x-1); if (q_sender[x] > 0 && p_name[q_sender[x]-1]) printf("%%s (proc %%d) and by ", p_name[q_sender[x]-1], q_sender[x]-1); printf("%%s (proc %%d)\n", p_name[who], who); uerror("error, partial order reduction invalid");short q_recver[MAXQ+1];q_R_check(int x, int who){ if (!q_recver[x]) { q_recver[x] = who+1; printf("recv proc %%s (%%d)\n", uerror("xr chans cannot be used for rv"); if (q_recver[x] != who+1) { printf("pan: xr assertion violated: "); printf("access to chan %%s (%%d)\npan: ", if (q_recver[x] > 0 && p_name[q_recver[x]-1]) printf("by %%s (proc %%d) and ", p_name[q_recver[x]-1], q_recver[x]-1); printf("by %%s (proc %%d)\n",q_len(int x){ if (!x--) uerror("ref to uninitialized chan name (len)"); return ((Q0 *)qptr(x))->Qlen;q_full(int from) uerror("ref to uninitialized chan name (qfull)"); Uerror("bad queue - q_full");q_e_f(int from){ /* empty or full */ return !q_len(from) || q_full(from);#if NQS>0qrecv(int from, int slot, int fld, int done){ uchar *z; int j, k, r=0; if (!from--) uerror("ref to uninitialized chan name (receiving)"); if (from >= (int) now._nr_qs || from < 0) Uerror("qrecv bad queue#"); z = qptr(from); if (done && (in_r_scope(from+1))) require('r', from); switch (((Q0 *)qptr(from))->_t) { default: Uerror("bad queue - qrecv"); return r;longcol_q(int i, char *z){ int j=0, k; char *x, *y; Q0 *ptr = (Q0 *) qptr(i); switch (ptr->_t) {run(void){ /* int i; */ memset((char *)&now, 0, sizeof(State)); vsize = (unsigned long) (sizeof(State) - VECTORSZ);/* optional provisioning statements, e.g. to *//* set hidden variables, used as constants */#ifdef PROV#include PROV settable(); Maxbody = max(Maxbody, ((int) sizeof(P%d))); reached[%d] = reached%d; accpstate[%d] = (uchar *) emalloc(nstates%d); progstate[%d] = (uchar *) emalloc(nstates%d); loopstate%d = loopstate[%d] = (uchar *) emalloc(nstates%d); stopstate[%d] = (uchar *) emalloc(nstates%d); visstate[%d] = (uchar *) emalloc(nstates%d); mapstate[%d] = (short *) emalloc(nstates%d * sizeof(short)); NrStates[%d] = nstates%d; stopstate[%d][endstate%d] = 1; retrans(%d, nstates%d, start%d, src_ln%d, reached%d, loopstate%d); if (state_tables) { printf("\nTransition Type: "); printf("A=atomic; D=d_step; L=local; G=global\n"); printf("Source-State Labels: "); printf("p=progress; e=end; a=accept;\n"); printf("Note: statement merging was used. Only the first\n"); printf(" stmnt executed in each merge sequence is shown\n"); printf(" (use spin -a -o3 to disable statement merging)\n"); pan_exit(0); #define ACCEPT_LAB 1 /* at least 1 in np_ */ #define ACCEPT_LAB %d /* user-defined accept labels */#ifdef MEMCNT #ifdef MEMLIM #warning -DMEMLIM takes precedence over -DMEMCNT #undef MEMCNT #if MEMCNT<20 #warning using minimal value -DMEMCNT=20 (=1MB) #define MEMLIM (1) #undef MEMCNT #if MEMCNT==20 #define MEMLIM (1) #undef MEMCNT #else #if MEMCNT>=50 #error excessive value for MEMCNT #else #define MEMLIM (1<<(MEMCNT-20)) #endif#if NCORE>1 && !defined(MEMLIM) #define MEMLIM (2048) /* need a default, using 2 GB */#define PROG_LAB %d /* progress labels */uchar *accpstate[%d];uchar *progstate[%d];uchar *loopstate[%d];uchar *reached[%d];uchar *stopstate[%d];uchar *visstate[%d];short *mapstate[%d];int NrStates[%d]; Maxbody = max(Maxbody, ((int) sizeof(Q%d))); r_ck(reached%d, nstates%d, %d, src_ln%d, src_file%d); case %d: j = sizeof(P%d); break; this = o_this; return h-BASE;#define Index(x, y) Boundcheck(x, y, II, tt, t)#if defined(BITSTATE) && defined(COLLAPSE)/* just to allow compilation, to generate the error */long col_p(int i, char *z) { return 0; }long col_q(int i, char *z) { return 0; }col_p(int i, char *z){ int j, k; unsigned long ordinal(char *, long, short); P0 *ptr = (P0 *) pptr(i); default: Uerror("bad proctype - collapse"); if (z) x = z; else x = scratch; y = (char *) ptr; k = proc_offset[i]; for ( ; j > 0; j--, y++) if (!Mask[k++]) *x++ = *y; x -= j; if (z) return (long) (x - z); return ordinal(scratch, x-scratch, (short) (2+ptr->_t)); default: Uerror("bad qtype - collapse"); y = (char *) ptr; k = q_offset[i]; /* no need to store the empty slots at the end */ j -= (q_max[ptr->_t] - ptr->Qlen) * ((j - 2)/q_max[ptr->_t]); return ordinal(scratch, x-scratch, 1); /* chan */ case %d: r = ((Q%d *)z)->contents[slot].fld%d; break;int unsend(int into){ int _m=0, j; uchar *z; uerror("ref to uninitialized chan (unsend)"); j = ((Q0 *)z)->Qlen; ((Q0 *)z)->Qlen = --j; default: Uerror("bad queue - unsend");unrecv(int from, int slot, int fld, int fldvar, int strt) uerror("ref to uninitialized chan (unrecv)"); if (strt) ((Q0 *)z)->Qlen = j+1;/** function prototypes **/char *emalloc(unsigned long);char *Malloc(unsigned long);int Boundcheck(int, int, int, int, Trans *);int addqueue(int, int);/* int atoi(char *); *//* int abort(void); */int close(int);int delproc(int, int);int endstate(void);int hstore(char *, int);int gstore(char *, int, uchar);int q_cond(short, Trans *);int q_full(int);int q_len(int);int q_zero(int);int qrecv(int, int, int, int);int unsend(int);/* void *sbrk(int); */void Uerror(char *);void assert(int, char *, int, int, Trans *);void c_chandump(int);void c_globals(void);void c_locals(int, int);void checkcycles(void);void crack(int, int, Trans *, short *);void d_sfh(const char *, int);void sfh(const char *, int);void d_hash(uchar *, int);void s_hash(uchar *, int);void r_hash(uchar *, int);void delq(int);void do_reach(void);void pan_exit(int);void exit(int);void hinit(void);void imed(Trans *, int, int, int);void new_state(void);void p_restor(int);void putpeg(int, int);void putrail(void);void q_restor(void);void retrans(int, int, int, short *, uchar *, uchar *);void settable(void);void setq_claim(int, int, char *, int, char *);void sv_restor(void);void sv_save(void);void tagtable(int, int, int, short *, uchar *);void do_dfs(int, int, int, short *, uchar *, uchar *);void uerror(char *);void unrecv(int, int, int, int, int);void usage(FILE *);void wrap_stats(void);int onstack_now(void);void onstack_init(void);void onstack_put(void);void onstack_zap(void);int q_S_check(int, int);int q_R_check(int, int);uchar q_claim[MAXQ+1];char *q_name[MAXQ+1];char *p_name[MAXPROC+1];to_compile(void){ char ctd[1024], carg[64]; strcpy(ctd, "-DBITSTATE "); strcpy(ctd, ""); strcat(ctd, "-DNOVSZ "); strcat(ctd, "-DREVERSE "); strcat(ctd, "-DT_REVERSE "); #if T_RAND>0 sprintf(carg, "-DT_RAND=%%d ", T_RAND); strcat(ctd, carg); strcat(ctd, "-DT_RAND "); #if P_RAND>0 sprintf(carg, "-DP_RAND=%%d ", P_RAND); strcat(ctd, "-DP_RAND "); sprintf(carg, "-DBCS=%%d ", BCS); strcat(ctd, "-DBFS "); sprintf(carg, "-DMEMLIM=%%d ", MEMLIM); sprintf(carg, "-DMEMCNT=%%d ", MEMCNT); strcat(ctd, "-DNOCLAIM "); strcat(ctd, "-DSAFETY ");#ifdef NOFAIR strcat(ctd, "-DNOFAIR ");#ifdef NFAIR if (NFAIR != 2) { sprintf(carg, "-DNFAIR=%%d ", NFAIR); strcat(ctd, carg); strcat(ctd, "-DNOREDUCE ");#ifdef XUSAFE strcat(ctd, "-DXUSAFE "); strcat(ctd, "-DNP "); strcat(ctd, "-DPEG "); strcat(ctd, "-DVAR_RANGES "); strcat(ctd, "-DHC0 "); strcat(ctd, "-DHC1 "); strcat(ctd, "-DHC2 "); strcat(ctd, "-DHC3 "); strcat(ctd, "-DHC4 "); strcat(ctd, "-DCHECK "); strcat(ctd, "-DCTL "); strcat(ctd, "-DNIBIS ");#ifdef NOBOUNDCHECK strcat(ctd, "-DNOBOUNDCHECK ");#ifdef NOSTUTTER strcat(ctd, "-DNOSTUTTER "); strcat(ctd, "-DREACH "); strcat(ctd, "-DPRINTF "); strcat(ctd, "-DOTIM "); strcat(ctd, "-DCOLLAPSE "); sprintf(carg, "-DMA=%%d ", MA); strcat(ctd, "-DSVDUMP ");#ifdef VECTORSZ if (VECTORSZ != 1024) { sprintf(carg, "-DVECTORSZ=%%d ", VECTORSZ); strcat(ctd, "-DVERBOSE "); strcat(ctd, "-DSDUMP "); sprintf(carg, "-DNCORE=%%d ", NCORE); sprintf(carg, "-DSFH ");#ifdef VMAX if (VMAX != 256) { sprintf(carg, "-DVMAX=%%d ", VMAX);#ifdef PMAX if (PMAX != 16) { sprintf(carg, "-DPMAX=%%d ", PMAX);#ifdef QMAX if (QMAX != 16) { sprintf(carg, "-DQMAX=%%d ", QMAX);#ifdef SET_WQ_SIZE sprintf(carg, "-DSET_WQ_SIZE=%%d ", SET_WQ_SIZE); printf("Compiled as: cc -o pan %%span.c\n", ctd);#ifndef _CONSOLE #define _CONSOLE #ifdef WIN64#undef long#include #define long long long#include #include #include /* code common to cygwin/linux and win32/win64: */ #define VVERBOSE (1) #define VVERBOSE (0)/* the following values must be larger than 256 and must fit in an int */#define QUIT 1024 /* terminate now command */#define QUERY 512 /* termination status query message */#define QUERY_F 513 /* query failed, cannot quit */#define GN_FRAMES (int) (GWQ_SIZE / (double) sizeof(SM_frame))#define LN_FRAMES (int) (LWQ_SIZE / (double) sizeof(SM_frame))#ifndef VMAX #define VMAX VECTORSZ#ifndef PMAX #define PMAX 64#ifndef QMAX #define QMAX 64 #define OFFT int #define OFFT short#ifdef SET_SEG_SIZE /* no longer usefule -- being recomputed for local heap size anyway */ double SEG_SIZE = (((double) SET_SEG_SIZE) * 1048576.); double SEG_SIZE = (1048576.*1024.); /* 1GB default shared memory pool segments */double LWQ_SIZE = 0.; /* initialized in main */ #warning SET_WQ_SIZE applies to global queue -- ignored double GWQ_SIZE = 0.; double GWQ_SIZE = (((double) SET_WQ_SIZE) * 1048576.); /* must match the value in pan_proxy.c, if used */ double GWQ_SIZE = (128.*1048576.); /* 128 MB default queue sizes *//* Crash Detection Parameters */#ifndef ONESECOND #define ONESECOND (1<<25)#ifndef SHORT_T #define SHORT_T (0.1)#ifndef LONG_T #define LONG_T (600)double OneSecond = (double) (ONESECOND); /* waiting for a free slot -- checks crash */double TenSeconds = 10. * (ONESECOND); /* waiting for a lock -- check for a crash *//* Termination Detection Params -- waiting for new state input in Get_Full_Frame */double Delay = ((double) SHORT_T) * (ONESECOND); /* termination detection trigger */double OneHour = ((double) LONG_T) * (ONESECOND); /* timeout termination detection */typedef struct SM_frame SM_frame;typedef struct SM_results SM_results;typedef struct sh_Allocater sh_Allocater;struct SM_frame { /* about 6K per slot */ volatile int m_vsize; /* 0 means free slot */ volatile int m_boq; /* >500 is a control message */ volatile struct Stack_Tree *m_stack; /* ptr to previous state */ volatile uchar m_tau; volatile uchar m_o_pm; volatile int nr_handoffs; /* to compute real_depth */ volatile char m_now [VMAX]; volatile char m_Mask [(VMAX + 7)/8]; volatile OFFT m_p_offset[PMAX]; volatile OFFT m_q_offset[QMAX]; volatile uchar m_p_skip [PMAX]; volatile uchar m_q_skip [QMAX];#if defined(C_States) && (HAS_TRACK==1) && (HAS_STACK==1) volatile uchar m_c_stack [StackSize];};int proxy_pid; /* id of proxy if nonzero -- receive half */int store_proxy_pid;short remote_party;int proxy_pid_snd; /* id of proxy if nonzero -- send half */char o_cmdline[512]; /* to pass options to children */int iamin[CS_NR+NCORE]; /* non-shared */int tas(volatile LONG *);HANDLE proxy_handle_snd; /* for Windows Create and Terminate */struct sh_Allocater { /* shared memory for states */ volatile char *dc_arena; /* to allocate states from */ volatile long pattern; /* to detect overruns */ volatile long dc_size; /* nr of bytes left */ volatile void *dc_start; /* where memory segment starts */ volatile void *dc_id; /* to attach, detach, remove shared memory segments */ volatile sh_Allocater *nxt; /* linked list of pools */DWORD worker_pids[NCORE]; /* root mem of pids of all workers created */HANDLE worker_handles[NCORE]; /* for windows Create and Terminate */void * shmid [NR_QS]; /* return value from CreateFileMapping */void * shmid_M; /* shared mem for state allocation in hashtable */#ifdef SEP_STATE void *shmid_X; void *shmid_S; /* shared bitstate arena or hashtable */int tas(volatile int *); volatile char *dc_start; /* where memory segment starts */ volatile int dc_id; /* to attach, detach, remove shared memory segments */int worker_pids[NCORE]; /* root mem of pids of all workers created */int shmid [NR_QS]; /* return value from shmget */int nibis = 0; /* set after shared mem has been released */int shmid_M; /* shared mem for state allocation in hashtable */ long shmid_X; int shmid_S; /* shared bitstate arena or hashtable */ volatile sh_Allocater *first_pool; /* of shared state memory */ volatile sh_Allocater *last_pool;struct SM_results { /* for shuttling back final stats */ volatile int m_vsize; /* avoid conflicts with frames */ volatile int m_boq; /* these 2 fields are not written in record_info */ /* probably not all fields really need to be volatile */ volatile double m_memcnt; volatile double m_nstates; volatile double m_truncs; volatile double m_truncs2; volatile double m_nShadow; volatile double m_nlinks; volatile double m_ngrabs; volatile double m_nlost; volatile double m_hcmp; volatile double m_frame_wait; volatile int m_hmax; volatile int m_svmax; volatile int m_smax; volatile int m_mreached; volatile int m_errors; volatile int m_VMAX; volatile short m_PMAX; volatile short m_QMAX; volatile uchar m_R; /* reached info for all proctypes */int core_id = 0; /* internal process nr, to know which q to use */unsigned long nstates_put = 0; /* statistics */unsigned long nstates_get = 0;int query_in_progress = 0; /* termination detection */double free_wait = 0.; /* waiting for a free frame */double frame_wait = 0.; /* waiting for a full frame */double lock_wait = 0.; /* waiting for access to cs */double glock_wait[3]; /* waiting for access to global lock */char *sprefix = "rst";uchar was_interrupted, issued_kill, writing_trail;static SM_frame cur_Root; /* current root, to be safe with error trails */SM_frame *m_workq [NR_QS]; /* per cpu work queues + global q */char *shared_mem[NR_QS]; /* return value from shmat */#ifdef SEP_HEAPchar *my_heap;long my_size;volatile sh_Allocater *dc_shared; /* assigned at initialization */static int vmax_seen, pmax_seen, qmax_seen;static double gq_tries, gq_hasroom, gq_hasnoroom;volatile int *prfree;volatile int *prfull;volatile int *prcnt;volatile int *prmax;volatile int *sh_lock; /* mutual exclusion locks - in shared memory */volatile double *is_alive; /* to detect when processes crash */volatile int *grfree, *grfull, *grcnt, *grmax; /* access to shared global q */volatile double *gr_readmiss, *gr_writemiss;static int lrfree; /* used for temporary recording of slot */static int dfs_phase2;void mem_put(int); /* handoff state to other cpu */void mem_put_acc(void); /* liveness mode */void mem_get(void); /* get state from work queue */void sudden_stop(char *);void enter_critical(int);void leave_critical(int);record_info(SM_results *r) uchar *ptr; if (0) { cpu_printf("nstates %%g nshadow %%g -- memory %%-6.3f Mb\n", nstates, nShadow, memcnt/(1048576.)); r->m_memcnt = 0; r->m_memcnt = 0; /* it's shared */ r->m_memcnt = memcnt; if (a_cycles && core_id == 1) { r->m_nstates = nstates; r->m_nShadow = nstates; r->m_nShadow = nShadow; r->m_truncs = truncs; r->m_truncs2 = truncs2; r->m_nlinks = nlinks; r->m_ngrabs = ngrabs; r->m_nlost = nlost; r->m_hcmp = hcmp; r->m_frame_wait = frame_wait; r->m_hmax = hmax; r->m_svmax = svmax; r->m_smax = smax; r->m_mreached = mreached; r->m_errors = errors; r->m_VMAX = vmax_seen; r->m_PMAX = (short) pmax_seen; r->m_QMAX = (short) qmax_seen; ptr = (uchar *) &(r->m_R); for (i = 0; i <= _NP_; i++) /* all proctypes */ { memcpy(ptr, reached[i], NrStates[i]*sizeof(uchar)); ptr += NrStates[i]*sizeof(uchar); if (verbose>1) { cpu_printf("Put Results nstates %%g (sz %%d)\n", nstates, ptr - &(r->m_R));retrieve_info(SM_results *r){ int i, j; volatile uchar *ptr; snapshot(); /* for a final report */ if (verbose) { printf("cpu%%d: local heap-left %%ld KB (%%d MB)\n", core_id, (int) (my_size/1024), (int) (my_size/1048576)); if (verbose && core_id == 0) { printf("qmax: "); for (i = 0; i < NCORE; i++) { printf("%%d ", prmax[i]);#ifndef NGQ printf("G: %%d", *grmax); memcnt += r->m_memcnt; nstates += r->m_nstates; nShadow += r->m_nShadow; truncs += r->m_truncs; truncs2 += r->m_truncs2; nlinks += r->m_nlinks; ngrabs += r->m_ngrabs; nlost += r->m_nlost; hcmp += r->m_hcmp; /* frame_wait += r->m_frame_wait; */ errors += r->m_errors; if (hmax < r->m_hmax) hmax = r->m_hmax; if (svmax < r->m_svmax) svmax = r->m_svmax; if (smax < r->m_smax) smax = r->m_smax; if (mreached < r->m_mreached) mreached = r->m_mreached; if (vmax_seen < r->m_VMAX) vmax_seen = r->m_VMAX; if (pmax_seen < (int) r->m_PMAX) pmax_seen = (int) r->m_PMAX; if (qmax_seen < (int) r->m_QMAX) qmax_seen = (int) r->m_QMAX; ptr = &(r->m_R); { for (j = 0; j < NrStates[i]; j++) { if (*(ptr + j) != 0) { reached[i][j] = 1; { cpu_printf("Got Results (%%d)\n", ptr - &(r->m_R)); snapshot();static voidrm_shared_segments(void){ int m; volatile sh_Allocater *nxt_pool; /* * mark all shared memory segments for removal * the actual removes wont happen intil last process dies or detaches * the shmctl calls can return -1 if not all procs have detached yet for (m = 0; m < NR_QS; m++) /* +1 for global q */ { if (shmid[m] != -1) { (void) shmctl(shmid[m], IPC_RMID, NULL); if (shmid_M != -1) { (void) shmctl(shmid_M, IPC_RMID, NULL); if (shmid_S != -1) { (void) shmctl(shmid_S, IPC_RMID, NULL); for (last_pool = first_pool; last_pool != NULL; last_pool = nxt_pool) { shmid_M = (int) (last_pool->dc_id); nxt_pool = last_pool->nxt; /* as a pre-caution only */ if (shmid_M != -1) { (void) shmctl(shmid_M, IPC_RMID, NULL);sudden_stop(char *s){ char b[64]; printf("cpu%%d: stop - %%s\n", core_id, s); if (proxy_pid != 0) { rm_shared_segments(); { if (*search_terminated != 0) { if (verbose) { printf("cpu%%d: termination initiated (%%d)\n", core_id, *search_terminated); { printf("cpu%%d: initiated termination\n", core_id); *search_terminated |= 8; /* sudden_stop */ if (core_id == 0) { if (((*search_terminated) & 4) /* uerror in one of the cpus */ && !((*search_terminated) & (8|32|128|256))) /* abnormal stop */ { if (errors == 0) errors++; /* we know there is at least 1 */ wrapup(); /* incomplete stats, but at least something */ return; } /* else: should rarely happen, take more drastic measures */ if (core_id == 0) /* local root process */ { for (i = 1; i < NCORE; i++) /* not for 0 of course */ DWORD dwExitCode = 0; GetExitCodeProcess(worker_handles[i], &dwExitCode); if (dwExitCode == STILL_ACTIVE) { TerminateProcess(worker_handles[i], 0); printf("cpu0: terminate %%d %%d\n", worker_pids[i], (dwExitCode == STILL_ACTIVE)); sprintf(b, "kill -%%d %%d", SIGKILL, worker_pids[i]); system(b); /* if this is a proxy: receive half */ printf("cpu0: %%s\n", b); issued_kill++; { /* on WIN32/WIN64 -- these merely kills the root process... */ if (was_interrupted == 0) { sprintf(b, "kill -%%d %%d", SIGINT, worker_pids[0]); system(b); /* warn the root process */ printf("cpu%%d: %%s\n", core_id, b); issued_kill++;#define iam_alive() is_alive[core_id]++extern int crash_test(double);extern void crash_reset(void);someone_crashed(int wait_type){ static double last_value = 0.0; static int count = 0; if (search_terminated == NULL || *search_terminated != 0) if (!(*search_terminated & (8|32|128|256))) { if (count++ < 100*NCORE) { return 0; /* check left neighbor only */ if (last_value == is_alive[(core_id + NCORE - 1) %% NCORE]) { if (count++ >= 100) /* to avoid unnecessary checks */ { return 1; last_value = is_alive[(core_id + NCORE - 1) %% NCORE]; count = 0; crash_reset();sleep_report(void) printf("cpu%%d: locks: global %%g\tother %%g\t", core_id, glock_wait[0], lock_wait - glock_wait[0]); printf("cpu%%d: locks: GL %%g, RQ %%g, WQ %%g, HT %%g\t", core_id, glock_wait[0], glock_wait[1], glock_wait[2], lock_wait - glock_wait[0] - glock_wait[1] - glock_wait[2]); printf("waits: states %%g slots %%g\n", frame_wait, free_wait); printf("cpu%%d: gq [tries %%g, room %%g, noroom %%g]\n", core_id, gq_tries, gq_hasroom, gq_hasnoroom); if (core_id == 0 && (*gr_readmiss >= 1.0 || *gr_readmiss >= 1.0 || *grcnt != 0)) printf("cpu0: gq [readmiss: %%g, writemiss: %%g cnt %%d]\n", *gr_readmiss, *gr_writemiss, *grcnt); if (free_wait > 1000000.) #ifndef NGQ { printf("hint: this search may be faster with a larger work-queue\n"); printf(" (-DSET_WQ_SIZE=N with N>%%g), and/or with -DUSE_DISK\n", GWQ_SIZE/sizeof(SM_frame)); printf(" or with a larger value for -zN (N>%%d)\n", z_handoff); { printf("hint: this search may be faster if compiled without -DNGQ, with -DUSE_DISK, "); printf("or with a larger -zN (N>%%d)\n", z_handoff);#ifndef MAX_DSK_FILE #define MAX_DSK_FILE 1000000 /* default is max 1M states per file */multi_usage(FILE *fd){ static int warned = 0; if (warned > 0) { return; } else { warned++; } fprintf(fd, "\n"); fprintf(fd, "Defining multi-core mode:\n\n"); fprintf(fd, " -DDUAL_CORE --> same as -DNCORE=2\n"); fprintf(fd, " -DQUAD_CORE --> same as -DNCORE=4\n"); fprintf(fd, " -DNCORE=N --> enables multi_core verification if N>1\n"); fprintf(fd, "Additional directives supported in multi-core mode:\n\n"); fprintf(fd, " -DSEP_STATE --> forces separate statespaces instead of a single shared state space\n"); fprintf(fd, " -DNUSE_DISK --> use disk for storing states when a work queue overflows\n"); fprintf(fd, " -DMAX_DSK_FILE --> max nr of states per diskfile (%%d)\n", MAX_DSK_FILE); fprintf(fd, " -DFULL_TRAIL --> support full error trails (increases memory use)\n"); fprintf(fd, "More advanced use (should rarely need changing):\n\n"); fprintf(fd, " To change the nr of states that can be stored in the global queue\n"); fprintf(fd, " (lower numbers allow for more states to be stored, prefer multiples of 8):\n"); fprintf(fd, " -DVMAX=N --> upperbound on statevector for handoffs (N=%%d)\n", VMAX); fprintf(fd, " -DPMAX=N --> upperbound on nr of procs (default: N=%%d)\n", PMAX); fprintf(fd, " -DQMAX=N --> upperbound on nr of channels (default: N=%%d)\n", QMAX); fprintf(fd, " To set the total amount of memory reserved for the global workqueue:\n"); fprintf(fd, " -DSET_WQ_SIZE=N --> default: N=128 (defined in MBytes)\n\n"); fprintf(fd, " To force the use of a single global heap, instead of separate heaps:\n"); fprintf(fd, " -DGLOB_HEAP\n"); fprintf(fd, " To define a fct to initialize data before spawning processes (use quotes):\n"); fprintf(fd, " \"-DC_INIT=fct()\"\n"); fprintf(fd, " Timer settings for termination and crash detection:\n"); fprintf(fd, " -DSHORT_T=N --> timeout for termination detection trigger (N=%%g)\n", (double) SHORT_T); fprintf(fd, " -DLONG_T=N --> timeout for giving up on termination detection (N=%%g)\n", (double) LONG_T); fprintf(fd, " -DONESECOND --> (1<<29) --> timeout waiting for a free slot -- to check for crash\n"); fprintf(fd, " -DT_ALERT --> collect stats on crash alert timeouts\n\n"); fprintf(fd, "Help with Linux/Windows/Cygwin configuration for multi-core:\n"); fprintf(fd, " http://spinroot.com/spin/multicore/V5_Readme.html\n");typedef struct Stack_Tree { uchar pr; /* process that made transition */ T_ID t_id; /* id of transition */ volatile struct Stack_Tree *prv; /* backward link towards root */} Stack_Tree;struct H_el *grab_shared(int);volatile Stack_Tree **stack_last; /* in shared memory */char *stack_cache = NULL; /* local */int nr_cached = 0; /* local */#ifndef CACHE_NR #define CACHE_NR 1024volatile Stack_Tree *stack_prefetch(void){ volatile Stack_Tree *st; if (nr_cached == 0) { stack_cache = (char *) grab_shared(CACHE_NR * sizeof(Stack_Tree)); nr_cached = CACHE_NR; st = (volatile Stack_Tree *) stack_cache; stack_cache += sizeof(Stack_Tree); nr_cached--; return st;Push_Stack_Tree(short II, T_ID t_id) st = (volatile Stack_Tree *) stack_prefetch(); st->pr = II; st->t_id = t_id; st->prv = (Stack_Tree *) stack_last[core_id]; stack_last[core_id] = st;Pop_Stack_Tree(void){ volatile Stack_Tree *cf = stack_last[core_id]; if (cf) { stack_last[core_id] = cf->prv; } else if (nr_handoffs * z_handoff + depth > 0) { printf("cpu%%d: error pop_stack_tree (depth %%d)\n", core_id, depth);e_critical(int which){ double cnt_start; if (readtrail || iamin[which] > 0) { if (!readtrail && verbose) { printf("cpu%%d: Double Lock on %%d (now %%d)\n", core_id, which, iamin[which]+1); fflush(stdout); iamin[which]++; /* local variable */ cnt_start = lock_wait; while (sh_lock != NULL) /* as long as we have shared memory */ { int r = tas(&sh_lock[which]); if (r == 0) { iamin[which] = 1; return; /* locked */ lock_wait++; if (which < 3) { glock_wait[which]++; } if (which == 0) { glock_wait[which]++; } iam_alive(); if (lock_wait - cnt_start > TenSeconds) { printf("cpu%%d: lock timeout on %%d\n", core_id, which); cnt_start = lock_wait; if (someone_crashed(1)) { sudden_stop("lock timeout"); pan_exit(1);x_critical(int which) if (iamin[which] != 1) { if (iamin[which] > 1) { iamin[which]--; /* this is thread-local - no races on this one */ if (!readtrail && verbose) { printf("cpu%%d: Partial Unlock on %%d (%%d more needed)\n", core_id, which, iamin[which]); fflush(stdout); } else /* iamin[which] <= 0 */ { if (!readtrail) { printf("cpu%%d: Invalid Unlock iamin[%%d] = %%d\n", if (sh_lock != NULL) { iamin[which] = 0; sh_lock[which] = 0; /* unlock */start_proxy(char *s, DWORD r_pid)start_proxy(char *s, int r_pid){ char Q_arg[16], Z_arg[16], Y_arg[16]; char *args[32], *ptr; int argcnt = 0; sprintf(Q_arg, "-Q%%d", getpid()); sprintf(Y_arg, "-Y%%d", r_pid); sprintf(Z_arg, "-Z%%d", proxy_pid /* core_id */); args[argcnt++] = "proxy"; args[argcnt++] = s; /* -r or -s */ args[argcnt++] = Q_arg; args[argcnt++] = Z_arg; args[argcnt++] = Y_arg; if (strlen(o_cmdline) > 0) { ptr = o_cmdline; /* assume args separated by spaces */ do { args[argcnt++] = ptr++; if ((ptr = strchr(ptr, ' ')) != NULL) { while (*ptr == ' ') { *ptr++ = '\0'; { break; } while (argcnt < 31); args[argcnt] = NULL; execvp("pan_proxy", args); /* no return */ execvp("./pan_proxy", args); /* no return */ Uerror("pan_proxy exec failed");/*** end of common code fragment ***/init_shm(void) /* initialize shared work-queues - linux/cygwin */{ key_t key[NR_QS]; int n, m; int must_exit = 0; if (core_id == 0 && verbose) { printf("cpu0: step 3: allocate shared workqueues %%g MB\n", ((double) NCORE * LWQ_SIZE + GWQ_SIZE) / (1048576.) ); for (m = 0; m < NR_QS; m++) /* last q is the global q */ { double qsize = (m == NCORE) ? GWQ_SIZE : LWQ_SIZE; key[m] = ftok(PanSource, m+1); if (key[m] == -1) { perror("ftok shared queues"); must_exit = 1; break; if (core_id == 0) /* root creates */ { /* check for stale copy */ shmid[m] = shmget(key[m], (size_t) qsize, 0600); if (shmid[m] != -1) /* yes there is one; remove it */ { printf("cpu0: removing stale q%%d, status: %%d\n", m, shmctl(shmid[m], IPC_RMID, NULL)); shmid[m] = shmget(key[m], (size_t) qsize, 0600|IPC_CREAT|IPC_EXCL); memcnt += qsize; } else /* workers attach */ { shmid[m] = shmget(key[m], (size_t) qsize, 0600); /* never called, since we create shm *before* we fork */ if (shmid[m] == -1) { perror("shmget shared queues"); must_exit = 1; break; shared_mem[m] = (char *) shmat(shmid[m], (void *) 0, 0); /* attach */ if (shared_mem[m] == (char *) -1) { fprintf(stderr, "error: cannot attach shared wq %%d (%%d Mb)\n", m+1, (int) (qsize/(1048576.))); perror("shmat shared queues"); must_exit = 1; break; m_workq[m] = (SM_frame *) shared_mem[m]; { int nframes = (m == NCORE) ? GN_FRAMES : LN_FRAMES; for (n = 0; n < nframes; n++) { m_workq[m][n].m_vsize = 0; m_workq[m][n].m_boq = 0; if (must_exit) fprintf(stderr, "pan: check './pan --' for usage details\n"); pan_exit(1); /* calls cleanup_shm */static uchar *prep_shmid_S(size_t n) /* either sets SS or H_tab, linux/cygwin */{ char *rval; key_t key; printf("cpu0: step 1: allocate shared bitstate %%g Mb\n", (double) n / (1048576.)); printf("cpu0: step 1: allocate shared hastable %%g Mb\n", if (memcnt + (double) n > memlim) { printf("cpu0: S %%8g + %%d Kb exceeds memory limit of %%8g Mb\n", memcnt/1024., n/1024, memlim/(1048576.)); printf("cpu0: insufficient memory -- aborting\n"); key = ftok(PanSource, NCORE+2); /* different from queues */ if (key == -1) { perror("ftok shared bitstate or hashtable"); if (core_id == 0) /* root */ { shmid_S = shmget(key, n, 0600); if (shmid_S != -1) { printf("cpu0: removing stale segment, status: %%d\n", shmctl(shmid_S, IPC_RMID, NULL)); shmid_S = shmget(key, n, 0600 | IPC_CREAT | IPC_EXCL); memcnt += (double) n; } else /* worker */ if (shmid_S == -1) { perror("shmget shared bitstate or hashtable too large?"); rval = (char *) shmat(shmid_S, (void *) 0, 0); /* attach */ if ((char *) rval == (char *) -1) { perror("shmat shared bitstate or hashtable"); rval = (char *) emalloc(n); return (uchar *) rval;#define TRY_AGAIN 1#define NOT_AGAIN 0static char shm_prep_result;prep_state_mem(size_t n) /* sets memory arena for states linux/cygwin */ static int cnt = 3; /* start larger than earlier ftok calls */ shm_prep_result = NOT_AGAIN; /* default */ { printf("cpu0: step 2+: pre-allocate memory arena %%d of %%6.2g Mb\n", cnt-3, (double) n / (1048576.)); { printf("cpu0: error: M %%.0f + %%.0f Kb exceeds memory limit of %%.0f Mb\n", memcnt/1024.0, (double) n/1024.0, memlim/(1048576.)); return NULL; key = ftok(PanSource, NCORE+cnt); cnt++; { perror("ftok T"); printf("pan: check './pan --' for usage details\n"); if (core_id == 0) { shmid_M = shmget(key, n, 0600); { printf("cpu0: removing stale memory segment %%d, status: %%d\n", cnt-3, shmctl(shmid_M, IPC_RMID, NULL)); shmid_M = shmget(key, n, 0600 | IPC_CREAT | IPC_EXCL); /* memcnt += (double) n; -- only amount actually used is counted */ if (shmid_M == -1) { if (verbose) { printf("error: failed to get pool of shared memory %%d of %%.0f Mb\n", cnt-3, ((double)n)/(1048576.)); perror("state mem"); printf("pan: check './pan --' for usage details\n"); shm_prep_result = TRY_AGAIN; rval = (char *) shmat(shmid_M, (void *) 0, 0); /* attach */ { printf("cpu%%d error: failed to attach pool of shared memory %%d of %%.0f Mb\n", core_id, cnt-3, ((double)n)/(1048576.)); perror("state mem");init_HT(unsigned long n) /* cygwin/linux version */{ volatile char *x; double get_mem; volatile char *dc_mem_start; double need_mem, got_mem = 0.; #ifndef MEMLIM { printf("cpu0: steps 0,1: no -DMEMLIM set\n"); { printf("cpu0: steps 0,1: -DMEMLIM=%%d Mb - (hashtable %%g Mb + workqueues %%g Mb)\n", MEMLIM, ((double)n/(1048576.)), (((double) NCORE * LWQ_SIZE) + GWQ_SIZE) /(1048576.) ); get_mem = NCORE * sizeof(double) + (1 + CS_NR) * sizeof(void *) + 4*sizeof(void *) + 2*sizeof(double); /* NCORE * is_alive + search_terminated + CS_NR * sh_lock + 6 gr vars */ get_mem += 4 * NCORE * sizeof(void *); /* prfree, prfull, prcnt, prmax */ #ifdef FULL_TRAIL get_mem += (NCORE) * sizeof(Stack_Tree *); /* NCORE * stack_last */ x = (volatile char *) prep_state_mem((size_t) get_mem); /* work queues and basic structs */ shmid_X = (long) x; if (x == NULL) { printf("cpu0: could not allocate shared memory, see ./pan --\n"); search_terminated = (volatile unsigned int *) x; /* comes first */ x += sizeof(void *); /* maintain alignment */ is_alive = (volatile double *) x; x += NCORE * sizeof(double); sh_lock = (volatile int *) x; x += CS_NR * sizeof(void *); grfree = (volatile int *) x; x += sizeof(void *); grfull = (volatile int *) x; grcnt = (volatile int *) x; grmax = (volatile int *) x; prfree = (volatile int *) x; x += NCORE * sizeof(void *); prfull = (volatile int *) x; prcnt = (volatile int *) x; prmax = (volatile int *) x; gr_readmiss = (volatile double *) x; x += sizeof(double); gr_writemiss = (volatile double *) x; stack_last = (volatile Stack_Tree **) x; x += NCORE * sizeof(Stack_Tree *); H_tab = (struct H_el **) emalloc(n); #ifndef MEMLIM #warning MEMLIM not set #define MEMLIM (2048) { printf("cpu0: step 0: -DMEMLIM=%%d Mb minus hashtable+workqs (%%g + %%g Mb) leaves %%g Mb\n", MEMLIM, ((double)n/(1048576.)), (NCORE * LWQ_SIZE + GWQ_SIZE)/(1048576.), (memlim - memcnt - (double) n - (NCORE * LWQ_SIZE + GWQ_SIZE))/(1048576.)); H_tab = (struct H_el **) prep_shmid_S((size_t) n); /* hash_table */ need_mem = memlim - memcnt - ((double) NCORE * LWQ_SIZE) - GWQ_SIZE; if (need_mem <= 0.) { Uerror("internal error -- shared state memory"); { printf("cpu0: step 2: pre-allocate shared state memory %%g Mb\n", need_mem/(1048576.)); SEG_SIZE = need_mem / NCORE; { printf("cpu0: setting segsize to %%6g MB\n", SEG_SIZE/(1048576.)); #if defined(CYGWIN) || defined(__CYGWIN__) if (SEG_SIZE > 512.*1024.*1024.) { printf("warning: reducing SEG_SIZE of %%g MB to 512MB (exceeds max for Cygwin)\n", SEG_SIZE/(1024.*1024.)); SEG_SIZE = 512.*1024.*1024.; mem_reserved = need_mem; while (need_mem > 1024.) { get_mem = need_mem;shm_more: if (get_mem > (double) SEG_SIZE) { get_mem = (double) SEG_SIZE; if (get_mem <= 0.0) break; /* for allocating states: */ x = dc_mem_start = (volatile char *) prep_state_mem((size_t) get_mem); if (x == NULL) { if (shm_prep_result == NOT_AGAIN || first_pool != NULL || SEG_SIZE < (16. * 1048576.)) SEG_SIZE /= 2.; if (verbose) { printf("pan: lowered segsize to %f\n", SEG_SIZE); if (SEG_SIZE >= 1024.) { goto shm_more; need_mem -= get_mem; got_mem += get_mem; if (first_pool == NULL) { search_terminated = (volatile unsigned int *) x; /* comes first */ x += sizeof(void *); /* maintain alignment */ is_alive = (volatile double *) x; x += NCORE * sizeof(double); sh_lock = (volatile int *) x; x += CS_NR * sizeof(void *); grfree = (volatile int *) x; x += sizeof(void *); grfull = (volatile int *) x; grcnt = (volatile int *) x; grmax = (volatile int *) x; prfree = (volatile int *) x; x += NCORE * sizeof(void *); prfull = (volatile int *) x; prcnt = (volatile int *) x; prmax = (volatile int *) x; gr_readmiss = (volatile double *) x; x += sizeof(double); gr_writemiss = (volatile double *) x; stack_last = (volatile Stack_Tree **) x; x += NCORE * sizeof(Stack_Tree *); if (((long)x)&(sizeof(void *)-1)) /* 64-bit word alignment */ { x += sizeof(void *)-(((long)x)&(sizeof(void *)-1)); #ifdef COLLAPSE ncomps = (unsigned long *) x; x += (256+2) * sizeof(unsigned long); dc_shared = (sh_Allocater *) x; /* must be in shared memory */ x += sizeof(sh_Allocater); if (core_id == 0) /* root only */ { dc_shared->dc_id = shmid_M; dc_shared->dc_start = dc_mem_start; dc_shared->dc_arena = x; dc_shared->pattern = 1234567; /* protection */ dc_shared->dc_size = (long) get_mem - (long) (x - dc_mem_start); dc_shared->nxt = (long) 0; if (last_pool == NULL) { first_pool = last_pool = dc_shared; { last_pool->nxt = dc_shared; last_pool = dc_shared; } else if (first_pool == NULL) { first_pool = dc_shared; if (need_mem > 1024.) { printf("cpu0: could allocate only %%g Mb of shared memory (wanted %%g more)\n", got_mem/(1048576.), need_mem/(1048576.)); if (!first_pool) { printf("cpu0: insufficient memory -- aborting.\n"); /* we are still single-threaded at this point, with core_id 0 */ dc_shared = first_pool; /* Test and Set assembly code */ #if defined(i386) || defined(__i386__) || defined(__x86_64__) int tas(volatile int *s) /* tested */ { int r; __asm__ __volatile__( "xchgl %%0, %%1 \n\t" : "=r"(r), "=m"(*s) : "0"(1), "m"(*s) : "memory"); return r; #elif defined(__arm__) tas(volatile int *s) /* not tested */ { int r = 1; "swpb %%0, %%0, [%%3] \n" : "=r"(r), "=m"(*s) : "0"(r), "r"(s)); #elif defined(sparc) || defined(__sparc__) " ldstub [%%2], %%0 \n" : "r"(s)); #elif defined(ia64) || defined(__ia64__) /* Intel Itanium */ { long int r; " xchg4 %%0=%%1,%%2 \n" : "=r"(r), "+m"(*s) : "r"(1) : "memory"); return (int) r; #error missing definition of test and set operation for this platformcleanup_shm(int val){ volatile sh_Allocater *nxt_pool; unsigned long cnt = 0; int m; if (nibis != 0) { printf("cpu%%d: Redundant call to cleanup_shm(%%d)\n", core_id, val); { nibis = 1; { *search_terminated |= 16; /* cleanup_shm */ for (m = 0; m < NR_QS; m++) { if (shmdt((void *) shared_mem[m]) > 0) { perror("shmdt detaching from shared queues"); if (shmdt((void *) shmid_X) != 0) { perror("shmdt detaching from shared state memory"); if (SS > 0 && shmdt((void *) SS) != 0) { perror("shmdt detaching from shared bitstate arena"); { /* before detaching: */ for (nxt_pool = dc_shared; nxt_pool != NULL; nxt_pool = nxt_pool->nxt) { cnt += nxt_pool->dc_size; { printf("cpu0: done, %%ld Mb of shared state memory left\n", cnt / (long)(1048576)); if (shmdt((void *) H_tab) != 0) { perror("shmdt detaching from shared hashtable"); for (last_pool = first_pool; last_pool != NULL; last_pool = nxt_pool) { nxt_pool = last_pool->nxt; if (shmdt((void *) last_pool->dc_start) != 0) { perror("shmdt detaching from shared state memory"); first_pool = last_pool = NULL; /* precaution */ /* detached from shared memory - so cannot use cpu_printf */ { printf("cpu%%d: done -- got %%d states from queue\n", core_id, nstates_get);extern void give_up(int);extern void Read_Queue(int);mem_get(void){ SM_frame *f; int is_parent;#if defined(MA) && !defined(SEP_STATE) #error MA without SEP_STATE is not supported with multi-core #error BFS is not supported with multi-core #error SC is not supported with multi-core init_shm(); /* we are single threaded when this starts */ { printf("cpu0: step 4: calling fork()\n");/* if NCORE > 1 the child or the parent should fork N-1 more times * the parent is the only process with core_id == 0 and is_parent > 0 * the workers have is_parent = 0 and core_id = 1..NCORE-1 { worker_pids[0] = getpid(); /* for completeness */ while (++core_id < NCORE) /* first worker sees core_id = 1 */ { is_parent = fork(); if (is_parent == -1) { Uerror("fork failed"); if (is_parent == 0) /* this is a worker process */ { if (proxy_pid == core_id) /* always non-zero */ { start_proxy("-r", 0); /* no return */ goto adapt; /* root process continues spawning */ worker_pids[core_id] = is_parent; /* note that core_id is now NCORE */ if (proxy_pid > 0 && proxy_pid < NCORE) { proxy_pid_snd = fork(); if (proxy_pid_snd == -1) { Uerror("proxy fork failed"); if (proxy_pid_snd == 0) { start_proxy("-s", worker_pids[proxy_pid]); /* no return */ } } /* else continue */ if (is_parent > 0) { core_id = 0; /* reset core_id for root process */ } else /* worker */ { static char db0[16]; /* good for up to 10^6 cores */ static char db1[16];adapt: tprefix = db0; sprefix = db1; sprintf(tprefix, "cpu%%d_trail", core_id); sprintf(sprefix, "cpu%%d_rst", core_id); memcnt = 0; /* count only additionally allocated memory */ signal(SIGINT, give_up); if (proxy_pid == 0) /* not in a cluster setup, pan_proxy must attach */ { rm_shared_segments(); /* mark all shared segments for removal on exit */ { cpu_printf("starting core_id %%d -- pid %%d\n", core_id, getpid());#if defined(SEP_HEAP) && !defined(SEP_STATE) { int i; volatile sh_Allocater *ptr; ptr = first_pool; for (i = 0; i < NCORE && ptr != NULL; i++) { if (i == core_id) { my_heap = (char *) ptr->dc_arena; my_size = (long) ptr->dc_size; if (verbose) cpu_printf("local heap %%ld MB\n", my_size/(1048576)); ptr = ptr->nxt; /* local */ if (my_heap == NULL) { printf("cpu%%d: no local heap\n", core_id); { ptr = ptr->nxt; /* local */ dc_shared = ptr; /* any remainder */ dc_shared = NULL; /* used all mem for local heaps */ if (core_id == 0 && !remote_party) { new_state(); /* cpu0 explores root */ cpu_printf("done with 1st dfs, nstates %%g (put %%d states), read q\n", nstates, nstates_put); dfs_phase2 = 1; Read_Queue(core_id); /* all cores */ { cpu_printf("put %%6d states into queue -- got %%6d\n", nstates_put, nstates_get); exit(0);int unpack_state(SM_frame *, int);grab_shared(int n) char *rval = (char *) 0; { printf("cpu%%d: grab shared zero\n", core_id); fflush(stdout); return (struct H_el *) rval; } else if (n&(sizeof(void *)-1)) { n += sizeof(void *)-(n&(sizeof(void *)-1)); /* alignment */ /* no locking */ if (my_heap != NULL && my_size > n) { rval = my_heap; my_heap += n; my_size -= n; if (!dc_shared) { sudden_stop("pan: out of memory"); /* another lock is always already in effect when this is called */ /* but not always the same lock -- i.e., on different parts of the hashtable */ enter_critical(GLOBAL_LOCK); /* this must be independently mutex */#if defined(SEP_HEAP) && !defined(WIN32) && !defined(WIN64) { static int noted = 0; if (!noted) { noted = 1; printf("cpu%%d: global heap has %%ld bytes left, needed %%d\n", core_id, dc_shared?dc_shared->dc_size:0, n); if (dc_shared->pattern != 1234567) { leave_critical(GLOBAL_LOCK); Uerror("overrun -- memory corruption"); if (dc_shared->dc_size < n) { printf("Next Pool %%g Mb + %%d\n", memcnt/(1048576.), n); if (dc_shared->nxt == NULL || dc_shared->nxt->dc_arena == NULL || dc_shared->nxt->dc_size < n) { printf("cpu%%d: memcnt %%g Mb + wanted %%d bytes more\n", core_id, memcnt / (1048576.), n); sudden_stop("out of memory -- aborting"); wrapup(); /* exits */ { dc_shared = (sh_Allocater *) dc_shared->nxt; rval = (char *) dc_shared->dc_arena; dc_shared->dc_arena += n; dc_shared->dc_size -= (long) n; if (VVERBOSE) printf("cpu%%d grab shared (%%d bytes) -- %%ld left\n", core_id, n, dc_shared->dc_size); memset(rval, 0, n); return (struct H_el *) rval; return (struct H_el *) emalloc(n);SM_frame *Get_Full_Frame(int n){ SM_frame *f; double cnt_start = frame_wait; f = &m_workq[n][prfull[n]]; while (f->m_vsize == 0) /* await full slot LOCK : full frame */ { iam_alive(); if (!a_cycles || core_id != 0) if (*grcnt > 0) /* accessed outside lock, but safe even if wrong */ { enter_critical(GQ_RD); /* gq - read access */ if (*grcnt > 0) /* could have changed */ { f = &m_workq[NCORE][*grfull]; /* global q */ if (f->m_vsize == 0) { /* writer is still filling the slot */ *gr_writemiss++; f = &m_workq[n][prfull[n]]; /* reset */ } else { *grfull = (*grfull+1) %% (GN_FRAMES); enter_critical(GQ_WR); *grcnt = *grcnt - 1; leave_critical(GQ_WR); leave_critical(GQ_RD); return f; leave_critical(GQ_RD); if (frame_wait++ - cnt_start > Delay) { if (0) { cpu_printf("timeout on q%%d -- %%u -- query %%d\n", n, f, query_in_progress); return (SM_frame *) 0; /* timeout */ iam_alive(); if (VVERBOSE) cpu_printf("got frame from q%%d\n", n); prfull[n] = (prfull[n] + 1) %% (LN_FRAMES); enter_critical(QLOCK(n)); prcnt[n]--; /* lock out increments */ leave_critical(QLOCK(n)); return f;Get_Free_Frame(int n) double cnt_start = free_wait; if (VVERBOSE) { cpu_printf("get free frame from q%%d\n", n); } if (n == NCORE) /* global q */ { f = &(m_workq[n][lrfree]); { f = &(m_workq[n][prfree[n]]); while (f->m_vsize != 0) /* await free slot LOCK : free slot */ if (free_wait++ - cnt_start > OneSecond) { cpu_printf("timeout waiting for free slot q%%d\n", n); cnt_start = free_wait; { printf("cpu%%d: search terminated\n", core_id); sudden_stop("get free frame"); if (n != NCORE) { prfree[n] = (prfree[n] + 1) %% (LN_FRAMES); enter_critical(QLOCK(n)); prcnt[n]++; /* lock out decrements */ if (prmax[n] < prcnt[n]) { prmax[n] = prcnt[n]; leave_critical(QLOCK(n));GlobalQ_HasRoom(void){ int rval = 0; gq_tries++; if (*grcnt < GN_FRAMES) /* there seems to be room */ { enter_critical(GQ_WR); /* gq write access */ if (*grcnt < GN_FRAMES) { if (m_workq[NCORE][*grfree].m_vsize != 0) { /* can happen if reader is slow emptying slot */ *gr_readmiss++; goto out; /* dont wait: release lock and return */ lrfree = *grfree; /* Get_Free_Frame use lrfree in this mode */ *grfree = (*grfree + 1) %% GN_FRAMES; *grcnt = *grcnt + 1; /* count nr of slots filled -- no additional lock needed */ if (*grmax < *grcnt) *grmax = *grcnt; leave_critical(GQ_WR); /* for short lock duration */ gq_hasroom++; mem_put(NCORE); /* copy state into reserved slot */ rval = 1; /* successfull handoff */ { gq_hasnoroom++;out: leave_critical(GQ_WR); return rval;unpack_state(SM_frame *f, int from_q) static struct H_el D_State; if (f->m_vsize > 0) { boq = f->m_boq; if (boq > 256) { cpu_printf("saw control %%d, expected state\n", boq); vsize = f->m_vsize;correct: memcpy((uchar *) &now, (uchar *) f->m_now, vsize); for (i = j = 0; i < VMAX; i++, j = (j+1)%%8) { Mask[i] = (f->m_Mask[i/8] & (1<m_p_offset, now._nr_pr * sizeof(OFFT)); memcpy((uchar *) proc_skip, (uchar *) f->m_p_skip, now._nr_pr * sizeof(uchar)); { memcpy((uchar *) q_offset, (uchar *) f->m_q_offset, now._nr_qs * sizeof(OFFT)); memcpy((uchar *) q_skip, (uchar *) f->m_q_skip, now._nr_qs * sizeof(uchar)); if (vsize != now._vsz) { cpu_printf("vsize %%d != now._vsz %%d (type %%d) %%d\n", vsize, now._vsz, f->m_boq, f->m_vsize); vsize = now._vsz; goto correct; /* rare event: a race */ hmax = max(hmax, vsize); if (f != &cur_Root) { memcpy((uchar *) &cur_Root, (uchar *) f, sizeof(SM_frame)); if (((now._a_t) & 1) == 1) /* i.e., when starting nested DFS */ { A_depth = depthfound = 0; memcpy((uchar *)&A_Root, (uchar *)&now, vsize); nr_handoffs = f->nr_handoffs; { cpu_printf("pan: state empty\n"); depth = 0; trpt = &trail[1]; trpt->tau = f->m_tau; trpt->o_pm = f->m_o_pm; (trpt-1)->ostate = &D_State; /* stub */ trpt->ostate = &D_State; if (upto > 0) { stack_last[core_id] = (Stack_Tree *) f->m_stack; #if defined(VERBOSE) if (stack_last[core_id]) { cpu_printf("%%d: UNPACK -- SET m_stack %%u (%%d,%%d)\n", depth, stack_last[core_id], stack_last[core_id]->pr, stack_last[core_id]->t_id); if (!trpt->o_t) { static Trans D_Trans; trpt->o_t = &D_Trans; #ifdef VERI if ((trpt->tau & 4) != 4) { trpt->tau |= 4; /* the claim moves first */ cpu_printf("warning: trpt was not up to date\n"); #ifndef NP if (accpstate[ptr->_t][ptr->_p]) if (progstate[ptr->_t][ptr->_p]) #ifdef EVENT_TRACE #ifndef NP { trpt->o_pm |= 2; { trpt->o_pm |= 4; #if defined(C_States) && (HAS_TRACK==1) /* restore state of tracked C objects */ #if (HAS_STACK==1) c_unstack((uchar *) f->m_c_stack); /* unmatched tracked data */write_root(void) /* for trail file */ if (iterative == 0 && Nr_Trails > 1) sprintf(fnm, "%%s%%d.%%s", TrailFile, Nr_Trails-1, sprefix); sprintf(fnm, "%%s.%%s", TrailFile, sprefix); if (cur_Root.m_vsize == 0) { (void) unlink(fnm); /* remove possible old copy */ return; /* its the default initial state */ if ((fd = creat(fnm, TMODE)) < 0) { char *q; if ((q = strchr(TrailFile, '.'))) { *q = '\0'; /* strip .pml */ sprintf(fnm, "%%s%%d.%%s", TrailFile, Nr_Trails-1, sprefix); sprintf(fnm, "%%s.%%s", TrailFile, sprefix); fd = creat(fnm, TMODE); if (fd < 0) { cpu_printf("pan: cannot create %%s\n", fnm); perror("cause"); if (write(fd, &cur_Root, sizeof(SM_frame)) != sizeof(SM_frame)) { cpu_printf("pan: error writing %%s\n", fnm); { cpu_printf("pan: wrote %%s\n", fnm);set_root(void) char *ssuffix = "rst"; int try_core = 1; if (whichtrail > 0) { sprintf(fnm, "%%s%%d.%%s", MyFile, whichtrail, ssuffix); fd = open(fnm, O_RDONLY, 0); if (fd < 0 && (q = strchr(MyFile, '.'))) { *q = '\0'; /* strip .pml */ sprintf(fnm, "%%s%%d.%%s", MyFile, whichtrail, ssuffix); fd = open(fnm, O_RDONLY, 0); { sprintf(fnm, "%%s.%%s", MyFile, ssuffix); sprintf(fnm, "%%s.%%s", MyFile, ssuffix); { ssuffix = MySuffix; sprintf(ssuffix, "cpu%%d_rst", try_core++); cpu_printf("no file '%%s.rst' or '%%s' (not an error)\n", MyFile, fnm); { if (read(fd, &cur_Root, sizeof(SM_frame)) != sizeof(SM_frame)) { cpu_printf("read error %%s\n", fnm); close(fd); (void) unpack_state(&cur_Root, -2); cpu_printf("partial trail -- last few steps only\n"); cpu_printf("restored root from '%%s'\n", fnm); printf("=====State:=====\n"); { int i, j; P0 *z; { z = (P0 *)pptr(i); printf("proc %%2d (%%s) ", i, procname[z->_t]); for (j = 0; src_all[j].src; j++) if (src_all[j].tp == (int) z->_t) src_all[j].src[z->_p], PanSource); printf("(state %%d)\n", z->_p); c_locals(i, z->_t); printf("================\n");unsigned long dsk_written, dsk_drained;void mem_drain(void);m_clear_frame(SM_frame *f){ int i, clr_sz = sizeof(SM_results); { clr_sz += NrStates[i]*sizeof(uchar); memset(f, 0, clr_sz); /* caution if sizeof(SM_results) > sizeof(SM_frame) */#define TargetQ_Full(n) (m_workq[n][prfree[n]].m_vsize != 0)#define TargetQ_NotFull(n) (m_workq[n][prfree[n]].m_vsize == 0)AllQueuesEmpty(void){ int q; if (*grcnt != 0) { return 0; for (q = 0; q < NCORE; q++) { if (prcnt[q] != 0) { return 0;Read_Queue(int q){ SM_frame *f, *of; int remember, target_q; SM_results *r; double patience = 0.0; target_q = (q + 1) %% NCORE; { f = Get_Full_Frame(q); if (!f) /* 1 second timeout -- and trigger for Query */ { if (someone_crashed(2)) { printf("cpu%%d: search terminated [code %%d]\n", core_id, search_terminated?*search_terminated:-1); sudden_stop("");#ifdef TESTING /* to profile with cc -pg and gprof pan.exe -- set handoff depth beyond maxdepth */ exit(0); remember = *grfree; if (core_id == 0 /* root can initiate termination */ && remote_party == 0 /* and only the original root */ && query_in_progress == 0 /* unless its already in progress */ && AllQueuesEmpty()) { f = Get_Free_Frame(target_q); query_in_progress = 1; /* only root process can do this */ if (!f) { Uerror("Fatal1: no free slot"); } f->m_boq = QUERY; /* initiate Query */ { cpu_printf("snd QUERY to q%%d (%%d) into slot %%d\n", target_q, nstates_get + 1, prfree[target_q]-1); f->m_vsize = remember + 1; /* number will not change unless we receive more states */ } else if (patience++ > OneHour) /* one hour watchdog timer */ { cpu_printf("timeout -- giving up\n"); sudden_stop("queue timeout"); if (0) cpu_printf("timed out -- try again\n"); continue; patience = 0.0; /* reset watchdog */ if (f->m_boq == QUERY) { cpu_printf("got QUERY on q%%d (%%d <> %%d) from slot %%d\n", q, f->m_vsize, nstates_put + 1, prfull[q]-1); snapshot(); remember = f->m_vsize; f->m_vsize = 0; /* release slot */ if (core_id == 0 && remote_party == 0) /* original root cpu0 */ { if (query_in_progress == 1 /* didn't send more states in the interim */ && *grfree + 1 == remember) /* no action on global queue meanwhile */ { if (verbose) cpu_printf("Termination detected\n"); if (TargetQ_Full(target_q)) { if (verbose) cpu_printf("warning: target q is full\n"); f = Get_Free_Frame(target_q); if (!f) { Uerror("Fatal2: no free slot"); } m_clear_frame(f); f->m_boq = QUIT; /* send final Quit, collect stats */ f->m_vsize = 111; /* anything non-zero will do */ if (verbose) cpu_printf("put QUIT on q%%d\n", target_q); { if (verbose) cpu_printf("Stale Query\n"); mem_drain(); query_in_progress = 0; { if (TargetQ_Full(target_q)) { if (verbose) cpu_printf("warning: forward query - target q full\n"); f = Get_Free_Frame(target_q); cpu_printf("snd QUERY response to q%%d (%%d <> %%d) in slot %%d\n", target_q, remember, *grfree + 1, prfree[target_q]-1); if (!f) { Uerror("Fatal4: no free slot"); } if (*grfree + 1 == remember) /* no action on global queue */ { f->m_boq = QUERY; /* forward query, to root */ f->m_vsize = remember; { f->m_boq = QUERY_F; /* no match -- busy */ f->m_vsize = 112; /* anything non-zero */ if (dsk_written != dsk_drained) { mem_drain(); if (f->m_boq == QUERY_F) { cpu_printf("got QUERY_F on q%%d from slot %%d\n", q, prfull[q]-1); if (core_id == 0 && remote_party == 0) /* original root cpu0 */ { if (verbose) cpu_printf("No Match on Query\n"); { if (verbose) cpu_printf("warning: forwarding query_f, target queue full\n"); if (verbose) cpu_printf("forward QUERY_F to q%%d into slot %%d\n", target_q, prfree[target_q]-1); if (!f) { Uerror("Fatal5: no free slot"); } f->m_boq = QUERY_F; /* cannot terminate yet */ f->m_vsize = 113; /* anything non-zero */ if (dsk_written != dsk_drained) { mem_drain(); if (f->m_boq == QUIT) { if (0) cpu_printf("done -- local memcnt %%g Mb\n", memcnt/(1048576.)); retrieve_info((SM_results *) f); /* collect and combine stats */ { cpu_printf("received Quit\n"); f->m_vsize = 0; /* release incoming slot */ if (core_id != 0) { f = Get_Free_Frame(target_q); /* new outgoing slot */ if (!f) { Uerror("Fatal6: no free slot"); } m_clear_frame(f); /* start with zeroed stats */ record_info((SM_results *) f); f->m_boq = QUIT; /* forward combined results */ f->m_vsize = 114; /* anything non-zero */ if (verbose>1) cpu_printf("fwd Results to q%%d\n", target_q); break; /* successful termination */ /* else: 0<= boq <= 255, means STATE transfer */ if (unpack_state(f, q) != 0) { nstates_get++; if (VVERBOSE) cpu_printf("Got state\n"); if (search_terminated != NULL && *search_terminated == 0) { new_state(); /* explore successors */ memset((uchar *) &cur_Root, 0, sizeof(SM_frame)); /* avoid confusion */ { pan_exit(0); { pan_exit(0); if (verbose) cpu_printf("done got %%d put %%d\n", nstates_get, nstates_put); sleep_report();give_up(int unused_x) { *search_terminated |= 32; /* give_up */ if (!writing_trail) { was_interrupted = 1; cpu_printf("Give Up\n"); sleep_report(); } else /* we are already terminating */ { cpu_printf("SIGINT\n");check_overkill(void) vmax_seen = (vmax_seen + 7)/ 8; vmax_seen *= 8; /* round up to a multiple of 8 */ if (core_id == 0 && !remote_party && nstates_put > 0 && VMAX - vmax_seen > 8) printf("cpu0: max VMAX value seen in this run: "); printf("cpu0: recommend recompiling with "); printf("-DVMAX=%%d\n", vmax_seen);mem_put(int q) /* handoff state to other cpu, workq q */ int i, j; if (vsize > VMAX) { vsize = (vsize + 7)/8; vsize *= 8; /* round up */ printf("pan: recompile with -DVMAX=N with N >= %%d\n", vsize); if (now._nr_pr > PMAX) { printf("pan: recompile with -DPMAX=N with N >= %%d\n", now._nr_pr); if (now._nr_qs > QMAX) { printf("pan: recompile with -DQMAX=N with N >= %%d\n", now._nr_qs); if (vsize > vmax_seen) vmax_seen = vsize; if (now._nr_pr > pmax_seen) pmax_seen = now._nr_pr; if (now._nr_qs > qmax_seen) qmax_seen = now._nr_qs; f = Get_Free_Frame(q); /* not called in likely deadlock states */ if (!f) { Uerror("Fatal3: no free slot"); } if (VVERBOSE) cpu_printf("putting state into q%%d\n", q); memcpy((uchar *) f->m_now, (uchar *) &now, vsize); memset((uchar *) f->m_Mask, 0, (VMAX+7)/8 * sizeof(char)); for (i = j = 0; i < VMAX; i++, j = (j+1)%%8) { if (Mask[i]) { f->m_Mask[i/8] |= (1<m_p_offset, (uchar *) proc_offset, now._nr_pr * sizeof(OFFT)); memcpy((uchar *) f->m_p_skip, (uchar *) proc_skip, now._nr_pr * sizeof(uchar)); { memcpy((uchar *) f->m_q_offset, (uchar *) q_offset, now._nr_qs * sizeof(OFFT)); memcpy((uchar *) f->m_q_skip, (uchar *) q_skip, now._nr_qs * sizeof(uchar)); c_stack((uchar *) f->m_c_stack); /* save unmatched tracked data */ f->m_stack = stack_last[core_id]; f->nr_handoffs = nr_handoffs+1; f->m_tau = trpt->tau; f->m_o_pm = trpt->o_pm; f->m_boq = boq; f->m_vsize = vsize; /* must come last - now the other cpu can see it */ if (query_in_progress == 1) query_in_progress = 2; /* make sure we know, if a query makes the rounds */ nstates_put++;int Dsk_W_Nr, Dsk_R_Nr;int dsk_file = -1, dsk_read = -1;char dsk_name[512];#ifndef BFS_DISKdsk_stats(void) if (dsk_written > 0) { cpu_printf("dsk_written %%d states in %%d files\ncpu%%d: dsk_drained %%6d states\n", dsk_written, Dsk_W_Nr, core_id, dsk_drained); close(dsk_read); close(dsk_file); for (i = 0; i < Dsk_W_Nr; i++) { sprintf(dsk_name, "Q%%.3d_%%.3d.tmp", i, core_id); unlink(dsk_name);mem_drain(void){ SM_frame *f, g; int q = (core_id + 1) %% NCORE; /* target q */ int sz; if (dsk_read < 0 || dsk_written <= dsk_drained) while (dsk_written > dsk_drained && TargetQ_NotFull(q)) { f = Get_Free_Frame(q); if (!f) { Uerror("Fatal: unhandled condition"); } if ((dsk_drained+1)%%MAX_DSK_FILE == 0) /* 100K states max per file */ { (void) close(dsk_read); /* close current read handle */ sprintf(dsk_name, "Q%%.3d_%%.3d.tmp", Dsk_R_Nr++, core_id); (void) unlink(dsk_name); /* remove current file */ sprintf(dsk_name, "Q%%.3d_%%.3d.tmp", Dsk_R_Nr, core_id); cpu_printf("reading %%s\n", dsk_name); dsk_read = open(dsk_name, RFLAGS); /* open next file */ if (dsk_read < 0) { Uerror("could not open dsk file"); if (read(dsk_read, &g, sizeof(SM_frame)) != sizeof(SM_frame)) { Uerror("bad dsk file read"); sz = g.m_vsize; g.m_vsize = 0; memcpy(f, &g, sizeof(SM_frame)); f->m_vsize = sz; /* last */ dsk_drained++;mem_file(void){ SM_frame f; int i, j, q = (core_id + 1) %% NCORE; /* target q */ { printf("pan: recompile with -DVMAX=N with N >= %%d\n", vsize); if (VVERBOSE) cpu_printf("filing state for q%%d\n", q); memcpy((uchar *) f.m_now, (uchar *) &now, vsize); memset((uchar *) f.m_Mask, 0, (VMAX+7)/8 * sizeof(char)); { f.m_Mask[i/8] |= (1<tau; f.m_o_pm = trpt->o_pm; f.m_boq = boq; f.m_vsize = vsize; { query_in_progress = 2; if (dsk_file < 0) { sprintf(dsk_name, "Q%%.3d_%%.3d.tmp", Dsk_W_Nr, core_id); dsk_file = open(dsk_name, WFLAGS, 0644); dsk_read = open(dsk_name, RFLAGS); if (dsk_file < 0 || dsk_read < 0) { cpu_printf("File: <%%s>\n", dsk_name); Uerror("cannot open diskfile"); Dsk_W_Nr++; /* nr of next file to open */ cpu_printf("created temporary diskfile %%s\n", dsk_name); } else if ((dsk_written+1)%%MAX_DSK_FILE == 0) { close(dsk_file); /* close write handle */ sprintf(dsk_name, "Q%%.3d_%%.3d.tmp", Dsk_W_Nr++, core_id); if (dsk_file < 0) Uerror("aborting: cannot open new diskfile"); if (write(dsk_file, &f, sizeof(SM_frame)) != sizeof(SM_frame)) { Uerror("aborting -- disk write failed (disk full?)"); dsk_written++;mem_hand_off(void) || *search_terminated != 0) /* not a full crash check */ { pan_exit(0); iam_alive(); /* on every transition of Down */ mem_drain(); /* maybe call this also on every Up */ if (depth > z_handoff /* above handoff limit */ && !a_cycles /* not in liveness mode */ && boq == -1 /* not mid-rv */ && (trpt->tau&4) /* claim moves first */ && !((trpt-1)->tau&128) /* not a stutter move */ && !(trpt->tau&8)) /* not an atomic move */ { int q = (core_id + 1) %% NCORE; /* circular handoff */ #ifdef GENEROUS if (prcnt[q] < LN_FRAMES) if (TargetQ_NotFull(q) && (dfs_phase2 == 0 || prcnt[core_id] > 0)) { mem_put(q); { int rval; rval = GlobalQ_HasRoom(); rval = 0; if (rval == 0) { void mem_file(void); mem_file(); rval = 1; return rval; return 0; /* i.e., no handoff */mem_put_acc(void) /* liveness mode */{ int q = (core_id + 1) %% NCORE; || *search_terminated != 0) mem_drain(); /* some tortured use of preprocessing: */#if !defined(NGQ) || defined(USE_DISK) if (TargetQ_Full(q)) if (GlobalQ_HasRoom()) { return; mem_file(); #if !defined(NGQ) || defined(USE_DISK) { mem_put(q);init_shm(void) /* initialize shared work-queues */{ char key[512]; { printf("cpu0: step 3: allocate shared work-queues %%g Mb\n", ((double) NCORE * LWQ_SIZE + GWQ_SIZE) / (1048576.)); for (m = 0; m < NR_QS; m++) /* last q is global 1 */ sprintf(key, "Global\\pan_%%s_%%.3d", PanSource, m); { shmid[m] = CreateFileMapping( INVALID_HANDLE_VALUE, /* use paging file */ NULL, /* default security */ PAGE_READWRITE, /* access permissions */ 0, /* high-order 4 bytes */ qsize, /* low-order bytes, size in bytes */ key); /* name */ } else /* worker nodes just open these segments */ { shmid[m] = OpenFileMapping( FILE_MAP_ALL_ACCESS, /* read/write access */ FALSE, /* children do not inherit handle */ key); if (shmid[m] == NULL) { fprintf(stderr, "cpu%%d: could not create or open shared queues\n", core_id); must_exit = 1; /* attach: */ shared_mem[m] = (char *) MapViewOfFile(shmid[m], FILE_MAP_ALL_ACCESS, 0, 0, 0); if (shared_mem[m] == NULL) { fprintf(stderr, "cpu%%d: cannot attach shared q%%d (%%d Mb)\n", core_id, m+1, (int) (qsize/(1048576.))); must_exit = 1; memcnt += qsize; { fprintf(stderr, "pan: check './pan --' for usage details\n");prep_shmid_S(size_t n) /* either sets SS or H_tab, WIN32/WIN64 */ char key[512]; { printf("cpu%%d: S %%8g + %%d Kb exceeds memory limit of %%8g Mb\n", core_id, memcnt/1024., n/1024, memlim/(1048576.)); printf("cpu%%d: insufficient memory -- aborting\n", core_id); /* make key different from queues: */ sprintf(key, "Global\\pan_%%s_%%.3d", PanSource, NCORE+2); /* different from qs */ { shmid_S = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,#ifdef WIN64 PAGE_READWRITE, (n>>32), (n & 0xffffffff), key); PAGE_READWRITE, 0, n, key); { shmid_S = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, key); if (shmid_S == NULL) fprintf(stderr, "cpu%%d: cannot %%s shared bitstate", core_id, core_id?"open":"create"); fprintf(stderr, "cpu%%d: cannot %%s shared hashtable", rval = (char *) MapViewOfFile(shmid_S, FILE_MAP_ALL_ACCESS, 0, 0, 0); /* attach */ if ((char *) rval == NULL) { fprintf(stderr, "cpu%%d: cannot attach shared bitstate or hashtable\n", core_id); fprintf(stderr, "pan: check './pan --' for usage details\n");prep_state_mem(size_t n) /* WIN32/WIN64 sets memory arena for states */ { printf("cpu0: step 2+: pre-allocate memory arena %%d of %%g Mb\n", { printf("cpu%%d: error: M %%.0f + %%.0f exceeds memory limit of %%.0f Kb\n", core_id, memcnt/1024.0, (double) n/1024.0, memlim/1024.0); sprintf(key, "Global\\pan_%%s_%%.3d", PanSource, NCORE+cnt); cnt++; { shmid_M = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, { shmid_M = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, key); if (shmid_M == NULL) { printf("cpu%%d: failed to get pool of shared memory nr %%d of size %%d\n", core_id, cnt-3, n); rval = (char *) MapViewOfFile(shmid_M, FILE_MAP_ALL_ACCESS, 0, 0, 0); /* attach */ if (rval == NULL) { printf("cpu%%d: failed to attach pool of shared memory nr %%d of size %%d\n", core_id, cnt-3, n); return NULL;init_HT(unsigned long n) /* WIN32/WIN64 version */ char *dc_mem_start; if (verbose) printf("cpu%%d: initialization for Windows\n", core_id); printf("cpu0: steps 0,1: -DMEMLIM=%%d Mb - (hashtable %%g Mb + workqueues %%g Mb)\n", MEMLIM, ((double)n/(1048576.)), ((double) NCORE * LWQ_SIZE + GWQ_SIZE)/(1048576.)); get_mem = NCORE * sizeof(double) + (1 + CS_NR) * sizeof(void *)+ 4*sizeof(void *) + 2*sizeof(double); get_mem += 4 * NCORE * sizeof(void *); get_mem += (NCORE) * sizeof(Stack_Tree *); /* NCORE * stack_last */ x = (volatile char *) prep_state_mem((size_t) get_mem); shmid_X = (void *) x; x += CS_NR * sizeof(void *); /* allow 1 word per entry */ printf("cpu0: step 0: -DMEMLIM=%%d Mb - (hashtable %%g Mb + workqueues %%g Mb) = %%g Mb for state storage\n", MEMLIM, ((double)n/(1048576.)), ((double) NCORE * LWQ_SIZE + GWQ_SIZE)/(1048576.), (memlim - memcnt - (double) n - ((double) NCORE * LWQ_SIZE + GWQ_SIZE))/(1048576.)); get_mem = memlim - memcnt - ((double) NCORE) * LWQ_SIZE - GWQ_SIZE; if (get_mem <= 0) { printf("cpu0: step 2: shared state memory %%g Mb\n", get_mem/(1048576.)); x = dc_mem_start = (char *) prep_state_mem((size_t) get_mem); /* for states */ { printf("cpu%%d: insufficient memory -- aborting\n", core_id); x += CS_NR * sizeof(int); gr_readmiss = (volatile double *) x; gr_writemiss = (volatile double *) x; stack_last = (volatile Stack_Tree **) x; x += NCORE * sizeof(Stack_Tree *); if (((long)x)&(sizeof(void *)-1)) /* word alignment */ { x += sizeof(void *)-(((long)x)&(sizeof(void *)-1)); /* 64-bit align */ #ifdef COLLAPSE ncomps = (unsigned long *) x; x += (256+2) * sizeof(unsigned long); dc_shared = (sh_Allocater *) x; /* in shared memory */ x += sizeof(sh_Allocater); if (core_id == 0) /* root only */ { dc_shared->dc_id = shmid_M; dc_shared->dc_start = (void *) dc_mem_start; dc_shared->dc_arena = x; dc_shared->pattern = 1234567; dc_shared->dc_size = (long) get_mem - (long) (x - dc_mem_start); dc_shared->nxt = NULL;#if defined(WIN32) || defined(WIN64) || defined(__i386__) || defined(__x86_64__)extern BOOLEAN InterlockedBitTestAndSet(LONG volatile* Base, LONG Bit);tas(volatile LONG *s){ return InterlockedBitTestAndSet(s, 1); #error missing definition of test and set operation for this platform static int nibis = 0; { if (shmid[m] != NULL) { UnmapViewOfFile((char *) shared_mem[m]); CloseHandle(shmid[m]); UnmapViewOfFile((void *) shmid_X); CloseHandle((void *) shmid_M); if (shmid_S != NULL) { UnmapViewOfFile(SS); CloseHandle(shmid_S); if (core_id == 0 && verbose) { printf("cpu0: done, %%ld Mb of shared state memory left\n", dc_shared->dc_size / (long)(1048576)); { UnmapViewOfFile(H_tab); shmid_M = (void *) (dc_shared->dc_id); UnmapViewOfFile((char *) dc_shared->dc_start); CloseHandle(shmid_M); #error MA requires SEP_STATE in multi-core mode #error BFS is not supported in multi-core mode #error SC is not supported in multi-core mode signal(SIGINT, give_up); /* windows control-c interrupt */ { printf("cpu0: step 4: creating additional workers (proxy %%d)\n", proxy_pid); if NCORE > 1 the child or the parent should fork N-1 more times the parent is the only process with core_id == 0 and is_parent > 0 the others (workers) have is_parent = 0 and core_id = 1..NCORE-1 if (core_id == 0) /* root starts up the workers */ { worker_pids[0] = (DWORD) getpid(); /* for completeness */ { char cmdline[64]; STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; if (proxy_pid == core_id) /* always non-zero */ { sprintf(cmdline, "pan_proxy.exe -r %%s-Q%%d -Z%%d", o_cmdline, getpid(), core_id); { sprintf(cmdline, "pan.exe %%s-Q%%d -Z%%d", if (verbose) printf("cpu%%d: spawn %%s\n", core_id, cmdline); is_parent = CreateProcess(0, cmdline, 0, 0, FALSE, 0, 0, 0, &si, &pi); if (is_parent == 0) worker_pids[core_id] = pi.dwProcessId; worker_handles[core_id] = pi.hProcess; { cpu_printf("created core %%d, pid %%d\n", core_id, pi.dwProcessId); if (proxy_pid == core_id) /* we just created the receive half */ { /* add proxy send, store pid in proxy_pid_snd */ sprintf(cmdline, "pan_proxy.exe -s %%s-Q%%d -Z%%d -Y%%d", o_cmdline, getpid(), core_id, worker_pids[proxy_pid]); if (verbose) printf("cpu%%d: spawn %%s\n", core_id, cmdline); is_parent = CreateProcess(0, cmdline, 0,0, FALSE, 0,0,0, &si, &pi); if (is_parent == 0) { Uerror("fork failed"); proxy_pid_snd = pi.dwProcessId; proxy_handle_snd = pi.hProcess; { cpu_printf("created core %%d, pid %%d (send proxy)\n", core_id, pi.dwProcessId); core_id = 0; /* reset core_id for root process */ tprefix = db0; sprefix = db1; sprintf(tprefix, "cpu%%d_trail", core_id); /* avoid conflicts on file access */ { new_state(); /* root starts the search */ cpu_printf("done with 1st dfs, nstates %%g (put %%d states), start reading q\n",init_SS(unsigned long n) SS = (uchar *) prep_shmid_S((size_t) n); init_HT(0L); "%s", #define SYNC %d #define ASYNC %d #ifndef NCORE #ifdef DUAL_CORE #define NCORE 2 #elif QUAD_CORE #define NCORE 4 #else #define NCORE 1 #endif short Air[] = { ,%s (short) Air%d, (short) Air%d }; char *procname[] = { ":np_:", }; np_#define WS %d /* word size in bytes */ #define StackSize () uchar sv[VECTORSZ]; } State; #define HAS_TRACK %d int addproc(int n, int par%d int provided(int II, unsigned char ot, int tt, Trans *t) { switch(ot) { default: return 1; /* e.g., a claim */ } return 0; } if (state_tables) ini_claim(%d, 0); iniglobals(); } void iniglobals(void) { #ifdef VAR_RANGES logval(" Maxbody = max(Maxbody, sizeof(State)-VECTORSZ); } endstopstateprogressprogstateacceptaccpstate %s[%d][%d] = 1; %s label inside d_step%s label inside atomic-spin: %3d:%s, warning, %s - is invisible visstate[%d][%d] = 1; spin: warning, line %3d %s, proctype %s:global '%s %s' could be declared 'bit %s' '%s %s' could be declared 'byte %s' ((P%d *)pptr(h))->; = %s%s:", ((P%d *)pptr(h))->); :never:error: %s defines local %s void c_chandump(int unused) { unused++; /* avoid complaints */ } void c_chandump(int from) { uchar *z; int slot; from--; if (from >= (int) now._nr_qs || from < 0) { printf("pan: bad qid %%d\n", from+1); return; } z = qptr(from); switch (((Q0 *)z)->_t) { case %d: ((Q%d *)z)->for (slot = 0; slot < %sQlen; slot++) { printf(" ["); printm(%scontents[slot].fld%d); printf("%%d,", %scontents[slot].fld%d); printf("],"); } break; printf("\n"); } printf(" (struct %s)\n"); %s%s. printf(" %s %s: %%d\n", %s%s); { int l_in; for (l_in = 0; l_in < %d; l_in++) { printf(" %s %s[%%d]: %%d\n", l_in, %s%s[l_in]); } printf(" chan %s (=%%d): len %%d:\t", %s%s, q_len(%s%s)); c_chandump(%s%s); printf(" chan %s[%d] (=%%d): len %%d:\t", %s%s[%d], q_len(%s%s[%d])); c_chandump(%s%s[%d]); :trace::notrace:((P%d *)pptr(pid))->void c_globals(void) { /* int i; */ printf("global vars:\n"); now.void c_locals(int pid, int tp) { /* int i; */ switch(tp) { case %d: printf("local vars proc %%d (%s):\n", pid); /* none */ break; } } void printm(int x) { switch (x) { case %d: Printf("%s"); break; default: Printf("%%d", x); ", now.cannot hide non-globals (%s)cannot hide channels (%s)/* hidden variable: */int _; /* a predefined write-only variable */ %s%s%s%s%s%s %s%s%s[%d]%s%s%s[%d] %s%s%s[l_in]%s%s%s[l_in]addqueue(%d, %d)%d:init:#define Pinit ((P%d *)this) _:never_template:_#define P%s ((P%d *)this) typedef struct P%d { /* %s */ unsigned _pid : 8; /* 0..255 */ unsigned _t : %d; /* proctype */ unsigned _p : %d; /* state */ } P%d; #define Air%d 0 #define Air%d (sizeof(P%d) - Offsetof(P%d, %s) - %d*sizeof(uchar)short)int)cannot happen Air %s#define _NP_ %d uchar reached%d[3]; /* np_ */ uchar *loopstate%d; /* np_ */ #define nstates%d 3 /* np_ */ #define endstate%d 2 /* np_ */ #define start%d 0 /* np_ */ case %d: /* np_ */ ini_claim(%d, h); ((P%d *)pptr(h))->_t = %d; ((P%d *)pptr(h))->_p = 0; reached%d[0] = 1; accpstate[%d][1] = 1; case %d: /* %s */ #define start%d %d #define start_claim %d #define start_event %d ((P%d *)pptr(h))->_p = %d; reached%d[%d]=1; case %d: /* %s */ if () return 1; /* params: */ array in parameter list, %s ((P%d *)pptr(h))->hidden array in parameter %s = par%d; /* locals: */ #ifdef HAS_CODE locinit%d(h); confusing control structure uchar %s; unsigned %s : %d unsigned %s : 1spin: warning: bit-array %s[%d] mapped to byte-array uchar %s short %s int %sundeclared structure element %s struct %s %svariable %s undeclared[%d]ushortuint Qlen; /* q_size */ #define NQS 1 /* nqs=%d, but has_io */ #define NQS %d short q_flds[%d]; short q_max[%d]; case %d: j = sizeof(Q%d); q_flds[%d] = %d; q_max[%d] = %d; break; typedef struct Q%d { uchar _t; /* q_type */ struct { unsigned fld%d : 1; uchar fld%d; short fld%d; int fld%d; bad channel spec } contents[%d]; } Q%d; typedef struct Q0 { /* generic q */ uchar _t; } Q0; int Q_has(int, int, intint Q_has(int into, int want%d, int fld%d{ int i; if (!into--) uerror("ref to unknown chan (recv-poll)"); if (into >= now._nr_qs || into < 0) Uerror("qrecv bad queue#"); for (i = 0; i < ((Q0 *)qptr(into))->Qlen; i++) { if (want%d && qrecv(into+1, i, %d, 0) != fld%d) continue; return i+1; return 0; #if NQS>0 void qsend(int into, int sorted, int fld%d, int args_given) /* =rv= */ case %d:%s (trpt+2)->o_m = 0; if (!sorted) goto append%d; for (j = 0; j < %sQlen; j++) { /* find insertion point */ ((Q%d *)z)->contents[j].fld if (fld%d > %s%d) continue; if (fld%d < %s%d) goto found%d; found%d: for (k = %sQlen - 1; k >= j; k--) { /* shift up */ %scontents[k+1].fld%d = %scontents[k].fld%d; append%d: /* insert in slot j */ #ifdef HAS_SORTED (trpt+1)->ipt = j; %sQlen = %sQlen + 1; %s%d = fld%d; if (args_given != %d) { if (args_given > %d) uerror("too many parameters in send stmnt"); else uerror("too few parameters in send stmnt"); case %d: return %d; case %d: return (q_sz(from) == %d); case %d:%s if (fld == 0) r = %scontents[slot].fld0; switch (fld) { default: Uerror("too many fields in recv"); if (done) { j = %sQlen - 1; %sQlen = 0; ((Q%d *)z)->contents { j = %sQlen; %sQlen = --j; for (k=slot; k#include #include #include #include #include #include #if defined(WIN32) || defined(WIN64)#include #else#include #include #include #include #include #define Offsetof(X, Y) ((unsigned long)(&(((X *)0)->Y)))#ifndef max#define max(a,b) (((a)<(b)) ? (b) : (a))#ifndef PRINTFint Printf(const char *fmt, ...); /* prototype only */#ifdef RANDOMIZE #define T_RAND RANDOMIZE#ifdef CNTRSTACK #define onstack_now() (LL[trpt->j6] && LL[trpt->j7]) #define onstack_put() LL[trpt->j6]++; LL[trpt->j7]++ #define onstack_zap() LL[trpt->j6]--; LL[trpt->j7]--#if !defined(SAFETY) && !defined(NOCOMP) #define V_A (((now._a_t&1)?2:1) << (now._a_t&2)) #define A_V (((now._a_t&1)?1:2) << (now._a_t&2)) int S_A = 0; #define V_A 0 #define A_V 0 #define S_A 0#ifdef MA#undef onstack_now#undef onstack_put#undef onstack_zap#define onstack_put() ;#define onstack_zap() gstore((char *) &now, vsize, 4)#if defined(FULLSTACK) && !defined(BITSTATE)#define onstack_put() trpt->ostate = Lstate#define onstack_zap() { \ if (trpt->ostate) \ trpt->ostate->tagged = \ (S_A)? (trpt->ostate->tagged&~V_A) : 0; \#ifndef NO_V_PROVISO#define V_PROVISO#if !defined(NO_RESIZE) && !defined(AUTO_RESIZE) && !defined(BITSTATE) && !defined(SPACE) && NCORE==1 #define AUTO_RESIZEstruct H_el { struct H_el *nxt;#ifdef FULLSTACK unsigned int tagged; #if defined(BITSTATE) && !defined(NOREDUCE) && !defined(SAFETY) unsigned int proviso; #endif#if defined(CHECK) || (defined(COLLAPSE) && !defined(FULLSTACK)) unsigned long st_id;#if !defined(SAFETY) || defined(REACH) unsigned int D;#ifdef BCS #ifndef CONSERVATIVE #define CONSERVATIVE 1 /* good for up to 8 processes */ #ifdef CONSERVATIVE #if CONSERVATIVE <= 0 || CONSERVATIVE>32 #error sensible values for CONSERVATIVE are 1..32 (256/8 = 32) #endif uchar ctx_pid[CONSERVATIVE]; uchar ctx_low;#if NCORE>1 /* could cost 1 extra word: 4 bytes if 32-bit and 8 bytes if 64-bit */ #ifdef V_PROVISO uchar cpu_id; /* id of cpu that created the state */#ifdef COLLAPSE #if VECTORSZ<65536 unsigned short ln; #else unsigned long ln;#if defined(AUTO_RESIZE) && !defined(BITSTATE) unsigned long m_K1; unsigned long state;} **H_tab, **S_Tab; typedef struct Trail { int st; /* current state */ uchar pr; /* process id */ uchar tau; /* 8 bit-flags */ uchar o_pm; /* 8 more bit-flags */#if 0 Meaning of bit-flags: tau&1 -> timeout enabled tau&2 -> request to enable timeout 1 level up (in claim) tau&4 -> current transition is a claim move tau&8 -> current transition is an atomic move tau&16 -> last move was truncated on stack tau&32 -> current transition is a preselected move tau&64 -> at least one next state is not on the stack tau&128 -> current transition is a stutter move o_pm&1 -> the current pid moved -- implements else o_pm&2 -> this is an acceptance state o_pm&4 -> this is a progress state o_pm&8 -> fairness alg rule 1 undo mark o_pm&16 -> fairness alg rule 3 undo mark o_pm&32 -> fairness alg rule 2 undo mark o_pm&64 -> the current proc applied rule2 o_pm&128 -> a fairness, dummy move - all procs blocked#ifdef NSUCC uchar n_succ; /* nr of successor states */#if defined(FULLSTACK) && defined(MA) && !defined(BFS) uchar proviso;#ifndef BFS uchar o_n, o_ot; /* to save locals */ uchar o_m;#ifdef EVENT_TRACE#if nstates_event<256 uchar o_event; unsigned short o_event; int o_tt; short o_To;#ifdef T_RAND short oo_i;#if defined(HAS_UNLESS) && !defined(BFS) int e_state; /* if escape trans - state of origin */#if (defined(FULLSTACK) && !defined(MA)) || defined(BFS) || (NCORE>1) struct H_el *ostate; /* pointer to stored state */#if defined(CNTRSTACK) && !defined(BFS) long j6, j7; Trans *o_t; /* bounded context switching option */ unsigned short sched_limit; unsigned char bcs; /* phase 1 or 2, or forced 4 */ unsigned char b_pno; /* preferred pid */#ifdef P_RAND short p_skip; /* to find starting point in list */ unsigned char p_left; /* nr of procs left to explore */#ifdef HAS_SORTED short ipt; union { int oval; int *ovals; } bup;} Trail;Trail *trail, *trpt;FILE *efd;uchar *this;long maxdepth=10000;long omaxdepth=10000; /* bitflags in trpt->bcs */ #define B_PHASE1 1 #define B_PHASE2 2 #define B_FORCED 4int sched_max = 0;#ifdef PERMUTED uchar permuted = 1; uchar permuted = 0;double quota; /* time limit */long z_handoff = -1;char *stackfile;uchar *SS, *LL;uchar HASH_NR = 0;double memcnt = (double) 0;double memlim = (double) (1<<30); /* 1 GB */double mem_reserved = (double) 0;/* for emalloc: */static char *have;static long left = 0L;static double fragment = (double) 0;static unsigned long grow;unsigned int HASH_CONST[] = { /* asuming 4 bytes per int */ 0x100d4e63, 0x0fc22f87, 0x3ff0c3ff, 0x38e84cd7, 0x02b148e9, 0x98b2e49d, 0xb616d379, 0xa5247fd9, 0xbae92a15, 0xb91c8bc5, 0x8e5880f3, 0xacd7c069, 0xb4c44bb3, 0x2ead1fb7, 0x8e428171, 0xdbebd459, 0x00400007, 0x04c11db7, 0x828ae611, 0x6cb25933, 0x86cdd651, 0x9e8f5f21, 0xd5f8d8e7, 0x9c4e956f, 0xb5cf2c71, 0x2e805a6d, 0x33fc3a55, 0xaf203ed1, 0xe31f5909, 0x5276db35, 0x0c565ef7, 0x273d1aa5, 0x8923b1dd, 0xa9acaac5, 0xd1f69207, 0xedfd944b, 0x9a68e46b, 0x5355e13f, 0x7eeb44f9, 0x932beea9, 0x330c4cd3, 0x87f34e5f, 0x1b5851b7, 0xb9ca6447, 0x58f96a8f, 0x1b3b5307, 0x31c387b3, 0xf35f0f35, 0xa0acc4df, 0xf3140303, 0x2446245d, 0xe4b8f4ef, 0x5c007383, 0x68e648af, 0x1814fba7, 0xcdf731b5, 0xd09ccb4b, 0xb92d0eff, 0xcc3c6b67, 0xd3af6a57, 0xf44fc3f5, 0x5bb67623, 0xaeb9c953, 0x5e0ac739, 0x3a7fda09, 0x5edf39eb, 0x661eefd9, 0x6423f0d1, 0x910fe413, 0x9ec92297, 0x4bd8159d, 0xa7b16ee1, 0x89d484e9, 0x7f305cb3, 0xc5f303e7, 0x415deeef, 0x09986f89, 0x7e9c4117, 0x0b7cbedb, 0xf9ed7561, 0x7a20ac99, 0xf05adef3, 0x5893d75b, 0x44d73327, 0xb583c873, 0x324d2145, 0x7fa3829b, 0xe4b47a23, 0xe256d94f, 0xb1fd8959, 0xe561a321, 0x1435ac09, 0xdd62408b, 0x02ec0bcb, 0x5469b785, 0x2f4f50bb, 0x20f19395, 0xf96ba085, 0x2381f937, 0x768e2a11, 0};extern int core_id;long mreached=0;int done=0, errors=0, Nrun=1;int c_init_done=0;char *c_stack_start = (char *) 0;double nstates=0, nlinks=0, truncs=0, truncs2=0;double nlost=0, nShadow=0, hcmp=0, ngrabs=0;#ifdef PUTPIDchar *progname;#if defined(ZAPH) && defined(BITSTATE)double zstates = 0;int c_init_run;#ifdef BFSdouble midrv=0, failedrv=0, revrv=0;unsigned long nr_states=0; /* nodes in DFA */long Fa=0, Fh=0, Zh=0, Zn=0;long PUT=0, PROBE=0, ZAPS=0;long Ccheck=0, Cholds=0;int a_cycles=0, upto=1, strict=0, verbose = 0, signoff = 0;#ifdef HAS_CODEint gui = 0, coltrace = 0, readtrail = 0;int whichtrail = 0, onlyproc = -1, silent = 0;int state_tables=0, fairness=0, no_rck=0, Nr_Trails=0;char simvals[128];#ifndef INLINEint TstOnly=0;unsigned long mask, nmask;#ifdef BITSTATEint ssize=23; /* 1 Mb */int ssize=19; /* 512K slots */int hmax=0, svmax=0, smax=0;int Maxbody=0, XX;uchar *noptr; /* used by macro Pptr(x) */#ifdef VAR_RANGESvoid logval(char *, int);void dumpranges(void);#define INLINE_REVextern void dfa_init(unsigned short);extern int dfa_member(unsigned long);extern int dfa_store(uchar *);unsigned int maxgs = 0;#ifdef ALIGNED State comp_now __attribute__ ((aligned (8))); /* gcc 64-bit aligned for Itanium2 systems */ /* MAJOR runtime penalty if not used on those systems */ State comp_now; /* compressed state vector */State comp_msk;uchar *Mask = (uchar *) &comp_msk;State comp_tmp;static char *scratch = (char *) &comp_tmp;Stack *stack; /* for queues, processes */Svtack *svtack; /* for old state vectors */static unsigned int hfns = 3; /* new default */static unsigned long j1_spin; /* 5.2.1: avoid nameclash with math.h */static unsigned long K1, K2;static unsigned long j2, j3, j4;static long udmem;static long A_depth = 0;long depth = 0;long nr_handoffs = 0;static uchar warned = 0, iterative = 0, exclusive = 0, like_java = 0, every_error = 0;static uchar noasserts = 0, noends = 0, bounded = 0;#if defined(T_RAND) || defined(P_RAND) || defined(RANDSTOR)unsigned int s_rand = 123; /* default seed */#if SYNC>0 && ASYNC==0void set_recvs(void);int no_recvs(int);#if SYNC#define IfNotBlocked if (boq != -1) continue;#define UnBlock boq = -1#define IfNotBlocked /* cannot block */#define UnBlock /* don't bother */#endif int (*bstore)(char *, int);int bstore_reg(char *, int);int bstore_mod(char *, int);void active_procs(void);void cleanup(void);void do_the_search(void);void find_shorter(int);void iniglobals(void);void stopped(int);void wrapup(void);int *grab_ints(int);void ungrab_ints(int *, int);Trans *settr( int t_id, int a, int b, int c, int d, char *t, int g, int tpe0, int tpe1){ Trans *tmp = (Trans *) emalloc(sizeof(Trans)); tmp->atom = a&(6|32); /* only (2|8|32) have meaning */ if (!g) tmp->atom |= 8; /* no global references */ tmp->st = b; tmp->tpe[0] = tpe0; tmp->tpe[1] = tpe1; tmp->tp = t; tmp->t_id = t_id; tmp->forw = c; tmp->back = d; return tmp;} cpytr(Trans *a) int i; tmp->atom = a->atom; tmp->st = a->st;#ifdef HAS_UNLESS tmp->e_trans = a->e_trans; for (i = 0; i < HAS_UNLESS; i++) tmp->escp[i] = a->escp[i]; tmp->tpe[0] = a->tpe[0]; tmp->tpe[1] = a->tpe[1]; for (i = 0; i < 6; i++) { tmp->qu[i] = a->qu[i]; tmp->ty[i] = a->ty[i]; tmp->tp = (char *) emalloc(strlen(a->tp)+1); strcpy(tmp->tp, a->tp); tmp->t_id = a->t_id; tmp->forw = a->forw; tmp->back = a->back;#ifndef NOREDUCEintsrinc_set(int n){ if (n <= 2) return LOCAL; if (n <= 2+ DELTA) return Q_FULL_F; /* 's' or nfull */ if (n <= 2+2*DELTA) return Q_EMPT_F; /* 'r' or nempty */ if (n <= 2+3*DELTA) return Q_EMPT_T; /* empty */ if (n <= 2+4*DELTA) return Q_FULL_T; /* full */ if (n == 5*DELTA) return GLOBAL; if (n == 6*DELTA) return TIMEOUT_F; if (n == 7*DELTA) return ALPHA_F; Uerror("cannot happen srinc_class"); return BAD;srunc(int n, int m){ switch(m) { case Q_FULL_F: return n-2; case Q_EMPT_F: return n-2-DELTA; case Q_EMPT_T: return n-2-2*DELTA; case Q_FULL_T: return n-2-3*DELTA; case ALPHA_F: case TIMEOUT_F: return 257; /* non-zero, and > MAXQ */ Uerror("cannot happen srunc"); return 0;int cnt;isthere(Trans *a, int b){ Trans *t; for (t = a; t; t = t->nxt) if (t->t_id == b) return 1;mark_safety(Trans *t) /* for conditional safety */{ int g = 0, i, j, k; if (!t) return 0; if (t->qu[0]) return (t->qu[1])?2:1; /* marked */ for (i = 0; i < 2; i++) { j = srinc_set(t->tpe[i]); if (j >= GLOBAL && j != ALPHA_F) return -1; if (j != LOCAL) { k = srunc(t->tpe[i], j); if (g == 0 || t->qu[0] != k || t->ty[0] != j) { t->qu[g] = k; t->ty[g] = j; g++; } } } return g;retrans(int n, int m, int is, short srcln[], uchar reach[], uchar lstate[]) /* process n, with m states, is=initial state */{ Trans *T0, *T1, *T2, *T3, *T4, *T5; int i, k; int g, h, j, aa; int p; if (state_tables >= 4) { printf("STEP 1 proctype %%s\n", procname[n]); for (i = 1; i < m; i++) for (T0 = trans[n][i]; T0; T0 = T0->nxt) crack(n, i, T0, srcln); return; do { for (i = 1, cnt = 0; i < m; i++) { T2 = trans[n][i]; T1 = T2?T2->nxt:(Trans *)0;/* prescan: */ for (T0 = T1; T0; T0 = T0->nxt)/* choice in choice */ { if (T0->st && trans[n][T0->st] && trans[n][T0->st]->nxt) break; } if (T0) printf("\tstate %%d / %%d: choice in choice\n", i, T0->st); if (T0) for (T0 = T1; T0; T0 = T0->nxt) { T3 = trans[n][T0->st]; if (!T3->nxt) { T2->nxt = cpytr(T0); T2 = T2->nxt; imed(T2, T0->st, n, i); continue; } do { T3 = T3->nxt; T2->nxt = cpytr(T3); } while (T3->nxt); cnt++; } } while (cnt); if (state_tables >= 3) { printf("STEP 2 proctype %%s\n", for (i = 1; i < m; i++) { if (trans[n][i] && trans[n][i]->nxt) /* optimize */ { T1 = trans[n][i]->nxt; printf("\t\tpull %%d (%%d) to %%d\n", T1->st, T1->forw, i); srcln[i] = srcln[T1->st]; /* Oyvind Teig, 5.2.0 */ if (!trans[n][T1->st]) continue; T0 = cpytr(trans[n][T1->st]); trans[n][i] = T0; reach[T1->st] = 1; imed(T0, T1->st, n, i); for (T1 = T1->nxt; T1; T1 = T1->nxt) { T1->st, T1->forw, i); /* srcln[i] = srcln[T1->st]; gh: not useful */ if (!trans[n][T1->st]) continue; T0->nxt = cpytr(trans[n][T1->st]); T0 = T0->nxt; reach[T1->st] = 1; imed(T0, T1->st, n, i); if (state_tables >= 2) { printf("STEP 3 proctype %%s\n", { if (!trans[n][i]) continue; /* check for each state i if an * escape to some state p is defined * if so, copy and mark p's transitions * and prepend them to the transition- * list of state i */ if (!like_java) /* the default */ { for (T0 = trans[n][i]; T0; T0 = T0->nxt) for (k = HAS_UNLESS-1; k >= 0; k--) { if (p = T0->escp[k]) for (T1 = trans[n][p]; T1; T1 = T1->nxt) { if (isthere(trans[n][i], T1->t_id)) T2 = cpytr(T1); T2->e_trans = p; T2->nxt = trans[n][i]; trans[n][i] = T2; } } } else /* outermost unless checked first */ { T4 = T3 = (Trans *) 0; T2->nxt = (Trans *) 0; if (T3) T3->nxt = T2; else T4 = T2; T3 = T2; if (T4) { T3->nxt = trans[n][i]; trans[n][i] = T4; } { if (a_cycles) { /* moves through these states are visible */ #if PROG_LAB>0 && defined(HAS_NP) if (progstate[n][i]) goto degrade; for (T1 = trans[n][i]; T1; T1 = T1->nxt) if (progstate[n][T1->st]) goto degrade; if (accpstate[n][i] || visstate[n][i]) if (accpstate[n][T1->st]) T1 = trans[n][i]; if (!T1) continue; g = mark_safety(T1); /* V3.3.1 */ if (g < 0) goto degrade; /* global */ /* check if mixing of guards preserves reduction */ if (T1->nxt) { k = 0; { if (!(T0->atom&8)) for (aa = 0; aa < 2; aa++) { j = srinc_set(T0->tpe[aa]); if (j >= GLOBAL && j != ALPHA_F) goto degrade; if (T0->tpe[aa] && T0->tpe[aa] != T1->tpe[0]) k = 1; } } /* g = 0; V3.3.1 */ if (k) /* non-uniform selection */ for (aa = 0; aa < 2; aa++) { j = srinc_set(T0->tpe[aa]); if (j != LOCAL) { k = srunc(T0->tpe[aa], j); for (h = 0; h < 6; h++) if (T1->qu[h] == k && T1->ty[h] == j) break; if (h >= 6) { T1->qu[g%%6] = k; T1->ty[g%%6] = j; g++; } } } if (g > 6) { T1->qu[0] = 0; /* turn it off */ printf("pan: warning, line %%d, ", srcln[i]); printf("too many stmnt types (%%d)", g); printf(" in selection\n"); goto degrade; /* mark all options global if >=1 is global */ for (T1 = trans[n][i]; T1; T1 = T1->nxt) if (!(T1->atom&8)) break; if (T1)degrade: for (T1 = trans[n][i]; T1; T1 = T1->nxt) T1->atom &= ~8; /* mark as unsafe */ /* can only mix 'r's or 's's if on same chan */ /* and not mixed with other local operations */ if (!T1 || T1->qu[0]) continue; j = T1->tpe[0]; if (T1->nxt && T1->atom&8) { if (j == 5*DELTA) { printf("warning: line %%d ", srcln[i]); printf("mixed condition "); printf("(defeats reduction)\n"); goto degrade; } for (T0 = T1; T0; T0 = T0->nxt) for (aa = 0; aa < 2; aa++) if (T0->tpe[aa] && T0->tpe[aa] != j) printf("[%%d-%%d] mixed %%stion ", T0->tpe[aa], j, (j==5*DELTA)?"condi":"selec"); printf(" '%%s' <-> '%%s'\n", T1->tp, T0->tp); } } { T2 = trans[n][i]; if (!T2 || T2->nxt || strncmp(T2->tp, ".(goto)", 7) || !stopstate[n][i]) continue; stopstate[n][T2->st] = 1; if (state_tables && !verbose) { printf("proctype "); if (!strcmp(procname[n], ":init:")) printf("init\n"); else printf("%%s\n", procname[n]); reach[i] = 1; tagtable(n, m, is, srcln, reach); } else { int nrelse; if (strcmp(procname[n], ":never:") != 0) { for (T0 = trans[n][i]; T0; T0 = T0->nxt) { if (T0->st == i && strcmp(T0->tp, "(1)") == 0) { printf("error: proctype '%%s' ", procname[n]); printf("line %%d, state %%d: has un", srcln[i], i); printf("conditional self-loop\n"); pan_exit(1); } } } nrelse = 0; { if (strcmp(T0->tp, "else") == 0) nrelse++; if (nrelse > 1) { printf("error: proctype '%%s' state", procname[n]); printf(" %%d, inherits %%d", i, nrelse); printf(" 'else' stmnts\n"); pan_exit(1); } } if (!state_tables && strcmp(procname[n], ":never:") == 0) { int h = 0; if (T0->forw > h) h = T0->forw; h++; frm_st0 = (short *) emalloc(h * sizeof(short)); frm_st0[T0->forw] = i;#ifndef LOOPSTATE if (state_tables) do_dfs(n, m, is, srcln, reach, lstate);#ifdef T_REVERSE /* process n, with m states, is=initial state -- reverse list */ if (!state_tables && strcmp(procname[n], ":never:") != 0) { for (i = 1; i < m; i++) { Trans *Tx = (Trans *) 0; /* list of escapes */ Trans *Ty = (Trans *) 0; /* its tail element */ T1 = (Trans *) 0; /* reversed list */ T2 = (Trans *) 0; /* its tail */ T3 = (Trans *) 0; /* remembers possible 'else' */ /* find unless-escapes, they should go first */ T4 = T5 = T0 = trans[n][i]; while (T4 && T4->e_trans) /* escapes are first in orig list */ { T5 = T4; /* remember predecessor */ T4 = T4->nxt; /* T4 points to first non-escape, T5 to its parent, T0 to original list */ if (T4 != T0) /* there was at least one escape */ { T3 = T5->nxt; /* start of non-escapes */ T5->nxt = (Trans *) 0; /* separate */ Tx = T0; /* start of the escapes */ Ty = T5; /* its tail */ T0 = T3; /* the rest, to be reversed */ /* T0 points to first non-escape, Tx to the list of escapes, Ty to its tail */ /* first tail-add non-escape transitions, reversed */ T3 = (Trans *) 0; for (T5 = T0; T5; T5 = T4) { T4 = T5->nxt; if (T5->e_trans) { printf("error: cannot happen!\n"); if (strcmp(T5->tp, "else") == 0) { T3 = T5; T5->nxt = (Trans *) 0; } else { T5->nxt = T1; if (!T1) { T2 = T5; } T1 = T5; /* T3 points to a possible else, which is removed from the list */ /* T1 points to the reversed list so far (without escapes) */ /* T2 points to the tail element -- where the else should go */ if (T2 && T3) { T2->nxt = T3; } /* add else */ /* add in the escapes, to that they appear at the front */ if (Tx && Ty) { Ty->nxt = T1; T1 = Tx; } trans[n][i] = T1; /* reversed, with escapes first and else last */ if (state_tables && verbose) { printf("FINAL proctype %%s\n", imed(Trans *T, int v, int n, int j) /* set intermediate state */{ progstate[n][T->st] |= progstate[n][v]; accpstate[n][T->st] |= accpstate[n][v]; stopstate[n][T->st] |= stopstate[n][v]; mapstate[n][j] = T->st;tagtable(int n, int m, int is, short srcln[], uchar reach[]){ Trans *z; if (is >= m || !trans[n][is] || is <= 0 || reach[is] == 0) reach[is] = 0; for (z = trans[n][is]; z; z = z->nxt) crack(n, is, z, srcln); { int i, j; tagtable(n, m, z->st, srcln, reach); for (i = 0; i < HAS_UNLESS; i++) { j = trans[n][is]->escp[i]; if (!j) break; tagtable(n, m, j, srcln, reach);dfs_table(int n, int m, int is, short srcln[], uchar reach[], uchar lstate[]) if (is >= m || is <= 0 || !trans[n][is]) if ((reach[is] & (4|8|16)) != 0) { if ((reach[is] & (8|16)) == 16) /* on stack, not yet recorded */ { lstate[is] = 1; reach[is] |= 8; /* recorded */ if (state_tables && verbose) { printf("state %%d line %%d is a loopstate\n", is, srcln[is]); reach[is] |= (4|16); /* visited | onstack */ dfs_table(n, m, z->st, srcln, reach, lstate); dfs_table(n, m, j, srcln, reach, lstate); reach[is] &= ~16; /* no longer on stack */do_dfs(int n, int m, int is, short srcln[], uchar reach[], uchar lstate[]){ int i; dfs_table(n, m, is, srcln, reach, lstate); for (i = 0; i < m; i++) reach[i] &= ~(4|8|16);crack(int n, int j, Trans *z, short srcln[]){ int i; if (!z) return; printf(" state %%3d -(tr %%3d)-> state %%3d ", j, z->forw, z->st); printf("[id %%3d tp %%3d", z->t_id, z->tpe[0]); if (z->tpe[1]) printf(",%%d", z->tpe[1]); if (z->e_trans) printf(" org %%3d", z->e_trans); else if (state_tables >= 2) { if (!z->escp[i]) break; printf(" esc %%d", z->escp[i]); printf("]"); printf(" [%%s%%s%%s%%s%%s] line %%d => ", z->atom&6?"A":z->atom&32?"D":"-", accpstate[n][j]?"a" :"-", stopstate[n][j]?"e" : "-", progstate[n][j]?"p" : "-", z->atom & 8 ?"L":"G", srcln[j]); for (i = 0; z->tp[i]; i++) if (z->tp[i] == '\n') printf("\\n"); putchar(z->tp[i]); if (z->qu[0]) { printf("\t["); for (i = 0; i < 6; i++) if (z->qu[i]) printf("(%%d,%%d)", z->qu[i], z->ty[i]); printf("]"); printf("\n"); fflush(stdout);#define BYTESIZE 32 /* 2^8 : 2^3 = 256:8 = 32 */typedef struct Vr_Ptr { char *nm; uchar vals[BYTESIZE]; struct Vr_Ptr *nxt;} Vr_Ptr;Vr_Ptr *ranges = (Vr_Ptr *) 0;logval(char *s, int v){ Vr_Ptr *tmp; if (v<0 || v > 255) return; for (tmp = ranges; tmp; tmp = tmp->nxt) if (!strcmp(tmp->nm, s)) goto found; tmp = (Vr_Ptr *) emalloc(sizeof(Vr_Ptr)); tmp->nxt = ranges; ranges = tmp; tmp->nm = s;found: tmp->vals[(v)/8] |= 1<<((v)%%8);dumpval(uchar X[], int range){ int w, x, i, j = -1; for (w = i = 0; w < range; w++) for (x = 0; x < 8; x++, i++)from: if ((X[w] & (1<= 0 && j != 255) printf("-255");dumpranges(void) printf("\nValues assigned within "); printf("interval [0..255]:\n"); { printf("\t%%s\t: ", tmp->nm); dumpval(tmp->vals, BYTESIZE); printf("\n");/*#define uchar unsigned char*/#define ulong unsigned long#define ushort unsigned short#define TWIDTH 256#define HASH(y,n) (n)*(((long)y))#define INRANGE(e,h) ((h>=e->From && h<=e->To)||(e->s==1 && e->S==h))extern char *emalloc(unsigned long); /* imported routine */extern void dfa_init(ushort); /* 4 exported routines */extern int dfa_member(ulong);extern int dfa_store(uchar *);extern void dfa_stats(void);typedef struct Edge { uchar From, To; /* max range 0..255 */ uchar s, S; /* if s=1, S is singleton */ struct Vertex *Dst; struct Edge *Nxt;} Edge;typedef struct Vertex { ulong key, num; /* key for splay tree, nr incoming edges */ uchar from[2], to[2]; /* in-node predefined edge info */ struct Vertex *dst[2];/* most nodes have 2 or more edges */ struct Edge *Succ; /* in case there are more edges */ struct Vertex *lnk, *left, *right; /* splay tree plumbing */} Vertex;static Edge *free_edges;static Vertex *free_vertices;static Vertex **layers; /* one splay tree of nodes per layer */static Vertex **path; /* run of word in the DFA */static Vertex *R, *F, *NF; /* Root, Final, Not-Final */static uchar *word, *lastword;/* string, and last string inserted */static int dfa_depth, iv=0, nv=0, pfrst=0, Tally;static void insert_it(Vertex *, int); /* splay-tree code */static void delete_it(Vertex *, int);static Vertex *find_it(Vertex *, Vertex *, uchar, int);static voidrecyc_edges(Edge *e) if (!e) return; recyc_edges(e->Nxt); e->Nxt = free_edges; free_edges = e;static Edge *new_edge(Vertex *dst){ Edge *e; if (free_edges) { e = free_edges; free_edges = e->Nxt; e->From = e->To = e->s = e->S = 0; e->Nxt = (Edge *) 0; e = (Edge *) emalloc(sizeof(Edge)); e->Dst = dst; return e;recyc_vertex(Vertex *v) recyc_edges(v->Succ); v->Succ = (Edge *) free_vertices; free_vertices = v; nr_states--;static Vertex *new_vertex(void){ Vertex *v; if (free_vertices) { v = free_vertices; free_vertices = (Vertex *) v->Succ; v->Succ = (Edge *) 0; v->num = 0; v = (Vertex *) emalloc(sizeof(Vertex)); nr_states++; return v; allDelta(Vertex *v, int n){ Vertex *dst = new_vertex(); v->from[0] = 0; v->to[0] = 255; v->dst[0] = dst; dst->num = 256; insert_it(v, n); return dst;insert_edge(Vertex *v, Edge *e){ /* put new edge first */ if (!v->dst[0]) { v->dst[0] = e->Dst; v->from[0] = e->From; v->to[0] = e->To; recyc_edges(e); if (!v->dst[1]) { v->from[1] = v->from[0]; v->from[0] = e->From; v->to[1] = v->to[0]; v->to[0] = e->To; v->dst[1] = v->dst[0]; v->dst[0] = e->Dst; } /* shift */ { int f = v->from[1]; int t = v->to[1]; Vertex *d = v->dst[1]; v->from[1] = v->from[0]; v->from[0] = e->From; e->From = f; e->To = t; e->Dst = d; e->Nxt = v->Succ; v->Succ = e;copyRecursive(Vertex *v, Edge *e){ Edge *f; if (e->Nxt) copyRecursive(v, e->Nxt); f = new_edge(e->Dst); f->From = e->From; f->To = e->To; f->s = e->s; f->S = e->S; f->Nxt = v->Succ; v->Succ = f;copyEdges(Vertex *to, Vertex *from) { to->from[i] = from->from[i]; to->to[i] = from->to[i]; to->dst[i] = from->dst[i]; if (from->Succ) copyRecursive(to, from->Succ);cacheDelta(Vertex *v, int h, int first){ static Edge *ov, tmp; int i; if (!first && INRANGE(ov,h)) return ov; /* intercepts about 10%% */ if (v->dst[i] && h >= v->from[i] && h <= v->to[i]) { tmp.From = v->from[i]; tmp.To = v->to[i]; tmp.Dst = v->dst[i]; tmp.s = tmp.S = 0; ov = &tmp; return ov; for (ov = v->Succ; ov; ov = ov->Nxt) if (INRANGE(ov,h)) return ov; Uerror("cannot get here, cacheDelta"); return (Edge *) 0;Delta(Vertex *v, int h) /* v->delta[h] */ if (v->dst[0] && h >= v->from[0] && h <= v->to[0]) return v->dst[0]; /* oldest edge */ if (v->dst[1] && h >= v->from[1] && h <= v->to[1]) return v->dst[1]; for (e = v->Succ; e; e = e->Nxt) if (INRANGE(e,h)) return e->Dst; Uerror("cannot happen Delta"); return (Vertex *) 0;numDelta(Vertex *v, int d) ulong cnt; if (v->dst[i]) { cnt = v->dst[i]->num + d*(1 + v->to[i] - v->from[i]); if (d == 1 && cnt < v->dst[i]->num) goto bad; v->dst[i]->num = cnt; { cnt = e->Dst->num + d*(1 + e->To - e->From + e->s); if (d == 1 && cnt < e->Dst->num)bad: Uerror("too many incoming edges"); e->Dst->num = cnt;setDelta(Vertex *v, int h, Vertex *newdst) /* v->delta[h] = newdst; */{ Edge *e, *f = (Edge *) 0, *g; /* remove the old entry, if there */ { if (h == v->from[i]) { if (h == v->to[i]) { v->dst[i] = (Vertex *) 0; v->from[i] = v->to[i] = 0; v->from[i]++; } else if (h == v->to[i]) { v->to[i]--; } else { g = new_edge(v->dst[i]);/* same dst */ g->From = v->from[i]; g->To = h-1; /* left half */ v->from[i] = h+1; /* right half */ insert_edge(v, g); goto part2; for (e = v->Succ; e; f = e, e = e->Nxt) { if (e->s == 1 && e->S == h) { e->s = e->S = 0; goto rem_tst; if (h >= e->From && h <= e->To) { if (h == e->From) { if (h == e->To) { if (e->s) { e->From = e->To = e->S; e->s = 0; break; } else goto rem_do; e->From++; } else if (h == e->To) { e->To--; } else /* split */ { g = new_edge(e->Dst); /* same dst */ g->From = e->From; g->To = h-1; /* g=left half */ e->From = h+1; /* e=right half */ g->Nxt = e->Nxt; /* insert g */ e->Nxt = g; /* behind e */ break; /* done */rem_tst: if (e->From > e->To) { if (e->s == 0) {rem_do: if (f) f->Nxt = e->Nxt; else v->Succ = e->Nxt; e->Nxt = (Edge *) 0; recyc_edges(e); { e->From = e->To = e->S; e->s = 0; break;part2: /* check if newdst is already there */ if (v->dst[i] == newdst) { if (h+1 == (int) v->from[i]) { v->from[i] = h; return; if (h == (int) v->to[i]+1) { v->to[i] = h; { if (e->Dst == newdst) { if (h+1 == (int) e->From) { e->From = h; if (e->s == 1 && e->S+1 == e->From) { e->From = e->S; e->s = e->S = 0; if (h == (int) e->To+1) { e->To = h; if (e->s == 1 && e->S == e->To+1) { e->To = e->S; if (e->s == 0) { e->s = 1; e->S = h; /* add as a new edge */ e = new_edge(newdst); e->From = e->To = h; insert_edge(v, e);static ulongcheap_key(Vertex *v){ ulong vk2 = 0; if (v->dst[0]) { vk2 = (ulong) v->dst[0]; if ((ulong) v->dst[1] > vk2) vk2 = (ulong) v->dst[1]; } else if (v->dst[1]) vk2 = (ulong) v->dst[1]; if (v->Succ) { Edge *e; for (e = v->Succ; e; e = e->Nxt) if ((ulong) e->Dst > vk2) vk2 = (ulong) e->Dst; Tally = (vk2>>2)&(TWIDTH-1); return v->key;mk_key(Vertex *v) /* not sensitive to order */{ ulong m = 0, vk2 = 0; Edge *e; { m += HASH(v->dst[0], v->to[0] - v->from[0] + 1); vk2 = (ulong) v->dst[0]; if (v->dst[1]) { m += HASH(v->dst[1], v->to[1] - v->from[1] + 1); if ((ulong) v->dst[1] > vk2) vk2 = (ulong) v->dst[1]; { m += HASH(e->Dst, e->To - e->From + 1 + e->s); if ((ulong) e->Dst > vk2) vk2 = (ulong) e->Dst; return m;mk_special(int sigma, Vertex *n, Vertex *v) Edge *f; if (v->dst[i]) { if (sigma >= v->from[i] && sigma <= v->to[i]) { m += HASH(v->dst[i], v->to[i]-v->from[i]); if ((ulong) v->dst[i] > vk2 && v->to[i] > v->from[i]) vk2 = (ulong) v->dst[i]; { m += HASH(v->dst[i], v->to[i]-v->from[i]+1); if ((ulong) v->dst[i] > vk2) for (f = v->Succ; f; f = f->Nxt) { if (sigma >= f->From && sigma <= f->To) { m += HASH(f->Dst, f->To - f->From + f->s); if ((ulong) f->Dst > vk2 && f->To - f->From + f->s > 0) vk2 = (ulong) f->Dst; } else if (f->s == 1 && sigma == f->S) { m += HASH(f->Dst, f->To - f->From + 1); if ((ulong) f->Dst > vk2) vk2 = (ulong) f->Dst; } else { m += HASH(f->Dst, f->To - f->From + 1 + f->s); if ((ulong) n > vk2) vk2 = (ulong) n; m += HASH(n, 1);void dfa_init(ushort nr_layers){ int i; Vertex *r, *t; dfa_depth = nr_layers; /* one byte per layer */ path = (Vertex **) emalloc((dfa_depth+1)*sizeof(Vertex *)); layers = (Vertex **) emalloc(TWIDTH*(dfa_depth+1)*sizeof(Vertex *)); lastword = (uchar *) emalloc((dfa_depth+1)*sizeof(uchar)); lastword[dfa_depth] = lastword[0] = 255; path[0] = R = new_vertex(); F = new_vertex(); for (i = 1, r = R; i < dfa_depth; i++, r = t) t = allDelta(r, i-1); NF = allDelta(r, i-1);static void complement_dfa(void) { Vertex *tmp = F; F = NF; NF = tmp; }doubletree_stats(Vertex *t){ Edge *e; double cnt=0.0; if (!t->key) return 0; t->key = 0; /* precaution */ if (t->dst[0]) cnt++; if (t->dst[1]) cnt++; for (e = t->Succ; e; e = e->Nxt) cnt++; cnt += tree_stats(t->lnk); cnt += tree_stats(t->left); cnt += tree_stats(t->right); return cnt;dfa_stats(void){ int i, j; double cnt = 0.0; for (j = 0; j < TWIDTH; j++) for (i = 0; i < dfa_depth+1; i++) cnt += tree_stats(layers[i*TWIDTH+j]); printf("Minimized Automaton: %%6d nodes and %%6g edges\n", nr_states, cnt);dfa_member(ulong n){ Vertex **p, **q; uchar *w = &word[n]; p = &path[n]; q = (p+1); for (i = n; i < dfa_depth; i++) *q++ = Delta(*p++, *w++); return (*p == F);dfa_store(uchar *sv){ Vertex **p, **q, *s, *y, *old, *new = F; uchar *w, *u = lastword; int i, j, k; w = word = sv; while (*w++ == *u++) /* find first byte that differs */ ; pfrst = (int) (u - lastword) - 1; memcpy(&lastword[pfrst], &sv[pfrst], dfa_depth-pfrst); if (pfrst > iv) pfrst = iv; if (pfrst > nv) pfrst = nv;/* phase1: */ p = &path[pfrst]; q = (p+1); w = &word[pfrst]; for (i = pfrst; i < dfa_depth; i++) *q++ = Delta(*p++, *w++); /* (*p)->delta[*w++]; */ if (*p == F) return 1; /* it's already there *//* phase2: */ iv = dfa_depth; do { iv--; old = new; new = find_it(path[iv], old, word[iv], iv); } while (new && iv > 0);/* phase3: */ nv = k = 0; s = path[0]; for (j = 1; j <= iv; ++j) if (path[j]->num > 1) { y = new_vertex(); copyEdges(y, path[j]); insert_it(y, j); numDelta(y, 1); delete_it(s, j-1); setDelta(s, word[j-1], y); insert_it(s, j-1); y->num = 1; /* initial value 1 */ s = y; path[j]->num--; /* only 1 moved from j to y */ k = 1; { s = path[j]; if (!k) nv = j; y = Delta(s, word[iv]); y->num--; delete_it(s, iv); setDelta(s, word[iv], old); insert_it(s, iv); old->num++; for (j = iv+1; j < dfa_depth; j++) if (path[j]->num == 0) { numDelta(path[j], -1); delete_it(path[j], j); recyc_vertex(path[j]);splay(ulong i, Vertex *t){ Vertex N, *l, *r, *y; if (!t) return t; N.left = N.right = (Vertex *) 0; l = r = &N; for (;;) { if (i < t->key) { if (!t->left) break; if (i < t->left->key) { y = t->left; t->left = y->right; y->right = t; t = y; if (!t->left) break; r->left = t; r = t; t = t->left; } else if (i > t->key) { if (!t->right) break; if (i > t->right->key) { y = t->right; t->right = y->left; y->left = t; if (!t->right) break; l->right = t; l = t; t = t->right; l->right = t->left; r->left = t->right; t->left = N.right; t->right = N.left; return t;insert_it(Vertex *v, int L){ Vertex *new, *t; ulong i; int nr; i = mk_key(v); nr = ((L*TWIDTH)+Tally); t = layers[nr]; v->key = i; if (!t) { layers[nr] = v; t = splay(i, t); if (i < t->key) { new = v; new->left = t->left; new->right = t; t->left = (Vertex *) 0; } else if (i > t->key) new->right = t->right; new->left = t; t->right = (Vertex *) 0; } else /* it's alread