ELF>`@@p @8 @%"@@@@@88@8@@@( ( . .i.i@% @. @.i@.iTT@T@ Ptd@@H@HQtdRtd. .i.i/lib64/ld-linux-x86-64.so.2GNU%.!- &" *,( )'$%   #++ +,)fUa9$ (qD>;jM+R-Y4!L#5Tjyjj__gmon_start__libc.so.6fflushstrcpyexitsprintf_IO_putcfopenstrncmpstrncpytime__stack_chk_failunlinkputcharstdinfgetsstrlenungetcmemsetgetcharstrstrstdoutfputcfputsmemcpyfclosemallocstrcat__ctype_b_locsscanfstderrsystemfscanf__sysv_signalfwriteatoistrchrfprintf_IO_getcstrcmp__libc_start_mainfree__xstatGLIBC_2.4GLIBC_2.3GLIBC_2.2.5ii Zii dui n/ij,j-j+0i0i0i0i 0i(0i00i80i @0i H0i P0i X0i `0ih0ip0ix0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i 0i!1i"1i#1i$1i% 1i&(1i'01i(81i)@1i*Hr H52!)%4!)@%2!)h%*!)h%"!)h%!)h%!)h% !)h%!)h% )hp% )h`% )h P% )h @% )h 0% )h % )h % )h% )h% )h% )h% )h% )h% )h% )h% )h%z )hp%r )h`%j )hP%b )h@%Z )h0%R )h %J )h%B )h%: )h%2 )h %* )h!%" )h"% )h#% )h$% )h%% )h&%)h'p%)h(`1I^HHPTICH CH1@HHI)HtHÐUHSH=X*uK0.iHR*H-(.iHHXH9s%HBH-*(.iH*H9r *H[fff.UH=)HtHt8.iIA@ÐUHH}uHUH}uHEZDUHSHEHHEHHEHEEEE,,HEHEHEHEHEEHEfH+EHHH?H)HEH;EqHUHEHH)HHHHEH}'2/HeH}'vHE'HEHEHUHHHHHxHEH}.HEHH}HuHEHEHEHHHEHEHHHEHEHH}HuHEHEHEHHHxHxHHHEHH9Et H}H+EHHH?H)HEHEH+EHHH=H)HEHEH+EHHH?H)HEH;E-EHCE},u d ,,EE܉,:,=Mw,H@Cp DžppE܋EE}}EH@C;EuyEHCE}}+}X+]b}),}tm:,t ,,EEHEH",HEH&EH`CE}g+EHCEظ+EHHHEHHE}o*EH(D,V*HEH8$]oHEH8HEHH@H+H+HEHHHBP**Ϋ*)***)cD!)HEHHHEHHHDHHEHHP HEH(H0HEH@HHxIDHpHEHPHHHEHPH@EKHEHHHtHEHH@t DžtHptEHEHPH@;ED,tHEH@HHPHEHPHHBPHptt*u Hp@#H+y(/蘧HEHE@L(/kHEHE@(HE(/1HEHE@'/HEHEHHPHEPHEHH@='DD'/襦HEHE@HEHHH@@ fu!HEHHH@H0D蛣%'HEHHH@H@Pf=/t!HEHHH@H0D^&HEHHH@H@PPHEP&HEHH@H+&HEHHP H=+AHhHEHHHtHEHH@x DžxHhxDH+ &HEHH@Hy+Hʧ*HtH5*DbHEHH@HH*%HEHHP HEHHHxA$H+%HEHH@H+HJ*HtH5>*DڡHEHH@HH*%**@%HEHHP HEHHHxAHq+צ*Φ*$HV+HtHEHH@H0D-HEHH@H7-$HEHH8Hg7-$HEHHE$HEHHE1*n$HEHH@H0"D赡Q$ **=$HEHH0HEH HHxOץ*Υ* $HEHHpHEHHHx/f^+W+f+#HEHHpHEHHHx4/f++fX+#HEHHPHEHHHpHEHHHx.f++f+@#HEHHPHEHHHpHEHHHx.f++f+"**[NH`**HEHUH`HBfV+"A*8*MHX**HXf@ fHEHUHXHBf+ "ƣ**rMHP**HEHUHPHBHPH8|Gf^+!!@蠠H[!HHEHP A!HEHH1!HEH8n !HEHH!HEH8M HE HEHHpHEH8jHE 6D SD HEHHE HEH0HEHH8HEs HEf HEHHEV HEHHEF HEHHE6 HEHHHEHHpHEH8.eHEHHE HEHHHEHHHpHEH8{5*HEH8HEHEH H@=tpDHEHH8kHEH(HHtHEH(HH@H0DћH+HPD蠜<HEH,YHEHEHHEHH,/HEHEHEHHEHEHHEH81HEHEHHEHHHEHH81輝HE{HEH80蘝HEWHEHHEHH80nHE-HEHHEHEHHX/6HCPHEHH@H@P@HEHHHPHEHHBPHEHHHEHEH0HEHH8Z^HEHf=/t$HEHf=2u#HEHH@H@pHt<*\-*MHEHHHPHEHHBPHEHHHE*HEH(H@tx+o+c+Z+HEHH8vEЋ}*E9M‰o*HEHH@՛HEHEH(HPHEPHEHH@@HEHHE]HEHHHPHEH@BHEH@?v*HEHHH@H0D臘HEH@?HEHHH@@HEHHHEHEHHHPHEHH@BHEHHH@@HEHHHE5H*HEH82HEwHEH82蔚HESH.-CHEHHHEH H82VHE*ٜ*HEHH@@ f=HEHH@H@`H--HEHHHEHEHHEHP8HEHHt.HEHHH@@ f=tHEHHH@f@ G*>*8*u>*u4HEHHH@@ fuHEHHH@H0D蔖HEHHtHEHHp0HEHH8~H,-HEHEH.HEHEHHEHEHHEq*D~/*&*j**+f+HEHHEHHHEHH8r[HEHEH8Ry]****Y+fO+HEHHEHHHEHH8sHEHE@HEH8S\HEH8UsHEHH8茗HEHEHHHP(HEHP(H})+!HEHH8:HEHEHHHP(HEHP(H}HEHHEHPHEH8ĖHEHEHH@@ ft-HEHH@@ f=tHEHH@H0D踓HEHH@f@ 1HEHHEHH8:HHEHEHHH@@ ft5HEHHH@@ f=tHEHHH@H0D0HEHHH@f@ HEHHEHHHEHH8:趕HEHEH0HEHH8WHEH0HEHH8HEHH82/QHEHE@HEHHHM+$HEHEHHHEHH8HM:HEHEHH0HEHH8`VHEHH8vHEHHH@@ f@xDȒd/胔HEHE@HEHHHM-VHEHEHHHEHH8HM:.HEHEHH0HEHH8UHEHH8HEHHH@@ f@$D)HEHHHEHH8蚓HEO)OHEHHhHE'HEHH@HEHEHHEHEH8HEHHEk*b*W*N*+f+HEHHEHHHEHH8r藒HEf+HE@HEH8RW,ݔ*Ԕ*ɔ**+fw+HEHHHEH(HHEH(H8rHEHE@HEHH8RWP*G*<*3*+f+HEHHHEH(HHEH(H8rxHEHE@f+HEHH8R~V ****^+fT+HEHHEHHHEHH8sHEf`+HE@HEH8SUHEH8NoHEHc茐HEH}VNBaHE HEH(H8*HEQHǾYHHEHP(HEH@(H8dHEH(H8跏HEHǾHHEHP(HEH@(H8 :+JHEqHǾyHHEHP(**HEHH0HEH HHx6i*`*HEHHEHEHHx HHEHP(kHEHHp(HEHHHx HHEHP(<-LHEsHHEHP HEHHEHEHHEHEHHHEHEHHEHH+ٍHEHEHHEHH-词HEnHEHHEHH*腍HEDHEHHEHH/[HEHEHHEHH%1HE HEHHEHH&HE HEHHEHH^݌HE HEHHEHH|賌HEr HEHHEHHF艌HEH HEHHEHHE_HE HEHHEHHD5HE HEHHEHHC HE HEHHEHHBHE HEHHEHHA跋HEv HEHHEHH@荋HEL HEHHEHH?cHE" HEHHEHHH9HE HEHHEHHGHE HEH~HE HEHLNJHE HEH!裊HEb HEHHHEHH?uHEHEH(HHM?SHE Ì**Hg+H <DC **HEHHHEH(H8 HEHEHHtHEH@| Dž|HE|PHEH(H0HEHH8ANH}LD HEHHHEHH8 WHE HEHH /HE+f+ ** z*q*2+f(+HEHHHEH(HHEH(H8R趈HEu &**a * *+f+HEHHHEH(HHEH(H8RNHEf+HE@HEHHEHEH8ʆHEHHE/HEHEHPHEfPHEHPHEP!覇HEe"脇HE+f+2HEHHKHE+f+HEHHPHEHH0HEH(HHxHEHEHHH0HEHHPHEHH0HEH(HHx詋HEHEHHPHEHHHxHE[HEHHH0HEHHPHEHHHxDHE#HEHEHHEHEHHEHEHHEHEHEHH8quXD'HEHEHHHEHEpDyHEHHEiHEHHHEUHEHHEHH@lHE+HEHHEHH@BHEHEHHEHH?HEHEHHEHH?HEHEHHEHH@ĄHEHEHHEHH?蚄HEYHEHHHEHH8+lHE+HEHHHEHH8->HEHEHHHEHH8,HEHEHHHEHH8.HEHEH@HEHPHEPHE@tDā`HEHHPHEHPHE@=HEHpHEH8UHEHEHHEHHpHEHH8"HEHEHEHHEHEHEHHEHEHHEHEHHf,u$HEHH0HEHH8HE_HEHHHEHH,rHE1HEHf,uHEHHEHEH,.HEHEHHf,u HEH0HEHH8HEHEHHEHH,ЁHEHEHHEHEH0HEH8,CHEH8M`HEHH yHEHEHH8(/GHEHEHPHEfPHEHPHEP/HEHEH@HEPHEHf,uHEHHEHEH,言HEgHEHHf,u HEH0HEHH8HE3HEHHEHH,JHE HEHHf,u$HEHH0HEHH80HEHEHHHEHH,HEHEHHHEHEH82HEHU,HERHEH82oHEHEHHHU,MHEHEHHHEEHHHHEEHHHHEEHEHUHEHEHCEEbHCHEE}x8}/EH@CHEf9uEHCEEbHCE}u,,D}u6[,Q,uܺlD+,EEHCE}t=E}x3}*EH@CfuEHCE}AHEH;EtdEHDHUD2HmHmHEEh})tHEH,HUHEEEEDE:,t0,tuܺlDEHHHHEEHHHHE,HEHDHUDbHmHmHEH;EuHH9Et H}EHĈ[UHHHXH`HhLpLxH@H@HHDž@C@H)@HEH@)x)p)h)`)X)P)H)@HHHH'yÐUH}}"t} t EEEUHH} HEHHHu}_u EEEUHH}HEHHH%UHH}HEHHH%UHH0}HuEMEHclEYMEHclE}\u>(yH=,EE؋E؉EMEHclEm(yH=ެ,EE܋E܉E}HEЅmEHƀl'(yH5,}(UHH0}uU(yH=e,8EAE܋E܉EE;EuEE&(yH5,,}EEEUHH@H}uHUHMLEH}HxwHEHuH}H+HEpHEHH0HEH8iuJHEHH0 DvHUHEHPHUHEHBHUEB(H,HEHP0HEH@@HEH}uHCwHEHUHEHHUHEHPHUHEHBHEt.H}HxvHHEHP HEHx HuHUEB(H ,HEHP0H+HEHP@HEHs+UHH0H}؋,'HMغ 4 DHMغ> DnHMغR DV+fH+HEHEH@ ftHEH@ fRHEHHH}ؾg DHEH@HEHEHE< tHE< tHE<\tHuؿ"QEHEEԃ}"t}%t"} t1IHMغq DlBH}ؾt Dg-HMغw D=HEHuHHEEHEt }bHEtHMغz DHuؿ"vHMغ~ DHEH@@HEH}qHMغ DHMغ DwUHH H}H+HE,HEHH0H}u EHEH@@HEH}uEEUHH H&+HtWH+EHBH+}u_H~+ S(HcH@kEHHcH@k) ((HcH@kEHHcH@k}un(HHŠk@,((HHŠkH@8H,(((yH=',EEEEEEEUHH~+HtH ~+HH~+ \(HcH@kHPHcH@kUHH H}Hi+HE#HEHH0H}HtHEH@@HEH}uH}uHu迠 D8rHEUHH0H}HuHUؿ =rHEHUHEHHUHEHBHUHEHBH|+HEHPHEH|+UHH0H}HuHUؿ qHEHUHEHHUHEHBHUHEHBHI|+HEHPHEH6|+H}t~HEH8 D>uHEH@[HEH8 Dt=HEH8 Dt(HEH8 DtHEH0 D p fyu*UHH H}HEHEHEHE< tHE< tHEHE< tHE< uHEHE< tHE< tHEHE<*tHEHE< tHE< tHEuHuD8pH}[Ht+H}{HuHu0DoHEHEHEHEUHH0H}HMغYDH}z+HEvHEH@HYHEH@H8pDHEH@HHE.HE<"uHE HE<\u HE HEHEHEuHEHH8AHEH}HEH@HHUH}ؾyD?HEH@H8D0HEH@HHE.HE<"uHE HE<\u HE HEHEHEuHEHH8HEH}t"HEH@HHUH}ؾDHEH@HEH}HMغDSUHHPH}ȉuHUEUH}ȾD1Hx+HEvHEH@HYHEH@H8D7HEH@HHEHE<"uHE HEHEuHEHH8}HEHEH@HHHEHEHE< tHE< tH}?HxKmHEHuH}H}HHEHE HEHmHE< tHE< tHuH}诿uT}tHMȺDݿEH}t(HEH@HHMUH}ID跿HEH@HEH}HMȺDxUHH+*Hv+Ht+*Hv+HErHEH@H8pDBtHHEH@H8D$t*HEH@H8Dt @+*HEH@HEH}uUHH@H}EH/v+HuH+v+Hu EH v+HEGHEH@H8pD胼uHEHHH}DRHEH@HEH}uHu+HEjHEH@H8pD(t@HEH@H8D t"HEH@H8DtEHEH@HEH}uH:u+HEEHEH@HEH}u}u EEHMD\Ht+HEHEH@H8pDRHEH@H8D0tdHEH@H8DtFHEH@HHEȃ}u HE DHE DH}HMHUо D輼EHEH@HEH}EHt+HE_HEH@HuFHEH@HHE؃}u HE DHE DH}HMHUDEEHEH@HEH}u}uHu4誺HMDEEUHH0H}EH\s+HE_HEH@HtFHEH@HHE؃}u HE DHE DH}HMHUD臻EHEH@HEH}u}uHM"DBUHH H}EHr+Hu Hr+Ht[fl*ftOHr+HEHEH@HtEHEH@HEH}u܃}~HM%D躺UHSHH}H,r+HEHEH@H8AD衸uiHEHHHEHH8DHH HEHHHPH}JDHHEHHHEHH8HH"HEH@HEH}bH[UHH H}HuHgq+HHu࿀j船j螸HjHǺ\DH'q+HEHEH@H8D蜷u_HEH@HHHEHEHE< tHE< tH}juHEHHH}D)HEH@HEH}lUHSHH}HM,`D۸H\p+HE$HEHHHEHH8蒷HH HEHH HEH@HHEH@H8_HH HEH@H HEH@H8pDlHEH@H8DJtsHEH@H8D,tUHEHH8&tHtHEHH0DdHEHHHEH@HH}ྯD÷HEH@HEH}H%o+HEqHEHHHEHH8VHH HEHH HEH@HHEH@H8#HH HEH@H HEH@HEH}uq,uHMD|@h*f\HM#DǶHMD诶HM D藶H} D蔶HMDlHm+HEHEH@HHEHHH}FD>HEH@HHEHHH}ODHMiDHEH@HH}pDHEH@HH}ྉDµHEH@HEH}?HMD胵HMDkHM DSH}DPHMD(Hl+HEHEH@H8pDHEH@H8DtdHEH@H8D޲tFHEH@HHEHHH}D袴HEH@HH} D脴HEH@HEH}EHk+HEHEH@HHEHHH}FD/HEH@HHEHHH}ODHMiD߳HEH@HH}pDѳHEH@HH}ྉD賳HEH@HEH}?HMDtd*fHM(DLHM D4H}HD1HMD Hj+HE|HEH@HtcHEHHH}FDHEH@HHEHHH}pD躲HEH@HH}ྉD蜲HEH@HEH}yHMD]HMDEHM D-H}ྰD*HMDHi+HEHEH@H8pDHEH@H8D֯tdHEH@H8D踯tFHEH@HHEHHH}D|HEH@HH} D^HEH@HEH}EHh+HE|HEH@HucHEHHH}FDHEH@HHEHHH}pDHEH@HH}ྉDʰHEH@HEH}yHMD苰HMDsH[UHH0H}HuUH}HEHp@UH}HEHH@pHHEH@ ;EHEHHH}DHEH@HEHEHE< tHE< tHE<\tHEHE HE HEH}DʮHEH}uHUH}D舯HEHHH}DkUHHH}H5+H}UHHH},u*tH} H}FH5+H}}Hjf+Hu Hff+HtHM'D蹮HM;D蟮*t H}H}cH} UHHHXdH%(HE1HȲ+HHв+HhH+HH0HhHH8ŭHhHHHpLDHXH@HHpHt@HhHHH/+HH0XDrHXHH0DWZHhH@(HhHh7HEdH3%(tUHH H}HuH}xHEH}HEH@HHukUHH H}HuH}HEf=HEH@H8HEHEH@ HHEHP H}辰D转HM%D蕬HEHP H}D芬HEHP H}(DoHMYDG"HEHp8H}HEHp0H} UHH H}H}HHEHEH@HEH}tDHuH}([H;Ev EEEUHH0H}HuUH}HEH}HMyD}HEH@ HHEHP H}辰DYHM%D1HEHP H}D&HEHP H}(D HM|DHEH@HHuHMD跪UHH H}H}HEHEH@HEH};Hu&H}D蟩HuH}D茩HtuHE@((HEH@0Hk,Hu连D VbHEHtHEH<E؋E؉E} t D T(yH=$,EE܋E܉E}cuHDS}_D@olBT(R(yH=Ç,薥EEEE} } txD`S (yH={,NEWEEE}"txD"S}C@(yH=0,"E "E}tDRlߤHlHǺDWlH,L(yH=,萤 E E}uUHH H}E(yH=w,JESEEEEHEHEEE}[t}]t} u((랃E똃m}HmHEUHH`H}HuEHEHEvHEH@0Ht]HEH@0f=2t*H}t HEHHEHEDHuDsQHEH@0HPHEH@0H@@ BHEH@8HEH}uH}udVQHEȿ HQHHEH(ƒ(HEH8D2H+HEHPpHEf@  HEf@ HEjfY*d(yH=Մ,訢EEEEMM} } }Ń} t} t0B}[t}{tY} t.HE@ fu2j뉋((uuD!HEH0 D P(EHE@ fuI+, t&HE,H(Dj: DjR$H ,HH(-Dj̡j蒡HEEE(yH=,ZEcEEEEHEHEHU฀jHH)HH=~<D OEE}#}#=} } } } } t } }{t&}}t-L(C(EEEEm}HEHE@ fu HmHEHEuH}IjjH}t#HEHH~,HuXD HEÃ}uHm}p{EEkEbEERUHSH8_(yH=Ё,裟EEЋEЉEEy,y,E Ẽ}EHD((Q*u}끋}C@(yH=D,"E "E׀}tlDLlHlHǺDkNQ*xNHx,Hx,l HCE6!(yH=,eEnE܋E܉E}\uc(yH=c,6E?EEE}nu E +}ru E }tu E }fuE (yH=,ӝ'E 'E}t;P*ulDK!P*KMH_w,HXw,EBE/}t\}_D@O*uLHv,Hv,l荝CE/S}Au}_u>}C@RO*l%E}EEE!Eȃ}[EHŸD/* E}N**/E}`N*k::E8-I-¾>E +J+hEEC=L¾H<;EFD=¾G>E:B=E|>=!¾A=ER<;?E9&@&E |?|}EESM*}JHt,EE؋EH8[UHSH8H}й@JHTt,EEHcHHHHH1iH}H t,EHcHHHH1iAEHcHHHHH1iHt*Hs,EHcHHHHH1i HCEHcHHHH1iE*EEHcHHHHH1iH!Hbs,H}wCCtHHs,f@E/H}о,Du+fu+ɺ(BHVR+H2(HHŠkH@HEEHEH@0H@H0H}詙g(HHŠkHPEHHHH0H}t2(HHŠkH@HEHEH@0H@H0(HHŠkHPEHHHH8HEH@0H@H5¹(8D (HHŠkHH0`DEHq,HEH@0fHq,HEH@0H@H8HCE25HEH@8HEH}%:(HHŠkHPEHHHHHE0HEH<.LH}^HE<.4HEHuH}荗HEH}uȸ(HHŠkHPEHHHHH?P+ExHEH@8HEEH}Hp,H}HCH}(wt E33H}莗t E4H}Et E5E2EH8[UHH  O+tO+EN+{EN+=u1}t(}tEN+N+EN+}us}$tj}9ta}7tX}tO}tF}t=}}t7} t.}t%}tE@N+:N+E}uMHv+Ht H,M+M+}t M+=uM+EM+EM+qG*Dlu'G*{G*uG*HH ƀkbDl訕uRfM+ƒXM+t.G*N+!kG*HH H<lDlCuAM+L+L+kF*HH H<l蓔}/uM6n,<'uBHm,PDl,kmF*HH H<l=S}/uBHm,PDlk"F*HH H<lE-E}3EHDDlDlΓDl赓|Dl蜓cDl胓JDlj1DlQDl8DlDlDlDlԒDl軒Dl袒lDl茒VDlv@Dl`*DlJDl4kD*HH H<lEEEÐUHH H}HuH}uH}u E5H}tH}u EHEH0HEH8EEUHH}E%HEEHEeE%tMHEuЋE%UHH0H}H}EEHH lHE]HEH8Huau=H5~+HEHxpt%H5,HEHxht HEHEHEH@xHEH}uH.+HtlEHH lHERHEH8Huސu2HEH@pHu%H5N,HEHxhqt HEHEHEH@xHEH}u=HEH}讏Hx=HHEHHEH8HukHE@J+HEPHd+HEHPpH,HEHPhA*EHH lHEHPxEHcHEH l+=HEHUHEHH +HuHEH+H+H+H+HUHPHEH+HEHEHEUHH}HuHEH@HEH}HEE܁}/tc}2HEH@@ fHE@ƒHEPHEH@@ fHE@ƒHEPnHE@t HE@tHE@ƒHEPHE@xHE@=~*HE@ƒHEPHE@ƒ HEPUHHH}H +HUK=H+UHHH}udH%(HE1EHv+HEHEH@0HEHEHPHEH@pH9HEH@0HEEE;EHEH@0Eȁ}/u3HEH@0@Eȃ}t }tM}x }~\MV}2u,HEH@0H@@ Eȃ}t1M}t'M!M HEH@8HEEH}QHEH@8HEH}EătEăLn, Eău HDžxhD HDžxlDH}HxnjHE@ H}8 H}ʋE EHD}~mEHD< tރ}HuH}\toH}HEHHEHEH@pHtHEH@pHHEHEqDHUHMHuxD#HEHHuпD HEdH3%(tŋUHH0H}HuUHEHEE|HEH@0Ht_HEH@0H@HtNHEH@0H@@ f@u8H}tHEH@HEHEHEH@0HxM܋UHun9HEH@8HEEH}yUHH0H}uHU؋ի(EE HEH@@ ftPHEH@@ u:HE@(HEH@H;l,HEH@H0D6Ee(HEHPEfB ;*t:HEHPHEH@@B}@uHEHxUFu8}ucHEH@@xHEH@@~HEH@H0D,7HEH@@uDHEH@@D6$HEH@@~HEH@H0D5H}HEH@H8+DuJHEHPHEH@@B܏+ӏ+}HEH@H08Dh6rHEH@H8[D蠇uHEHPHEH@@B8HEH@H8bDfuHEHPHEH@@@B}@u"HEHP+++BfHEH@@HEH@H@PHtFHEH@H@Pf@u1HEH@Hi,HE@'(HEH@H0pDf5HEH@@:HE@(HEH@Hi,HEH@H0D84Eɨ(HEH@8HEEH}UHHH}uHE@0 UHEP0}t }EHUHHHDHtpH+H0EHUHHHDH8qtEH+HEHUHHHDH0HʿDYHEH0DV3EH C+HUHHHLUHH H}uHEHEwHEH@0HEVHEH@@ f=uHEH@HxXu"HEH@@ f@uHEHxuHEH@8HEH}uHEH@8HEH}uUHH@H}؉ufٌ+g,tK}uEHEH@HtHEH@HHEHEDHE؋pHUȿD$H%+Hu+HE؋@(HEH@H\g,GD2HEHE@2HEHUEԉBHEHP0HEHP0H~+HEHPH~+HEHP8HEH~+HEH@0HEHEH@@ f=uHEH@HxXu3gHEH@@ f@uHEHxu5C٥(EHE@ɥ(HEH@Hrf,HEH@H0aD 1E(HEH@8HEH}UHSHH}p(EH}tHE@Y(HEH@Hf,H}+Hu HEH}+2H}+HE HEH@8HEHEH@8HuHUHEHB8Hp}+HEEHEH@0Ht3HEH@0H@Ht"HEH@0f=2uHEH@0H@0Ht{D0HEH@0H@@ f=tuHEH@0HPHEH@0H@@ȀBHEH@0H@f@ HEH@0HX/W2HCPHEH@0H@HPPEB1HEH@0H@H@P@;EtHEH@0H@H0DC/HEH@8HEEH}E(}~D/H[UHH H}EH{+HE4HEH@0H@H0H}蚂uEEEHEH@8HEH}uEEUHH H}uEE} } 4}t{}}N}}5}}}@ty}}}$H} DrH}DZH}DBH}D*H}DH} DwH} DbH} DЀMH}  D軀8H}# D覀E#H}* D芀EEEUHHldH%(HE1lHpt"Hp1 D~Džh DžhhHUdH3%(t)UHH H}HE@ fr i~HEH@hHtHEH@hH04 D~HEH01 D}HE@ HE@<uHEp8 D}HE@ f@u8HEH@PHtHEH@P@EEu= Dz}HHE@ f=uHEH@`H0A DP}HEHxP-ƿ= D0}HEH@hHtE D}8HEH@pHuW D|HEH@pH0c D|HE@yHE@޿i D|y D|HE@ f@HEH@PHHEH@PH@8HEEEHEH@8HEH}uu D?|HEH@PH@8HE[HEf=uHEH@H0 D|HE HEH@8Ht |HEH@8HEH}u |UHHHv+HEHEH8GHEH@HEH}uUHHH} Dn{HEH@pHtHEH@pH0 DG{HEH@hHtHEH@hH04 D {HEH01 D {HE@ HE@<uHEp8 Dz {UHH0H}E],ucHEH@HHE.HE@ruMHE@suMHEH@HEH}u˃}HE@yH}EEE3EHEH@HHE*HEPEHH@7i9uEHEH@HEH}uσ}EEHHHH7i!DyHEH@HHEHEPEHH@7i9uzHEHH01 D{yHEH@HtHEH@H0!DTyHE@tHEp!D3ym}~!DyHEH@HEH}UE}}u HEТ!DHEqDH}xUHHdH%(HE1Hs+HhHhHH@hHHhH@ \\tn\ \t\\tS\tJj\@t\t0\ t'G[,9HhH85%HhH@t[,uGHhHH@pHu4,+fu(Ǡ(tHhHHhH@BZ, +fHZ,H0!D_wHhH@ HpHhHH@pHt"HhHH@pH0!Dw!DvHhHHHp!DvHhH@HhHhHEdH3%(twxÐUHH0H}HEH@HEHEH8"D[xu"Dv$EjHEH8/"D+xu-H|+HtH|+@ EEEE(HEH85"DwuAH|+Ht#H|+H@HtH|+H@@ EEMMHEH88"Dwu6HP|+Hu EH8|+P n|+)MHEH8="DHwu.|+,|+)M]HEH@pHtHE@ ftH}rE5HE@ fuHEH8RHEHUHEHBH}E܋EUHHH}uHEH@H@pHt"HEH@@ ftuH}訹E;HEH@@ fuHEH@H8HHEHPuH}EEUHHH}HuH}HEf=2HEH0HEH@H8vHEH@H@pHu HEH@pHtAHEH@H@pHtsHEH@pHtfHEH@pH0HEH@H@pH8uuCHE@\(HEH@HW,HEH0H"D!HEf/HE@"HEHp0H}HEHp8H}UHSH(H}u܋(EHV,HEuH}u EHE@ fuHEH0i"D !HEf@ HEH@ HHE@HH<!HHEHP EsHE@ f@t7HEHpPH}-HEHP EHHHHEHxPb*U,u HEHP EHHHH}KEHE@;EEה(HEHU,EEH([UHH H}HEH@HEHEHx0EHE@ fuKHx+Ht?Hsx+H0H}fE}tHEH0"DqEEqHE@ f=uHuH}XELuH}t5HEHHEHP EHHH0HE@ EEEUHHp}uUdH%(HE1EfEE}t } t}@uEEu}u EfEf}t }u EEL}uEE8}u2}u"DsU )ЉE!ЉEEUE;Et6EEMEUH}A"D^qHu"DEEEHUdH3%(tqUHH H}uHEH@@ f=uHEHpMH}aWHEHx0EHEHxu7tyHEH@HP EHHHEHEH@PHEH@@ u0EHEH@HP EHHH‹EE;EtHEHPu+BUHH0H}uHUE,EH j+HE-HEH@H8Hupu EHEH@8HEH}ũ}E,HM"DpHi+HEHEH@H8Hu:pfv+HEHP0H}A#D#Dfov+HEPH}#DEpfJv+HEHP0H}A#D #D9f v+HUH}"#DoHEH@8HEH}6HM*#DoE{,UHSH8Hp+Hu7/(H¾2H}p+H>h+HEHEHHEHE@ fHEH@pHHEH@hHHE@ f=$HE@ fHE@ fHE@ fHE@ f=uHEH8jHE@ f=uYO,t2O,@u%HE؋P(s+9}O,s+9HEH0H}غdEHE@ f@uuH}غbO,t2 O,@u%HE؋Pr+9}N,r+9Hn+HEHBHn+HP0EBH=n+hEHEH02#DbkHE؋@ HE@tu7#D8k<#D)kHE@ f=H=H*ua >kdN,HE@,EN,uCN,uHEH@#D@mkHEHH#D@mkHE@ f=}`HE@uNR(HE؈P C(EgfffE)É]ԋEE)‰UԋEԃ (HE@Ћp+E6M,u}@mAMM,u@mN#DiHEH0@mT#Di5wp+Uh#Di#DiHEH02#DeiHE؋@ HE@tu7#D;i@m#D'iEHE؋@;E HEH@HEH}H8[UHSH8H}H} HEH@0HEHl+Hu7/H¾2jHk+HEHEHE@ f=uHEH0HUH}I`sEWHE@ f@uHUЋuH}2_0]K,t2PK,@u%HEPn+9}BK,n+9H5k+HEHBH&k+HP0EBHEHHEЋP n+)HEHH0#DgHE@ HE@tu7#Dqg<#DbgHE@ f=H=j+H=s*] jgJ,!HE@ ,qJ,uk3J,u1HEH0HEЋH HEHHI#D@mg/HEH0HEЋH HEHHI#D@mgHE@ f=H=i+lj[HE@uNI(HEP :(EgfffE)É]̋EE)‰ŰẼ(HE@Ћl+E-I,u}@m=DI,u@mN#DeHEHHEЋP HEHH0A@m#De5\l+Uh#Dje$DeHEHHEЋP HEHH0#D9eHE@ HE@tu7#De@m#DdEHE@;EHEH@xHEH}OH8[ÐUHH}Gh+ult l=e/h+tG H,u=G,u3G,u)g+uEk+~5g+1$DLdG,t8G,u ~G,t$}tu@$Dd ^$D*d}2dUHSHH HHdH%(HE1H5(HeDžLHHdHHǺl$D+eHH4ŀlHdf+9~H^dH=v%H w*!p$D[eYHHHHI$D3dHwctFHwct HbcH *$Ddt H(cHEdH3%(tDdHH [UHH0HHdH%(HE1H$DbHH$DbHHt HuaX&D4a&D*a&D`&Da&D`'D`('D`H'D`'D`'D`'D`(D`/(D`C(D`h(D`(D`(D`(D{`)Dq`@)Dg`x)D]`)DS`)DI`8*D?`Y*D5`x*D+`*D!`*D`*D `+D`0+D_X+D_+D_+D_+D_+D_(,D_UHH@}E1Ẽ}EHH-Dp()Љc(B, L(t HEJ,DHEM,DHuпX,D_e()Љ(-B, A(t HEJ,DHEM,DHuؿ,D^ ()Љ(A, (t HEJ,DHEM,DHu࿰,Dc^A,)Љ{A,}A, dA,t HEJ,DHEM,DHu,D ^`ka+)Љ^a+(A, t@Ka+t HEJ,DHEM,DHu-D] -D]-UHH HdH%(HE1_,Dž(H*H@,H*HR8,H{*H,HHHHA6Hň.DHHHHxr^l@,R@,Z@,K @,<?,-6@,?,`+_+ _+HHHHcHŀl?,_+_+ _+HHHHPHcHŀlHHHo_+ HpHHE_+ HN>,>,:;_++?,!_+ >,HHHHx\>,>,HHH>, HQ>,H>,E>,.>,zHHH[^+ HTHHHHx@\,,(HHHHDž(HHHHH(=,z=,h[HHHHHHHH%HHHHx{[Ll=,=,X<,<,D9=,5<,ZHHHHHHHH%HHHHxZ<,\+\+ \+HHHHcHŀlHHHHxZ%<,|!<, <,kp-DXU;,@;,D9<,3<,<,@ X;, \+ H ~HHH<- (t;,u -DEXH[+HH[+HHs[+Hl[+HHHfH_[+H8$DJXHK,HD,Hu#H8[+H0-DWH,H0HEH@8HEH}uEEHEH@HtHEH@HHEHEIDHuؿID EE\} L}xFEHHŠlHt4EHHŠl'+BEHH<ŠlUHuEEEUHH0H}HuEEHEH@8HEzHEHx0 }HEHPEHHH8EHEHP HE؋@ EEHHHEE;Et E;E);HEH@8HEEH}tHE؋@ ;EoEHE؋@;EFHE؋@EEHEHH EPHE؋@ EHHHHEHP HE؋@ EEHHH}u2HEHP(EHHHH HEHP(EHHHEHE؋@ ;ElmE;EPHE؋@ EUHH HdH%(HE1, t};to@t @u]H}ٝHpǝHpHMHHIJDgHJD$HEdH3%(tUHSHHH}HuHEЋPHEЋ@ ‰EEHEЋ@~ HEЋPHEЋ@9|,Ei+t EHEȋ@tHuH} EHEHH(HEЋ@ UUUÉHHH'$+HEH@8HEHEHx0zEHEHH UEHHHHEHPEHHH8uɫ,t3#+,9|#HEЋUuH}IAй JD#JD`HEHx0HEHPEHHH8)JDHEH@8HEEH}tHEЋ@ ;E+#+x+9|zEE)HEЋUH}IAй JD#JDEHEЋ@ ;EHEЋ@ ;E~5"+0JDH}t5"+XJDHEЋ@PHEЉPEEHH[UHSHXH}HuȉUEHEЋ@u EHEH@8HEEHEH@0f=/u1HEHP HEЋ@ EEHHHHEH@0@9uHHEH@0f= unHEHP HEЋ@ EEHHHHEH@0Hx0w9t7HEȋ@t HEȋ@tEHEЋ@9E3EHEH@8HEEH}tHEЋ@ ;Ef+t Ez+t?HEЋ@ ;E~5 !+JDH}t5 +JD +tHEH/ +HEH, +HEHP(EHHHEHEH@8HEE+t }+t_ +uuY ++9|e}tHEȋ@ HEJDHEJDHEHP HEЋ@ EEHHH0HEЋUH}IAйJDHU }?H}HEH@0f=/tpHEH@0f= t_HEHP HEЋ@ EEHHH0HEHx0跣HEHx0HEHPEHHH8JDHEȋ@EEHEHP HEЋ@ EEHHH4HEHH EPHEЋ@ EHHH}u2HEHP(EHHH HEHP(EHHHHEHEЋ@;EhHEH@8HEEH}tHEЋ@ ;E+t }+tzO+upI++9|`EEL}tHEȋ@ HEJDHEJDHEЋUH}IAйJDHU EHEЋ@ ;E=+u.}t(+u+ +9|5+}|}tHEȋ@HEЋ@PHEЉPEEHX[UHSH8H}HuH"+HEEHEH@8HEHEHP EHHHHEHx0(sHEHPEHHH8HEHx0 HEHPEHHH8JDHEH@8HEEH}tHEЋ@ ;EbHE@OuHE@Ea+tHE@EHEHP(F++-++9zHEH@8HEH+HEHEH+E?HEHx0qHEЋUH}IAй JDJDHEH@8HEEH}t HEЋ@ ;EEE)HEЋUH}IAй JDJDQEHEЋ@ ;EHEЋ@ ;E~5S+KDdH}t55+0KDFHEH++RHn+Ht Hj+HuZKDHG+H@8HEEHEH@0f=2uHEH@0H@H8oKDtHEHx0pEE+t)H+H=+EuIAJDJD*HEH@8HEEH}tHEЋ@ ;E\y+tCEE/H{+H=l+UIAйJDJDEHEЋ@ ;Eŋ5+u5+=+H+H+EEH8[UHH0HdH%(HE1HH@@ f@uHH@H0@m&HH@@ f=2u%HH@H8}H0@mHH@@ f=HH@HHH@pHt1HUHHuqKD@m0HHH0JDHID HHx0HHH@muKD@mHH@0H@0Ht=HH@0Hx0mH¾wKD;H@mZHEdH3%(tUHH@H}HuU܉MLEЃ}uIB,H}H}|KDt HEKDHEKDHu@mKD@mHE<[uKD@mHEHPEHHH=}HEЋ@ ;EupO+t AR,E4H+HtH+P +)MEẺEHE<[uKD@m}@mUHH@H}HuU܉MLEЋ;(tcKDdEuKDIE+ +)+);Eɿ Z<;(}HEKDH+Ht9EKDEHf+P +);EпKDz@,H}H}|KDt E?E!U̾@mKDK ,HE<[u [jHEHPEHHH=H=9)uHEЋ@ ;EuHE<[u ] UHH }ټHEHUEH+HEHPHEH+UH}H+HE HE;Eu EHEH@HEH}uEEUHHHhdHXHPDLL@dH%(HE1HhHx0i_c +tg+u.H@LdHXHhI H@LdHXHhI++t8HX<[t*HhHx0$iHp¾KD` (HhHx0hHp¾KD6 HX|KD0 uHpKD; &HpKD( HXHp Lu:8QHhH@HHhpHpKDb , H@HPLHHH=H=_)dH@@ ;Lu|y+t#KD %+ug  [HhHx0gHP¿KD <,Hh@mKD H=) HEdH3%(t; UHH0dH%(HE1DžHR+H;unHH@0H@H8 H=vHH@0H@H0KDaHH@0H@H0H H@m ]HH@8HHt THLD H@m HEdH3%(t UHHH}uU;,u}H}@m@ UHH0H}uHUHEH@ HH +HEHEHEHP EHHH9+~"+tHEP]+9]HE@NHELDMH}t*HE؋P  +)HEHH0LDHE@ HE@tHEH0ULDHEH0%LDE[Ef}~ ,HEHPEHHH=HEHP HE@ EEHHH0H=)EHE@ ;E]xEHE@;E] ZHEH@0HEH}7UHH0H}HuUE}HEH@HHEH@@ f@HEHxL裶H}tHEf=/u+LDqH}t@HEH@Ht3HEH@@ f@u!HEHxV>H}HEf= HEf= HEf=+HEf=-HEf=,HEf=.HEH@HtEHEH@@ f@u3}u@LD腴HEHxVvHEf=2t HEf.uEHEHp0UH}7HEHp8H}!UHH H}HF,HE3HEH8HuuHE@PHEPrHEH@HEH}uƿHEH}HxгHHEHHE@HEH8HuvHgF,HEHPHEHTF,UHH H}HEH7F,HEnHEH8HuuFHE@PHEPHE@uEH}tHEHPHEHP,HEH@HE,HEHEHEH@HEH}uUHH H}HuHE,HE0HEH8HuuHu`LD衱HEH@HEH}uUHHPHHHdH%(HE1HH@%(Hf=27HH@H0HqHH@H0HWHH@0HHLD2HHHHID-HKDHHx0HHHKDHHhHHHHH@8HHHx8HHmHf=/u@HLD3HPH}оLDHuHtHf.uBHLDHLDHHx0HH"HLDHLDHEdH3%(tUHH HdH%(HE1HB,HIDhHIDRHHHHEdH3%(tTUHH H}HEH@HtxHEH@HHthHEH@HHEH}QHuH}LD t!H}0Hu H}LDuHuLDH}ÐUHH } HEH5L+H}HEHEH4+}t +UH++(UH+(UHH@H}HuHEHEH}ttHEHHthHEHf=uXHEH8DHEH}tHEPG+(9}+HEH@!(HEHH@HQ+EpHEH@0HE3HEHHpHEHH8@u E;HEH@HEH}uHEH@HHEH}tHEH;EEEUHHH}HuH}tDH}t=HEP HE@ 9t+HE@ (HEH@H+LDUHH}HEf=tHHEf=t;HEfcu7HEH@0Ht*HEH@0f=/uHEH@0@u EEEUHH0H}HEEHEHHEHEHHEH}OH}HE}HEf=HEf=H+ t!HEH@HHEpLDHEHH;EtPHEH@H;EtBHEH@H;Et4HE@ ƒHEP HEHPHHEHPHHEHEEHEHEHEH@HHEH}UHH H}H}t_HX*Ht&H)HtH5)H9*H8 t-HEH@(HEHEH8gHEH@HEH}uUHH0}Hd+HHE}(HEH8nHEH}HEHHEHEHHHtHEHH@EEHEHHHtHEHHH@HHEHEMDHMЋUHuMD8}yEHODHMD7pMD-MD#IMDMDMDNDMD NDMDHNDMDpNDMDhND~MDJND`MD1NDGpND;OD1 OD'OD*OD6OD GOD ODYODgOD sOD}u'HEHpHEH8uODzH*H@H**HEPHEHPHEHPHEH@HuOD/HEUHH@H}Huй ٩HEHE؋PHEPHEHPHEHP=+f3+HEf=uHEH@(HE.H} HǾHEHEf=u!HEHP(HEHBHEH@(HE_HEf:!HEH@0f=t&HEH@0f=tHEH@0f=HEH@0EHEH@0HP(HEHBHEH@0HP(HEHP(H} u脨HEHǾHHEHP(HE؋PHEPHEHPHEHPHUH}ع:)HEHE؋PHEPHEHPHEHPHEHEA2H} HHuHEHUHEHB(HEHEHEUHH H}HuHEHUHEHHUHEHBHEUHH H}H}tHHEf=t HEf=uH}jHEHEf= uH}HEgPfHEHUHEH*HEP B**HEPBv*H_*HEHP@HEHL*HEHEHEUHHH}H}u EYHEE}r|}s~ E-+w E*HEHx0t EHEHx8EEUHHH*HE9HEHHHEH@HH HEH-HEH@HHE HEH@HHEH}tHEHf.tHEHH@(HH@H@HHuHEHH@(HHPHEHBHHEHH@(HH@H@HHf=tHEH@H0HEH8u#HE@ UHEPHEH@@ EHEH@ HEH}uEEUHH`dH%(HE1HE*ƒ*H}RDH}VHEHUHEHH*HEHPHEH*HEdH3%(tUHH*HuRD H~*HUHH H}uHEHpHEH8UHEH@HEHEHE}|A}~ } t-HEHH@(H8u;HEH@0H8uv&HE@ ƒHEP HE@ ƒHEP UHHPH}HuЉUH+HE(EHEHEHEP E ЉƒHEP HEHE}}}t 5}th} + }t HE3RDHE:RDHEHH@HHEHpHMHRDc]+ u }uJHEHH@HHEHpRD"}t RD2 :RD&gHEHfHEHH@(HEHEHHpHEHH8U-}t'HEHH@HHEHpRDHEH@0HE)HEHHpHEHH8U%HEH@HEH}uHEH;EtHEH@HHE&HEH+E(UHHH*HEYHEH@Ht@HEHH<:t/HEH@HHEH@P HEHH0RDHEH@ HEH}uÐUHH@H}uU@轑HEHEHHEHHE@ HEP >*<*)G*HEP A*|+u o+ tDHE@ EHEHHtHEHHHEHESDUHuп SDHEH@Hu2HEHHtHEHHHEHESDHuؿ$SD詐HEH@H@ HEH@H8HHEHPHEHPHEHP HEH@H@Ht!HEH@HPHEH@H@@ @B H*HEHP8HEHPHEHP(HUEB}t H}M *E*HEH*UHHPH}HuHUȉMLE0HEHUHEHHUHEHBHUHEHBHUHEHB m*HEfP AZ*}t!}tH )(HSDEĉHEP"H*HEHP(HEH*HEHEE1HEH@0HEEHEH@8HEH}uHEH@8HEH}uȋ*E9M‰*H*UHH}Ht*HE/HEHH;EuHEHPBEB%HEH@(HEH}uʋ*E*EUHH*HEHEH@HEHEH@HEdHEH@0HECHEf,tHEHPEBmHEH@0HPEBmHEH@8HEH}uHEH@8HEH}uHEH@(HEH}XUHHH}+ (+uZH*HHH*P >*)¾qSD@mH*P *)Ǿ@mOH*HHH*P *)HʿwSD+L+ ++H}tHuSD '#H(*HHH*P I*)HʿSDJH*@~H*pSD" XUHH0H}HEH@HEHEH@0HEHE؋@ HE@H*HEHEHH0HEH8x*v*)=~SDyHE؋pH}H= *HUHuH=*H*P *)*‰UHEH@(HEH}>EEUHH@}HuHEH@HEEH*HEHEHH0HEH8HEH@0Ht$HEH@0@8'HEH@0H@Hݾ+HEH@HE1HEH@0HEEHEH@8HEH}uHEH@8HEH}uȋE;Et=Uu̿SDTDTDHEH@(HEH}&UHH0}HEH*HEVHE@ ;Eu}x.HuhTDHEP uTD HE@ EHEH@8HEH}uEUHH }+ƻ+t$+u?+u TDz+"**9j+E**)*)*4TD/+&+hjE++ ++ +Hk*H\*H=S*HG*H@8H<*H5*Hu֋E++u ?*t HETDHETD"*3*)+*4HUTD*+t Nr}t >rUHH }U %)HƀlEEEEHlEE~*|*);E׋k*i*);ElEEEUHH0H}HEHHHEHE܁}!}}}.}t} tE*HEH8HEHEH0HEH8XHEHEnHEH@0HH8IHEUHEHH@(HHPHEH@HHBHHEHH@(HH8HEHEHxHHEHEHEHEUHSHHdH%(HE1Dž*P*9|H*H*HDž(n+t*"+9**)‹*9~ UD觃 ‹ *||UH&*@)H*HH*H@8H*H*HuHDžH*H*H*P)Ѕy?DžDž*"UD H*H*DžHq*@ ={H\*H HcfEH?*H@Ht$H/*H@(HtFH*Hx(Z0u2H *H *H9H*@ HfDŽEH*H*HxHCH*H@H@0H(H*H@HHH*Hx=t  $+u"tѵ+ u $5UDjH *HxtBUD=QUD.H*H@H0H=Q);_H*H@H@8HtTUD^UD{HDžH[*H@H@0HDžuHHH8HH<HHf=uK1*uHH HDžHHH;t  J+ut+ u }5UDH4*HxEtBUDfQUDWHH0H=~)h]^UDRHH@HH}H)ы)Ѓ9|B5UDH_*Hxp`UD;5UDH"*Hx3hUDH*H@8H*H*HpH*H*)Ѓ-*u#*DžDžd+tp~UDC)ȃUDipUD+u=)ȃu&UDUH=u)HUDDžCHHHH%tHs+H*H;EHE@ t + tgHp*HxVDHl*HuH@*H@HU*HN*H0H=|)V^UD+t[+t H=*H`HE@ u+t [H*H9EuH*H@@ "tH}HEEHUHEHBHz*H*I+u *lHD*H@HH0*H@@ j}tH*H9ESH*H@@ iE]* *HEH@Ht!HEH@@ tVD vH*H@HpH*H@HHYHs*H@Hf@>HX*H w*u*)É؃9H1*H2*H9tH}tH*HP8HEHP8H*H@8H***&*H*@)ȉ*V+t H=>z)VDFH*H*l+u ***9lHS*H@8HtHC*H@8HE H:*H]HEH#*mH*x ftZ8*&*(*+9|2H*HEH*H=Yy) WDaHEH*H*Ht3H*Ht'H=*HEEH~*HH*H([UHSHHHI*HEH^*HE؋+EϨ+t EHEH@@ tWDNt$*¨+(‹*E}UH*H*9H*@)EH*H@8H*H*HuH*H*H{*PE)Ѕy**)ЉEHR*H;EHA*H@(HtH1*Hx(l!H*HxkHEH}f+tHEH**0g+ uZ+HEHEH*HEHEH*H}uH*H@HEH}ؾ VDHEH0H=v)P^UDHEHEH=*HEHEH.*HG*HuH*H@H0*H=)* VDHH *H0H=ov)YP^UDC*H*H}HCE+E_H*H@8H*H*HuH~*Ho*m}*HEHL*E+EEHH[UHH H}HuHEH@0HE'HEH0HEH89HEH@xHEH}uҿYqHEHEHHEHHEP HEfP HEPHEPHEPHEPHEPHEPHEHPPHEHPP*HEPHEHHEHPpHE@ f=HEH@ HtjHE@HH<pHHEHP E2HEHP EHHH HEHP EHHHEHE@;E^H}MNHEH@(HtHEH00WDpHEHPXHEHPXHEHP`HEHP`HEHPhHEHPhHEHP0HEHPxHUHEHB0UHH0H}HK*HEHEH<*H*HEHEHHEH}HEH@pHHEHH0HEH@pH8#HE@HE@ ftbHE@ ftTHE@ f=tFHE@ ft8HE@ f@t*HE@ ftHE@ f tHE@ f=uH}HuHEH0MWDmHEH@HEH}HEH#*UHHHHH@H8H0dH%(HE1H*HXH8uH0HH0pWDnH@H@@H@H@@tH@H@H0WDmH8Hx0lH8Hx0诨hHHHD*H@菨dh;dtuh@t d@ucdH}=hHp=H0HHHpHMHpIWDXHpWDlH@f2H@HpHHZlH@HHXHl*HEdH3%(t耿UHH@H}HuHUH}tHEȋ@.'HEH@Hנ+HEH@HEHEHEHEH@0HEnHEf,tHMHUHuH}HEHp0HMHUH}HEH@8HEH}tHEH@8HEHEHEHEHEH}uHEH@8HEH}fUHH H}HW*Hu HEiHA*H@0HE#HEH0HEH8\tHEH@xHEH}uH}uH=*HuH*H@0HEHEHEHEUHHH}uH}u ESHE@;E~}y:HEHHEH0UWDHEH0XDiEEEUHH0H}HEH@HEHEHx0EH}HEH}t%HE@ f=uHuH}غELuH}t5HEHHEHP EHHH0HE@ IEEEUHSH(H}uHEHx)HEHEHx0EuH}tcHE@ f=uMHuH}O>HEHP EHHHHEPHE@ uVIK*HEPH([UHH}H*H}t5*XD"XD*ftH*@ u$XD%H*P *)ƿ'XDùHd*HH0+XD觹UHHH}˜+ u +tDHEHx4 裹+tK+t H}FPUHH0H}uEH}tHEHHt HEH@E*ftQH*HtEH*@ u7 ';Et,H}t%=+tu2XD诸E'}FH}HE@ EHEHHtHEHH@HHEHECXDHEHHtHEH@EEMHU؋uEXD&+u0HE@ @uH}Ht\XDUHH H}HE@y'HEH@H"+HEH@@ ftEHEH@@ f=t3HEH@@ oXD職HEH@H0XDhfHE@ xHEH@H0XDHfHEH@0HpHEHxE}uHEH@H0XD fEUHH@H}EHEȋ@'HEH@H<+HEH@0H@0HuHEH@0H@H8E*HEH@0Hx0E*Et*E}y EK@*>*)ȉEH *HEQmE;E5HEH@0H@H0HEHH8t>UE)щHEH@0H@H0XDHEHH0 YDcHEH@H8(YD謷u,HEH@HtHEH@@ E}EqH=*HEHEH.*HEH@0HEHEHP8HEHP0HEH@HEHEHxHHEHPH}>EHUHEHBHUHEHB0HEH*EEHEH@8HEH}UE)щHEH@0H@H0+YD˴HEH@H0?YDbLYD̴v*t*)ȃEH=*HENHEH@0H@H0HEHH8IuHEHHuWYDIHEH@8HEmH}uEEÐUH}EHK'UHSH ='EyEAHEHHHH?HH)H]HiEHH)HUHiuAH 'EyEAHEHHHH?HH)HHiHH'H'HH'HH'H'[UHH H}H}u HE5HEHxHEH}t HEHEHEHH8 HEHEUHHHdH%(HE1HtHHHuHDžH HHf=r*tHDžH HH<*HH8uHH@ HVHHH0HH8詳HHHJ HHf= u"HH@0HH8HH HH@0HHDžHDžDžDž+tv+uu*uk~*uaH@ uP7*+9|@`YD>oYDJ**)Ѓ~ qYD-HH@0HDžc+l+^˸*P*BH@ -r*ԓ+9HHHH+u'+ uHHH8-HHHHf=uK*uHHHH@HHP HDžPHPHnYDįHHH8uYD蟯HHHH0H=b)< 諯HH@HH_uHtYD#+b*Q+9N*@H@ +*+4+tYD裮YD茮H=a)HYDJ蕯HHHH%tHů7 t2 t&!t :uHH**t?HtHH@HH HDžHHH@HH8tHH@HH HDžHHHHHHUdH3%(ttUHH0H}H}t HEHHEHEHEHEH}t&HEfruHE@ H}u EHEH*H}EEUHH H}F*t EHEH@8- E}$w*HcMHHHH!Ht EHEHx8認EHEHx0蚍Nju2ZD迄HEHx8kHEHx0.EEUHH H *HE,HEHxHt EHEH@8HEH}uEEUHSH8H}H}}HE@'HEH@H@+HE!EЁ}+EHZDHE@E/HEHx0EHEHx0iډUHEHx0PщMHEHx07HEHx8(ډEHEHx0HEHx8ЉUHEHx0HEHx8)M`HEHx0HEHx8É]:HEHx0HEHx8Eĉډ}ĉU HEHx0`HEHx8Q9EHEHx04HEHx8%9EHEHx0HEHx8!‰UHEHx0HEHx81MaHEHx0HEHx8 ‰U9HEHx0HEHx89E HEHx0dHEHx8U9EHEHx08HEHx8)9EHEHx0 HEHx89EHEHx0uHEHx8t EEM؉MLHEHx0tHEHx8t EEE܉EHEHx0fHEHx8WUHEHx0H +{G#H +{G)H*HE$HE@ +H}+HEH@(HEH}uՋ%p+z+ߔ*ft6H +({G苎H l+{GpEPH=C+ujo+u!*PH=+jْ*H=+jH=+jgUHH H}Ho*HE*HEHHHE@ H}jHEH@(HEH}uUHH n+E}tH}t}<)<)P5<)H=6+ jH= +j<)H=+ j*x<)pH=+ jc:H=+jF*PH=+ j'H=*HE#HE@ HEH8\HEH@(HEH}u֋m+E}tH}t};);)P5;)H=+j;)H=+j}*r;)pH=+j]H +{Gϋ=;)H=+{GË_*H=+jH=n+jl+ua*u S*M*P5D*H=5+ j1*P5(*H=+ jɏ*P*pH=+@jkH +|G݊H=+ ;i5H=+TiH=+%jH=e+ li*H=D+jH .+#|G:H +'|GH +-|GoD~EH +A|G։T|GH +F謉*PH=|+jH f+0`|GrH K+|GWUHH=*+ jUHHHHDdH%(HE1'lH*j+H`a8)9Du?j+3D8)9Dt"j+H*HXSDžhhHHHH}jHcЋhHHH}jHXHH8vHHH0HXH@H8HXH@p hHHH}jH=+DA|GhHHHH}j**hHHHH}j**HXH@@ t+hHHH}jHp|GkOhHXH@@ hHHH}jHp|GHXH@H@k'HXH@HH@H h+Hh+HtHg+HH8 HDž8}G5"'HpH8}G]hhHHHH}jHXH@ HXHXHv*HXnHX@tNHHH0HXHH@pH8跅u*HXH@H H=+D:}GHXH@ HXHXul)'H`Hf+HEdH3%(t/UHH@H}uUHMEmEEYEHHHELUMu}LUED$E$AAȉLL׸/Hu 豃EE;E|EEHHHEHHzUHH H}R}G蛂H}t[HEH@pHtHEH@pH@PHE HEH@PHEHEHEH}t!HEH@HHEpb}G9UHHHHH@dH%(HE1H@HH@ ft&HH@ ftHH@ f JHH@.DžhH`*H`AH`HHHtH`HH0H@LtH`H@(H`H`uH`H`H@HXHXH@0HPaHPH@Ht8HHH0HPH@H8ƂuhHHcKHPH@8HPhHPuHXH@8HXHXaHH@c+ HH@ HpHpCllHƄpl~llHp< tHH5HHH@pHtH@p}G}}GHHHHHHHp}GHH@ fHH@b+ HH@ HpHp0llHƄpllHp< tHH+HHH@pHtH@p}G~}}G~HHHHHHHp}G~HEdH3%(ta*}E)щHE@9}&a*}E)щʋa*`*HEP`*`*HE@uZHE@uNHE@uH+H}+H!+HHH<Šj;H>H_+HX+H!+HHH<Šj;H>H"+H+Htb!+HH H<Šj;HP>HQF*HJF*Ht1W!+HH H<Šj;H>H+H+Hu;H=H=+H ~+XG>5 +t6H ~++H ~+=H>H ~+=H>H h~+,=Hd>H M~+<=HI>H 2~+XG.>H ~+L=H>H }+\=H=H }+XG=H }+XG=H }+l=H=H }+{=H=H u}+XGq=H Z}+ =HV=H ?}+=H;=H $}+XG =H }+)=H=H |+=HHHEHH(HUH}AOY++t>H3:H>H):H "|+r>HHH;H={+>H;H {+ >H};H f{+$>Hb;H K{+?HG;H 0{+?H,;H {+ "?H;H z+-?H:H z+G?H:H z+ V?H:H z+ d?H:H z+#x?H:H sz+G?Ho:H Xz+r>HT:H =z+#>H9:H "z+XG:P+tF+H=y+?H:+t+H=y+?H9H+tH y+?H9+t+H=y+?H9?*t?*H=`y+?Hq9|?*ft p?*H=4y+>HE9Z?*ft N?*H=y+?H9+tH x+@H8 ?*ft >*H=x+%@H8H x+<@H8(ft (H=px+N@H8>*ftH Nx+d@HJ8u>*ft i>*H=x+{@H.8K>*ft ?>*H=w+@H8>*ft >*H=w+@H7=*ft =*H=w+@H7=*fu$=*fu=*fu =*ftQH Sw+@HO7H 8w+@H47H w+XG7<=*ft 0=*H=v+AH6]'tH v+AH6H v+'(AH6H v+&PAH6H {v+wAHw6H `v+(AH\6H Ev+?HA6H *v+XG&6H v+&AH 6H u+AH5H u+AH5H u+?H5H u+XG5H u+#BH5;*fuH au+4BH]5 :*H=@u+FBHQ5H *u+XBH&5H u+XG 5H4(HH=$(](H t+%xBH4<(H=t+FBH4 (H=t+BH4H t+XG{4H(HtwH=('((H=@t+BHQ4(H=$t+BH54HV(Ho+&HFHB/H #o+oFH'/H o+FH /3*PH=n+FH.G+ulH #5*FH.H 5*6FH.H 4*%GH.H 4*.GHv.H 4*7GH[.H 4**PGH@.H=4*GH:.H k4*XG.H P4*GH-?H m+ GH-H m+EH-H m+XG-H m+!GH-H dm+GHh-H Im+-HHM-H .m+oFH2-H s3*7GH-H X3**PGH,H==3*HHH,H '3*XG,H 3*uHH,H 2*&HH,H 2*-HHz,H 2* HH_,H 2*(HHD, +tH z2*IH,H _2*b:H,H D2*0IH+B +uH 2*OIH+6H 2*IH+H 1*hIH+H 1*b:Ho+( +uH #k+IH?+H k+IH$+H j+%IH +H j++IH*Hw/*HEH}HEH@(HEH}u +H j+  JH*H j+JH*H ij+,JHe*H.*HE8HE@ HE@ H=+j+=JH<*HEH@(HEH}uH j+UJH)H i+jJH)H i+nJH)H i+JH)H=i+_ +t %'u4HEHpHEHH@HH=)+UAWUH%H}UHH0H}HuHEH@8HEHEH@8HE+HEHHEHH9u&HEH@HEHEH@HEH}tH}uH}u H} HEHf=HEHf.HEH@0H@HHEHHtHEH@EEHEHHtHEHH@HHEHE[HUHuؿ [HI[HZ[Hf[Hn[H[H[HZ[Hf[H[H[H[HzUHH@H}؉uԉUHEHHEHE@ HE@ ƒHEP HEH@t H}wVHEHf= uHEH@0H8UЋu|6HEH@0HHEH &+H=&+[HHE@ HEPH=&+UHHEP HEH0H=u&+qHE@ %tHE@ ƒHEP HE@ H=4&+EЋMAUHDH5&+  'u.HEHHHEHH@HH=%+UHHEH@0HEHEHHx +THEHH8&HEHEH@8Ht HuH}HE@ EHEHfcHEHH@0f=/HEHH@0@HEH@8HuzH #%+[H'E"* tRHEHH@HtHEHH@HHEHEȫGHEHpHUȿ\HEHEH@HtH $+@\HH x$+O\H|HE@ HEPH=J$+EAVH]HEP HEH0H= $+/oHE@ %tHEHHHEHH@ B HEHH@ H=#+EЋMAUHH5#+ ^ 'u.HEHHHEHH@HH=}#+UH}tH a#+XGeHEH@HEH}tHEH@0HEHEH8UЋuHEH@HEH}uPHEHf=t HEHf=tHEHf=uUЋuH}!UЋuH}HEH@H;EtHEH@HHEH}>UHH0H}HEHHEHEHHHEHf=HEH86HEHEH0HEH8HE@ t4HE@ u&HE@ ƒHEP HE@ ƒHEP HE@ tcHE@ tUHE@ ƒHEP HE@ ƒHEP -HEH@0HEHEH8HEH@HEH}uHEH@H;EtHEH@HHEH}UHH H}HEHHEHE@ ƒHEP HEHf=t HEHf=tHEHf=uHEHH@(H8HEH@0HEHEH8tHEH@HEH}uHEH@H;EtHEH@HHEH}XUHH0H}H}u HEHE8)* ƒ))*t^\HHEHE}t }t9mHEH8HEHEH0HEH8cH}cHE>HEH@HHt)HE@ HEHxHH-HEHEHEHEHEHEUHHH}H}u HEHE9HEH@&HEHH@H*&(*H}HEHEUHH0H}HuHEHHEHEH;Eu EHE@ %u]HE@ €HEP HEH@0HE5HEHHtHEH8Hu}t E1HEH@HEH}uHEH@HHEH}fEEUHH0H}HEHHEHE@ %uHEH8t EHEHf=utHE@ ufH}oHEH}tRHuH}uAHE@ HEp HEHPH=+Aȉx\HEfHEH@0HE%HEH8t E?HEH@HEH}uHEH@H;EtHEH@HHEH}EEUHH H}EHEH@8HETHEH@0f=/t7HEH@0f= uHEH@0Hx0EHEHx0EHEH@8HEH}uEUHH H}HN)HE?HEHH0HEH@H8NuHE@#EHEH@(HEH}uEEUHH0H}H}u E)ft EHE!EЁ}+EHŨ\HHEH@(H8lEEHE@EH}wuHEH@@0t EEE؉EoH}HEHp8|H}Hu):Hu(HEHp0|H}Hu-HEHp8|H}Hu)/:Hu(HEHp0|H}NHu+HEHp8|H})Hu)_9Hu(LHEHp0|H}H}GfHHEHp8|H}Hu)p9Hu(HEHp0|H}Hu&HEHp8|H}jHu)9Hu(HEHp0|H}2Hu^hHEHp8|H} Hu)C8Hu(0HEHp0|H}Hu| HEHp8|H}Hu)Y8Hu(HEHp0|H}xHu<HEHp8|H}SHu)7Hu(vHEHp0|H}Hu>QHEHp8|H}Hu),7Hu(HEHp0|H}HMJfHJHEHp8|H}Hu)87Hu(HEHp0|H}WHMMfHHEHp8|H}(Hu)^6Hu(KHEHp0|H}HMPfH|HEHp8|H}Hu)j6Hu(HEHp0|H}HMSfHHEHp8|H}ZHu)6Hu(}HEHp0|H}"HMVfHHEHp8|H}Hu))5Hu(HEHp0|H}HMYfHGHEHp8|H}Hu)55Hu(HEHp0|H}THM\fHHEHp8|H}%Hu)[4Hu(HHEHp0|H}HM_fHyHEHp8|H}Hu)g4*uHM bfH,HMlfH(*45v&fH4HEH@HufHHH(Ht,H5(HEH@H8[uH5Ѐ(fHb|Hǀ(Ht,H5(HEH@H8#uH5(fH*|t*tgH|HEH@H8H}¾.gH0HEH@0HEE?HM9gHHEHp0|H}8HEH@8HEEH}uHu})9E~3HEH@H0@gHe{HMcgHEU)9E|Hu)u2HM ggHEHEHp0|H}Hu)32u*uHMtgH 2HM%gH1HM gHHEHp0|H}HM gH1)f*)fHMgHDHEHP0|H}AgHgHP1HEHP0|H}AGgH.1HM hHHEHP0|H}AhHgH0HEHP0|H}AhH#hH0HM .hHHEHP0|H}A9hH;hH0}0|)fs*p)fHMgHHEHP0|H}AgHgH+0HEHP0|H}AGgH 0HM hHHEHP0|H}AhHgH/HEHP0|H}AhH#hH/HM .hHgHEHP0|H}A9hHBhHs/X/W)fN*K)fHMgHHEHP0|H}AgHgH/HEHP0|H}AGgH.HM hHHEHP0|H}AhHgH.HEHP0|H}AhH#hH.HM .hHBHEHP0|H}AJhHPhHN.3.2)f)*&)fttHMgHHEHP0|H}AhHgH-HEHP0|H}AhH#hH-HM .hH}HEHP0|H}AXhH[hH-n-m)fd*a)fttHMgHHEHP0|H}AgHgH -HEHP0|H}AhHgH,HM .hHHEHP0|H}AehHPhH,,S+w(9HM&phHeHEHP0|H}AGhHq,HEH@8HEEHEH@0f=/tHEH@0f= HMhHHEHP0|H}A9gHG+HEHP0|H}AhH;hH+UH}hHHEH@0f=/uHEHp0|H}HEH@0Hp0|H}HEH@8HEEH}HMhHHM hHHEHP0H=+|A9hHhH +**tDէ*tHu1W*HEHP0|H}A9hHhH**)fHM.hHcHEHP0|H}AiH'iHo*HEHP0|H}A4iH>iHM*HM#G,)ft^HE@uRHEHP0|H}AKiHSiH)HM?hiHHM#GHM YHc)~])u HDžpiH HDžpiHH}HpiHOHEHP0|H}AiHiHK)#*tHM"iH&HMiHH}iH)ftHMiH)t,)u"*tHM jHyHMVHaHM)jHIHMDjH1HEHP0|H}AYjH]jH=(L)fB)HEH@8HEEwH}zjHHEHp0|H}HMjHHEH@8HtHMjHHEH@8HEEH}u)f)HM+RHBHM YH*HEHP0|H}AGjH6'HEPH}jHHEH@8HEE?HM9gHHEHp0|H}HEH@8HEEH}us(9E~n)f)HEHP0H=ps(|AjHjH&i)f_)[s(ujHGkHnEEHMcgHEs(9E|ًUH},kH)HMsWH)t"HEHP0|H}A2kH6kH%HEHP0|H}AGBkH%w *tHM PkH?HMqkH'-*1%HMukH%+hp(9HM&kHHEHP0|H}AGhH$HEH@8HEEHEH@0f=/tHEH@0f= HMhHXHEHP0|H}A9gHGd$UH}kH0HEH@0f=/uHEHp0|H}THEH@0Hp0|H}7HEH@8HEEH}*HMhH訿HM hH萿HEHP0H=a*|A9hHhH#~# *HMkH@)tHMkHHEHP0|H}A9hH;hH*#)tPHE@DHEHP0|H}AkHkH"HEHP0|H}AXhHkH"Hu)4HE@tHE@uHEH@8HEEEEGHEH@0f=/HMkH.HEHp0|H}sHMkHHEHP0|H}A9gHkH "UH}kH׽HEH@0f= HMkH蕽HEH@0Hp0|H}HMkHbHEHP0|H}A9gHkHn!UH}kH:EHEH@8HEEH}DHM lHHEHP0|H}AGG HEH@8HEEHEH@0f=/u1HMlH艼HEHp0|H}^HEH@0f= u5HMlHGHEH@0Hp0|H}HMlHHEH@8HEEH}EHMlHݻEl(9E|Hu)`Hu)R)fHM.hH腻HEHP0|H}AKiH'iHHEHP0|H}A4iHlHoh)ft#HE@tHM?(lHHM#GHM YH)HE@)tRHMhlH袺HEHP0|H}AXhHkHHMmlHhHMslHPHM lH8)tHMlHHMXHHMhlHÿ)u'HEHP0|H}AlHlHHEHP0|H}AXhHkHHMlHvHEHP0|H}AlHGH}lH#HMlH.H}sWH)tHMlHHEHP0|H}AlHlH H}GHEH@8HEE2HEH@0f=/tHEH@0f= tEHEH@8HEH}uHM lHhHE@tHE@HEH@8HEEHEH@0f=/HMsWHHMhlHHEHp0|H}5HMmHHEHP0|H}A9gHkHUH}mH虷H}GXHEH@0f= HMsWHIHMhlH1HEH@0Hp0|H}rHMmHHEHP0|H}A9gHkH UH}mHֶH}GHEH@8HEEH}hHMmH耶HEHP0|H}AGGHEH@8HEEHEH@0f=/u1HMlHHEHp0|H}b^HEH@0f= u5HMlH۵HEH@0Hp0|H}HMlH覵HEH@8HEEH}EHMlHqEf(9E|HM*mHJH}GR)HMsWH*t2*PH}.WH**HMIWH´HM/mH誴ɺ)ftHM2mH膴}u)HE@~HMsWH\om)EHMsWH*}usHE@uhHMLmHHEHP0|H}AdmHG UH}nmHٳHM-xmH豳HEH@8HE2HEH@0f=/tHEH@0f= tEHEH@8HEH}uǃ}HEH@8HEEfHEH@0f=/AHEH@0f= ,*t2*PH}.WH**H}IWH?HEH@0H@HtiHEH@0H@H8\HUuLHuH}蟲HEHP0|H}AGkHUH}mHgc)f)HuH}BHEHp0|H}wHMsWH@)f6)HEH@8HEEH}}!HEH@8HEHEH@0f=/HEH@0f= HEH@0H@HHEH@0H@@ f=HEH@0H@@HEH@0H@@utHEH@0H@H8\HΰtWHEH@8HEBHEH@0HPHEH@0H@H9uHEH@0H@H0mH]HEH@8HEH}uHEH@8HEH}HEH@8HEE7HEH@0f=/tHEH@0f= uHEH@8HHMsWHIHEH@0f=/HEH@0f= HEH@0H@HHEH@0H@H8\H衯tcf)!)f)HEHp0|H})f)f)HMmH芯HEHP0|H}A9gHkHUH}mHbHEH@8HuHE@ Džx DžxH}xmHHEH@0f=/HEH@0f= sHEH@0H@H^HEH@0H@H8\Hb=HEH@0f=2uHEH@0H@@ f@HMnHgHM nHOfb)[)fV)O)fl)g)f])HEHp0|H}^f))f ))f)HM nHŭHEHp0|H} )f)HM $nH腭HM+HmHEH@8HEEH}HMsWH:HMVH"HM)jH HMDjHHEHP0|H}AYjH/nH )f)HEH@8HEEHEH@0f= tDH}zjH蓬HEHp0|H}HMjHTFH}zjHOHEH@0Hp0|H}HMjH HEH@8HtHMjHHEH@8HEEH}% )f)HM+RH裫HM YH苫i)HEHP0|H}AXhH6kHHMLnHCHM\nH+HMlnHHM}nHHMnHHM%nH˪HM nH質HM nH蛪HMoH胪HMoHkHMXGSHM 8oH;H}HoH8H}oH%HM%oHHMXGHMoHͩHMoH赩HMXG蝩HMoH腩 )f))fHMgH:HEHP0|H}AgHgHF HM gHHEHP0|H}AhHG HEHP0|H}AhHgH HEHP0|H}AhH#hH HM .hH肨`)~"HEHP0|H}AoHpH HEH@8HEEEE6HEH@0f=/tHEH@0f= tEHEH@8HEEH}uHE@t E;E#HEHP0|H}ApHPhH HEH@8HEEHEH@0f=/tHEH@0f= HMpHoHEHP0|H}A9gHG{ UH}$pHGHEH@0f=/uHEHp0|H}kHEH@0Hp0|H}NHEH@8HEEH}*Hu)i HEHP0|H}AG2pH HEH@8HEEHEH@0f=/u1HMlHaHEHp0|H}^HEH@0f= u5HMlHHEH@0Hp0|H}`HMlHHEH@8HEEH}EHMlH赥EV(9E|Hu)8 HEHp0H}iHM9pHjHEHp0|H}HM@pH;H}G @ >)uPx*uHMGpHHMWpHH}GHM mpH趤HEH@0HtGHMxpH茤HEHp0|H}HM|pH]HEH@8HdHu(ޢHEH@8Hp0|H}HMpH Hu(蝢HEH@8Hp8|H}>HMOHʣ)ftHMpH衣ީ)fԩ))T*tsdE*PH}.WHg)* *HuH}FHEHp0|H}{HMsWHGHMIWHHEHp0|H}2HMsWH辢fѨ)HEHp0|H}f)HMmH})f)HEHp8|H}HEH@@ f@uE*MHMnHHM nHf))f ))f"))f)HEHp0|H}f˧)ħ)f))fէ)HM nH{HEHp0|H})f)HM $nH;HM+H#6=)ftHMpHHEH@HH}pHHEH@0HE;HM9gH趠HEHp0|H}HEH@8HEH}uHu))ftHMpHUHMpH=HEH@0Ht1HEH@0@ft HEH@0PH}8fHHEHp0|H}DHu)z)fu>HEH@Ht1H}肇#|HUH}A9hHpH|HUH}AGG|HuH}shg)ftHEH@H8Hu耞CH}H}¾8fH Hu(蚝HEH@H0H}Hu)xHEH@HtHEH@HH}pH踞Ǥ)ftHMpH脞)uHM pHbHEH@HtHEH@H0H}|fHcA)5Hu 诜HM(pHHM)THߝHMXGǝ)ftHMpH螝HMqH膝HEHp0|H}HM9gHWfj)c)f^)Hu"қHEHp0|H}wHM  qHf))f )*SL(9uHMqH远| q*L(9uHM1qH臜)ft0HM:qH^HMPqHFHMpqH.H}G6HEPHEqHΙH=?)24HEdH3%(ttUHH@H}HuHU؉MLEHEH@HEHE؋@&HEH@H|*H}u{HEHHEH@pHt&H=)HtHE@ ft H}XHEH}u.HEH@HHEHUH}I"{H&-HE@ fuHEH8 HEHE@ fu-H}){H艚tHEH0+{HFHEf@ HE@ f=$uHEH0H{HgGHuH}虚)fHEH@hH)fHEH@pHu*HEH8n{HtHEH8\Hԙu*H}QHeHEH8\H褙EHE@u}tHMQH}u)fuq{HlF۟)ft=HEH@pHt0H}){H)tHEH@pHH}辎{Hg)ftHEH8Hu芘HE@HE@<7)ft-{HD{H{Hߖ|HՖ)fuH}F|H՘{)fuCf)HM9gH蒘HEHp0UH}ڿf)+)fuLHEH@0Ht'HEH@0f=/uHEH@0PHE@9|HEH@0Hu@HE@~5Hu[誖HEHp0UH}RHu]舖HML|H˗HEHp0UH}HM9gH蟗HEPH}U|H蕗>HEH@0Ht1HEH@0f=/uHEH@0@tHEH0`|HDHE@ f=uAHEH@8Ht4HEH@8H@0Ht#HEH@8HP0MH}AG){H$HuH}UHH0H}HuUEߜ)fHEH@0H@H8HuHEH@0H@0Ht4Hu[!HEH@0Hp0UH}ŽHu]HEH@HH}辅|HMH}}EHMpH HEH@0H@H8QEUH}辉|HHEH@0H@0Ht2HM|H赕HEH@0Hp0UH}UH}辝|H蕕HEH@HH}辧|HwHEH@8Ht0Hu[HEHp8UH}蔼Hu]ʓ}tHu)趓UHHH}HEE}rt}r}ct.K}st}!t:E8E/E&HEHx0!t EEEUHH H}uH}u EVHE;Eu E>HEHx0uuHEHx8ut EEEEEUHHH}uH}tzHE= u) )}t))}tHEf= t EEHEHx0uHEHx8upUHHH})))H}>z)~G|H@`)uY)~G|H?UHHH}-)'))H} )~G}H?UHH})ƒ)t%H *8}H艒)H=h*U;}HvUHH}HuH)HtH)H;Eu}uRH)Ht2EP )Hg)HH=*AH¾A}HHEH=)E)UHH}H )Ht, )H)HH=*EAS}H译UHH }H)HEHE@;EtEHEH@HEH}uQ>HEHUEBH)HEHPHEHt)UH}HEH\)HEZHE@;Eu:HC)H9EuH6)H@H+)4H}t-HEHPHEHPHEHEHEH@HEH}uUHH H}H}HEHHHEH@EHE@ EH)HElHE@;EuTHE;EuHEHPHEHH@H9HEH@HHEEuIЉ¿h}HڍaHEH@HEH}u(9EuH=*Uؾ}H菎=(9EuH=]*Uؾ}HkH)UHH0}܉uH=)*Uؾ~H7E^)^HEH=)HE-HE@;Eu HE8 HEHEHEH@HEH}uH}u EE;E~H *}H蓍H)H)1~HH=f*Uؾ5~HtE)HEHw)HEZHE@;Eu:HEHp}H}tHEHPHEHP,HEH@H-)HEHEHEH@HEH}uH}u }`Zl`EE;Ef}H *}H葌;(9EuH=o*UؾQ~H};(9EuH=K*Uؾm~HYHv)u؋}UHH0H}HuEHE@ftQH)HE=HE@;Eu!HEH@0H@H8Hu,EHEH@8HEEH}uEEUHHpHHdH%(HE1HuH0HH!+HŠHH@HpHH~HHHp0HH)ZH~H蚊HHp0HH) MH~HLHHp0HH)辈H(計HHp0H;H/zHHp8H H)LH(6HHp0HH*HHp8HH)ڇH(ćHHp0HWH-薇HHp8H)H)hH(RHHp0HH+$HHp8HH)7H(HHp0HsH~HHHp8H@H)H(iHHp0HH&;HHp8HH) NH(HHp0HH^ɅHHp8H\H)蛅H(腅HHp0HH|WHHp8HH))jH(HHp0HH~H;HHp8HnH)譄H(藄HHp0H*H~H迅HHp8HH)1rH(HHp0HH>HHp8HH)迃H(詃HHp0HX|H@t HDž~H HDž~HHHP0HL~HHH@8HDžvHH@8H;tH,{HHp0HuHHp0H9HH@8HHuH]U{H~H|HHp0HH){HH~HG|HHp0HzH)zH~H{H ~H{HHp0H H)KzH(5zHHp0HH)zHHH@0HtSHH7{HHp0HjH HzHH@8HH(zyHH@8Hp0H HHzH(-yHH@8Hp8HHHQz2HHp0HHHzHHp8HGHH@H0HyDžHH@HHHHc\uHc"uHƄ't_Hf=uHHxH%HxHH.HxHH@0H@H,-wHHp0HHH@8HHuH)v$H2H#xHHp0HVH)vHHA~H~HHHHH@H8HvpHH@HH:HvwGH?HFwHHp0HyH)uHGHvHH@HHOHvHWHvH]HvpHbHovPHhHOv0HoH/vH vHvHHuHHuHHuHHustHHHH%@t%HHHOu#HHH*uHEdH3%(ttUHH H}HuUf{)z)fz)UHuH}fz)z)fz)ÐUHH@H}؉uH}uH5c*0)sHE؋@&HEH@HU*HE!Eȁ}+EHHH=*UHu臛H *H thȳ*r#(9TT*tH * HsHEHP0H=*MA'H)Hh*#(9HEH@8HEEEE6HEH@0f=/tHEH@0f= tEHEH@8HEEH}uÃ}uHE؋@EHEH@8HE2HEH@0f=/tHEH@0f= tEHEH@8HEH}uHE؋@urE*+EEH *6Hrn*~H=[*UJHrEH >*PHZr*H !* UH=r*+EEHE؋@HEH@8HEEHEH@0É} t }/H *`HqHEHP0H=*MAgHpHH=k*UrHqHEH@0f= uHEH@0Hx0uHEHx0u}H=*wHBq H *`HqHEHP0H=Ӱ*MAgHpHH=*UrHpHEH@0H@Ht]HEH@0H@H8H]pu@H r*Hp`*~2H=M*UJH{pHEHp0H=**U讗}H=*wHBp*~EHEH@8HEEH}ۯ*+EEHE؋@u*~EHEH@8HEEHEH@0EЁ} }/HEH@0H@Ht!HEH@0H@H8H#of~u)HEHp0H=#*U觖f^u)H *H'o*~H=*UJHoH ͮ*PHn*~EHEH@8HEEH}*+E*H u*Hnft)HEHp0H=D*Uȕft)H ,*HHn*~.***PH=*JH nHEHx8u~`HEHx0ulNH * Hm1uH}A#HEÉHxkUHHH}H}u EHEE}}}=}.tJ}ctK}t9E-w5*HEHx0 -E#H} EEEEUHH H}uH}u EVHE;Eu E>HEHx0uuHEHx8ut EEEEEUHHH}uH}taHEf@t HEf= u'H *PH7luH}{HEHx0uHEHx8uUHSH(dH%(HE1H=ǫ*jFHo)HHH=*@Hkq)fFHHKHzjH C*`HOkH (*sH4kH *HkHH=*HkH Ϫ*HjDž@H=*HHAIHHjH@ ;H V*HbjH ;*HGjHHH4iDž*H=*HHjH@ ;H@uSH *'HiH *@HiH q* `H}iH T*lH`iH 9* HEiHH@0HHeH=*@j}H m)HHHKHgHH=*@HhH@u H |*HhH@H@PH=<*H]hH &*H2hH *ٔHhDžMH=*HޔHgH=*HHgH@ ;H *HgHH^fHHǺ HfH A*HMgDž*H=*H&H.gH@ ;H ަ*HfH@ u"H=*H8HfH *WHfDžFH=k*HiHfH=H*wHcfH@ ;H *HfH * HfHH@0HHH=*jHEE}~}~}-}-3}&}%}!xE*q}R}R}/W}?M}c>}|4}^*_}.]}+} } }} t_}}!}H$}?}/tg}2t}Ltwffj)HEH@H8Hcu EHEH@H@pHEfj)EHEHx0#E{HEHx0EiHEHx0tHEHx8t EEEE/H>aHEy eaEEÐUHH:)1)+*%)9}*)*)HH<H*!)HHH=آ*`Ь)ά))Hɢ*HE)H*HEHHHHEHHEH@8HEH}uUHH@}HuЃ}u EHQ*EHHHHHEH}u!uܿH_HHE@t EHE@HEH@(HEEHEHUHHDHE)HEHPHEH@H9uEEWHEH@HEH}uЃE}~HE8Huu EHEH@ HEH}vEEUHE>H;*EHHHHHtH*EHHHH@E )9E|UHH}HuHE@E}tE}uhHEHf=:uXHEHH@8f=/uDHEHH@8@u2E0HEHfctHEHfrt EEEUHH0H}HEHEH}t HEH@HEH}tHEH@HHEH}HEH@ HHEH@8HHE@ %HEf=HEf=HEf=HEf=HEf=t{H}rHuhHEf=t[HEf= tNHEf=tAHEf=t4HEf@t'HEfctHEfrt HEfsu EPHE@ u;HE@ uHEH8耂EEEԉE}t EEEUHH H}HEH@HEHEH@HHEH}t*HEH@ HuHEH@8HuHE@ %t EHEHxHEH@HE@H*HEHPHEH *UHHH}H}t]HEHx HEHxHEHxsHEH@HEHPHEHPH)HEHP HEHw)UHHH}H}t@HEHx8HEHx(aHEH@(H-)HEHP8HEH)UHH==*H-*UHH }H*HEHE;EtHEH@8HEH}uH}H)Ht2H)HEH}@SH)H@8H~)@HEHUEHEH@(H*HEHP8HEHo*Y)9E~ EK)HEUHH }H)Ht2H)HEH}(RH)H@ H)(HEHUEHEUHH }uHU}HE}tHEHUHEHBHEHP(HEHP HUHEHB(}jHEHE@PHEP5*t4}HEHUHEHBHEHP0HEHP HUHEHB0HEH@HtHEH@H0H}UHH0H}HuUH}H}HEH@HHEH@H<_uWHEH@H8HYSaHEH@H8H E)DE)ȋ=D)DD)D)D))D)4EAȉDҿH=H=HuD)HfD)8H]D)HHHPD)p "H=H7D)H@8H,D)H%D)Hu =*5=D)7HN= HC)HHHBHHH@_&HHHH@Hm *HHHf=HHH0H0߉H8H8C) *9* u**tsH03H0Hf=uH0HH@(HHH0JH/)Hh7^HUdH3%(t9H[UHH2UuѣH!7}MUuH7H==)HEHUHMHuIIHH8t)^UHH H}=)=))ȉEH}膓EH@=)HE(mE;EuHEH@@ EHEH@8HEH}uEEÐUHH }uEEH@[l;EtZEr)9E|g)=~HK)HcЋE@l 8)HcыE@[lA")UHH }EEH@[l;EtzE)9E|EEH@{l;EtQÉ)9E|)=~HK )HcыE@{lA))UHH@H}dH%(HE1EE EH@[lEH@{l9tE))9E|Ջ)9EuhEH@{lO'9u%)uH;'H}Ⱦ!H6-EH@{lH}=H5HuHHgE)9EFE8E EH@[lEH@{l9tEj)9E|ՃEW)9E|EE܉EYEH@ltEM܋EH@[lHc@[lEH@l}~gHEE)9E|E܉))HEdH3%(t05UH}E/EH@[l;EuEH@lEEq)9E|EEUHHH}Hu𿀤H2HEH0H='H2Hu𿢤HUHHH}HEHE}}}%}@to}ct}t{}tb~HEHHx0 tH}H5HEHHx0p\t>H}H.H}٤HH}HH}HUHH0H}HuUHEH@0HEHEHH8NHEH}HEHE؃}r}r}R2}c}.t}V}}}s1}t2}HEHH@(HH0UH})EUHuH}EHEH@HHf=HEHpHUH}E}EtHMH2r**'9tHM H2VHM7H}29}EtHMHQ2Hu(0]|)HEP HEH0H}~YHu)0.|)}EtHMH1Hu(p0{)HEP HEH0H} YHu)A0{)S}EtHMHk1Hu(/w{)q*'9tHMFH+1HEP HEH0H}pXHu)/ {)}EtHMH0Hu(b/z)zp* '9tHMVH0HEP HEHHp0H}W7p*'9tHu).Hu).cz)HEH@HEH}8EUHHH}HuHUMDED|dH%(HE1EHp*eHHEH8HEHHttstsGtRtRt.vatcXtr?Btt%ttt tt:pHHEHHH@(H8|UHuLUAAйHHLx HEHHH@(H0|UH}AAйQSHMHW.HEH0H}.uHu1,HMH.EHEHH@HHf=HMH-HEHHpHH}uHu1N,HMH-EnHMHr-w)HEHP HEHH0H}THMH3-Mw)HMH -&w)HEHP HEHH0H}ATHMH,v)HMH,hl*'9tHMH~,HMHf,v)HEHP HEHH0H}SHMH',Av)HMH,k*h'9tHM H+u)HEHP HEHHHp0H} SHMH+u)mHMΥHq+ *tHMHN+HMH6+HM H+}tDžxjHM H*j*|H}H*j*H}4H*yj*H}OH*UH}hH)HEHj*HEHPHEH0EHMH}AH}HExtSHE@ tHE@ u7HEPH}H*HE@ ƒHEP t)HEx`EKJ&HEHH@H *H}aHEHx ws)xxHUdH3%(t#)UHSHHxHpHhH`D\dH%(HE1HpHEHE@ HE@ ƒHEP HE@ u<*s)HEPHxH(HExZHEPHxH(r)HExHEH@0H H}HEHDDoDD.xDtSD\HEHH@(HEHEHHHHEHHPHEHH0HxAVq)HEH@HHtjHE@ HEHxHHG@EUHxǦH'Hx٦HZ'}Z4H`tOH`PHxH3'Hx H'H`xH q)HE@ HEH88HǺ@EUHxǦH&Hx Ho&}oIp);HEH@HH*HEH@H@ HEH@HHtHEH@H@H DžHHEUHxH%Hx ,H%}HEx o)\o)Hx8H|%HEP HEH0HxLHx;HG%mo)go)\\Eo)?o)5o)HEH@HHtHEH@H@L DžLLEHEH@HHHEH@H@ n)UHx>H$Hx PH}$}}HEH@0HEEHEPMH}[HK#Mn)Dn)>n)HcHEH@QmHEHHtHEHf=tHEH@HHP HEHPHPHEHEHHPHEHH0HMHxA(m)m)HEHPHxjH#m)HEH@HEEH}m)uzHxwH2#HEHHtHEH@X DžX8m)ƒ-m)HxXH"m)HEH;huEl)uRH`tHH`PHxH"H`xHEH@HHEH}7HEdH3%(t!Hĸ[UHH H}Hqd*HuHHV)HE?HEHH0H?d*H8!uHEHH0HUHEH@HEH}uHEHc*HEHHUHEHBH)HEHPHEH)UHH H}HuH}HEHpH}HEHHH}HU!HEH@HE:HEH@0HEHEHxHEH@8HEH}uHEH@8HEH}uHM%H UHHH}H5)H}2UHH H}H)HE,HEHH0H}B u EHEH@HEH}uEEUHH H}H)HE4HEHH0HEH8uHEH@HE,HEH@HEH}uHEH0)HHEHEUHH@H}HuHUȋQ@&EH*HEH}\HEHEHEHE@@&HEH@H*HEH@@ ftHEH@H0>HMHEH@@~HEH@H0XH)i'tHEHPHEH@@BH}HEH@H8H"u+HEHPHEH@@B$)$)rHEH@H8HuHEHPHEH@@B8HEH@H8HuHEHPHEH@@@BHEH@f@ HEHPHEHBXHEHPHEHB`HEH@@HEHPHEH@@BHEH@@HEH@H0HHEH@8HEH}E>>&HEH)UHHPH}HuUHEHx0UxE>&EH)HEHEȋ@=&HEH@H)}t H}HE@;E~}y1HEHHEH0UHHEH0ܨHHEH@8HtHEH@8H@0Hu2HEH0HET=&HEH)HE5HEH@8f.t'HEH@8Hf蔵HEH@8H@0HEHEf=2t0HEf=0t#HEHGHEHP(EHHHHHEnHEH@0HEMHEH@H0HEH@H8u"Ec<&HEH)HEH@HECHEH@8HEH}uHEH@8HEH}uHEH@H0-HcHEHEUHH@H}HuЉUH}tUHuH}HEH}u EHEH@8H@0HEHEH@@ f=uHuH}EHEH@8HtHHHEHx0uEHE@;E~}yHEH0ܨHHEHHEHP EHHH0HE@ @EȋEUHH@H}HuЉỦMȋUHuH}HEH}u EHEH@8H@0HEHEH@@ f=uMHuH}EHEH@8HtHHHEHx0tEHE@;E~}yHEH0ܨHHE@~HEH!EHEHP EHHH;Et&HEHP EHHH‹Eȉ)HEPEEUHH0H}EHEf,u HEHE7HEH@Ht HEf=t EHEHxHEHEHEHEH@0HEwHEH@@ f=uKHEH@@HEH@@tHEH@H0hHVHEH@HxX,EHEH@@EHEH@8HEH}uHEH@8HEH}]EEԋEUHH H}HEH@HEH}u EjHE@ f=tHE@ ELHEH@8Ht"HEH@8f.uHEH@8H@0Hu EHEH@8Hx0qEEUHH@H}؉uHUȋEԉEHEHEHEH@0HE}HEH@@ f=uHEH@HPXuH}EBE)EHHHHUHEH@@ EEHEH@@;EHEH@8HEH}xHEH@8HEH}SEUHSH(H}HE@ f=tH}оHEH@(HHEЋ@HH<bHHEHP(EHEHP(EHHHHEHxX}HHEHP(EHHHHHE:HEH@0HEHEHx'HEH@8HEH}uHEH@8HEH}uEHEЋ@;EYH([UHH0H}uUMH}u HES@jHEHEHEfHEPHEPHEPHEPHEHPHEHPHEHPHEHP}t%HEHx0Mܺ_HHEHP0}t%HEHx8Mܺ4HHEHP8}tnHEH@HtaHHEHPHEHpHEHxHEH@@ f@u HEHPW )N )H )BHEH@ Hu HEH@(HtHHEHEHEUHH@H}HuHUȉMEHEH8HuHH}tUHuH}(HEH}u EHEH@8H@0HEHEH@@ f=u)Huؿ.:HUHuH}ع^EHEHH}ؾHuHEH@@HEH@@<u)HEHx0mH}؉¾H3EEEEUHH0HHdH%(HE1HH@H@XHgHH@0H7HH@H0HH@H8Lt{HH@8HHuHH@8HHuHH@HHH@HHH>HHEdH3%(tUHH@HHHdH%(HE1H6HHHHHH@8H@0HHH@@ f=uIH?HHǺ٩HHHH HHHHHH/HH@@HH@@<u;HHx0ukH¾HHHHEdH3%(tUHHHHH@dH%(HE1H@H@@u6H@@u'H@HHHHp۩HDžl)H@@H@@<u0H@HlHHHpAHH@HP(lHHHHH`H`H@0HXlHXH@@ f=uHXHpHp,HXH@@ f@uHXHpHpHXH@8HXHXuH`H@8H`H`VlH@@;lHEdH3%(t=UHHHHDH8H0L(L HEHdH%(HE1H0H0@u6H0@u'H0HH8Hp۩H DžlH0@H0@<u0H0HlH8HpAH H0HP(lHHHHH`H`H@0HXHXH@@ f=uOHXHHH H(HpDDLHHH$IIHDLaMHXHHH H(HpDDLHHH$IIHDLhHXH@8HXHX/H`H@8H`H`lH0@;lcHEdH3%(t UHHHHHdH%(HE1H=Dž~HHP(HHHHH?HH@0HHH\ H@H@<uGHR HƄHHZ HHw HH@@ f=uKHH@H0HH H٩H7 HHPHHHHPHH莑HH@8HHHH@8HHH@;lHEdH3%(t UHHHHHdH%(HE1HIDžH@H@<u%HHHHHf HHP(HHHHH%HH@0HHH@@ f=uaHHH٩HlHH@H0HRHHxHHfDž=HH@@ f@u"HHxHHjHt&HP HHH0H:HH@HHHHH@@HH@@<uH HHH@@ f=HH@HP HHH0H=ø'M HH@@;HH@8HHHH@8HHH@;0HEdH3%(tUHSHHH}ЉủUHMDEẺEHEHEtHEH@0HELHEH@@ f=HEH@HHXEUȋuH}AE}H}HEHEH.HHEHP8HUHEHEEE;EusH}fHHEHHEH/艴HC0HEHHP0EB}t HEHEfEPEEHEH@@;EiHEH@8HEH}HEH@8HEH}EEEHH[UHHH}H}u EHEH@HuHHEH@@ f=t EHEH@8Hu EsHEH@8f.tNHE@D%&HEH@H)HEH@8&HpHEH@H0/HWHEH@8Hx0!EEUHH0H}uHE}uKHEHEPH}CHEH}tHuH}HEHEHEH@8HEH}uHEHEHEUHH@H}؉uԉUHEHEH@@ f=u H}gt HEHElHEH@8HHEH@8f.HEH@8H@0HHEH@8H@0H@HHEH@8H@0H@@ f=HEH@8Hx0UЋu1HEHEHE[H}عXHEHEHP0.腱HHEHP8HUHEHB0HEH@8HEH}uHEHEf}tHEH@H@XHuZ't HEHE8EH<H=m'HuغSQH=HEH@H0SHHEH@HxXEEEHM,裰HEHEH@HHXHEHx0EЋUAx'uqHHEH@H0HtH}عHEHEHP0.HHEHP8HUHEHB0m}5HEHEHEUHH H}HuHEHE(HEf,tHӭHEH@8HEHEH@8HuHUHEHB8HEUHH H}H )HEAHEHH0HEH@H8YuHEH@H0HnJHEH@HEH}ufHEHEHPHEHH)HEHPHEH)UHH H}Ho)HE,HEHH0H}u EHEH@HEH}uEEÐUHH H}H}t HEH@Hu ElHEH@HEHE@ f@uHEH@Pf@E8HE@ f=u#HEH@8HtHEH@8Hx0wEEEUHH H}HuUH}}tEHEH@pHt)HE@ ftHEH@pH0ЪHתHHEH0ڪHHE@ f=uUH}tNHEH@8HtAHEH@8H@0Ht0:HEH@8H@0HpHEH@8Hx0UHHH}uH}tpHEH@HtcHEH@@HEH@@tHEHx0uHEH@@ f=u!HEH@8HtHEH@8Hx0uzUHH H}uH}MEtrHo)H@HtbH_)H@HHtOHL)H@HcuHEHPHEH@@BHEHPHEH@@BH)H@HE5HEH0H}tHE@;EHEH@HEH}uH=*HtH<*HEH<*H@H<* 迩HEHUHEHHUEBHb)HPHEHPHO)HEHBEƃH}UHH H}uH}HE!E}+EHHEƃHEHx0Eƃ HEHx0EƃHEHx0sEƃHEHx8^]EƃHEHx0DEƃHEHx8/.uH}uH} H}HEH@0HEHEHx0HEH@8HEH}uEƃ HEHx0HEH@8HE!EƃHEHx0HEH@8HEH}uvEƃ HEHx0]HEH@8HEUHEH@0f= uHEHx0u.&HEH@0f=/tEƃHEHx0HEH@8HEH}uEƃ HEHx0HEH@8HE-HEH@0f= uHEHx0uHEH@8HEH}uEƃHEHx0}HEH@8HttHEH@8Hx0u\HEH@8Hx8uHJHEH@0HE!EƃHEHx0#HEH@8HEH}uHEHx0UHH H}uH=)H@HETHEH8Hut/HE@#EEHE@ UHEP}E_HEH@HEH}u HEHUHEHHUEBH)HPHEHPH)HEHBEEUHH0H}HuHU؉MH}HEf= ubHEH@H8HuuzHEH@0HEE,E;EuHEHx0IHEH@8HEEH}u0HEHP0MHuH}WHEHP8MHuH}?UHH0H}؉uH)HEHEH@ HE^HEH@(HE=HEH@Ht$HEH@HHEHHH8MHuHEH@ HEH}uHEH@8HEH}uHEH@(HEH}vUHH0H}H (HEHEHHEH}HEH@pHHEHH0HEH@pH8unHE@xcHE@ f@uUHEH@Pf=2uD=HEHUHEHBH}EHEHxPHEH@HEH}6UHH@H}EH}HEH@HEHEH@0HEHEf,t HEHE HEH@0HEEH}@uS ̢HEHUHEHH)HEHPHEH)H)H)HEHH8uHEH@8HEH}aHEH@8HEH}9UHHH}H}t8H}@uH}HEHx8HEHx0UHH}EHEH@8HEEHEH@8HEH}uEUHH}HuEHEH@8HE1EHEHPHEH@0H@H9uEEHEH@8HEH}uEEUHH0H}HuUH}uH}u EH}tH}u EHEH@HEHEH@HEH}tH}u E}t!HEHPpHEH@pH9t EHEP HE@ f9t EvHEH0HEH8Rt EVHE@ f=uAHEH@8Ht4HEH@8Ht'HEH@8Hp0HEH@8Hx0EEEUHH H}H)HE2HEH8Hut HEHݝ)THEH@HEH}uǿ ӟHEHUHEHH)HEHPHEH)H)H)UHH@H}HEH@ HEHEH@(HEtHEH@HELHEH8)@+HE@HEH8HEH@HEă}rt&}:HEH@HHx8Hܜ)HEHEH8EHEH@H8EE;EuKHEHpHEH8EHEH0HEH@H8EE;EuHEHxHEH@HEH}t/HEH@H@HKHHEH@HEH}HEH@ HEH}HEH@8HEH}YUHH H)HEqdHHEHHpHEH8NzH]HEH@HEHEHH@Hu}H-HEHHpHEH8<EHE@tHHE@tHHE@tHHEH8t HE蜴HHE裴HHu迨Hy>HEH@HtHSHEH@HEH} rHEH@HEH} QUHH0H}HuHUHMHE@u)))HEfPHEf@) HEH@Ht~HuпHHEH@H0H='yHuؿH^H}t+ҴHHHEHHpHEH8 bHEH@HEHEH;EtjHE@ t\+) t@EE;EHE@HEH8HuȺtHMHuH}H}H)HEHEH0HEH8ltiHEH@HEMHEH8HuȺEt(HEH8tHMHuH}HOHEH@HEH}uH}uHEH@HEH}dHEH@HEH}UHH0H}H}H}@E) t9HEHHEHpH}غHH)HE1HE@uMHUHu"HHEH@ HEH}uHL)HE1HE@uMHUHu+HHEH@ HEH}uH)HEHEHHH82HHEHHH8:HHEHHH8BHtoHEH@ HEZHEH@(HE9HE@uHEHHH8MHUHuHEH@ HEH}uHEH@8HEH}uHEH@(HEH}!UHH@H}H)HE$HEHEHE@HEH@HEHEHH@@ fHEHH@H@pHtnHEHH@H@pH8HupuO) t9HuؿPHlHEHHpHEH82 EjHEH@HEH}OHEH@ HEH}H)H9Eu H)HEHEHEHEH}EEUHHH)HE|H)HEAHEHH0HEHHH8puHE@ƒHEPHEH@(HEH}uH}uHEHH0uHEHEH@HEH}yUHH H}H])HE&HEH0HEHH8tFHEH@HEH}uӿHEHUHEHH )HEHPHEH)UHH H}H)HE7HEHHH8HufuHE@ƒU)HEH@(HEH}u¾H]EEUHHH}H}u EZHEf= uHEH@H8UE8HEHx0uHEHx8t EEEEEUHH H)HE$HEHHH82HytQHEHHH8:H^t6HEHHH8BHCtHEHHH8H(uHE@ƒHEPHEHHH8tHE@ƒHEPiHEH@ HE:HEH@(HEHE@fu&HEH@ HEH}uHEH@8HEH}uH}tHE@ƒHEPHEH@(HEH}H)HEHEH@ HEnHEH@(HEMHEH@Ht4HEH@H8t HEHHHHu躺HHEH@ HEH}uHEH@8HEH}uHEH@(HEH}fUHH0H}HuHE@u/HE@ƒHEPHEHHH0HHE@ EHEHHtHEHH@HHEHEHHEHHtHEH@EEMHUuHH HEH0H=6' oH UHHH}H}u E[HEf@t HEfpu E8HEHx0uHEHx8t EEEEEUHH0H}HuHEH@(HE,HEH@Ht)HEH@H8FtHE@ƒHEfPG) eHE@E؃}t-}}ts}t5}tKeHcHE@ HGHE@&H+HE@,Hs2HbHEHE05HGHEH@HtHEH@H0H=`'Jm?H HEH@HEMFHHEHHpHEH8HEpIHHEH@HEH}u tHE@fugHEH@HtZHEH@HE܃}s}r}}ct 2}:u)HEH@HH@0f=/tHEHpH}VHEH@ HEH}UHH H}uUH!!*EHHHHHEHE@uQHE@}t HuH}PHEH@(HEHE0UH}HEH@ HEH}uUHH H}HEH@ HE4HE@H *HEHHHHEHHEH@8HEH}uŋd) t#HEPHEHHH0NHHEpH}UHH0H}HEH@ HEHEH@(HEHEH@HHEH@HHHEH@HfsHEH@HEHEH8b@ueHE@tWHE@uI]HEHEH@HHEHHEHHEHPH,)HEHPHEH)HEH@HEH}sHEH@ HEH}HEH@8HEH}UHH H}H)HE/HEH8HuAt HEHEHEH@HEH}uHEHEUHH0EHW)HEHEH;)HEH@HEeHEH8_HEH}tBHEH@HE-HE؋PHE@ HEH8EHEH@HEH}uHEH@HEH}uHEH@HEH}d}CH)UHH H}HEH@ HEHEH@(HEoHEH5)HEHxHEHxHEH@HEHPHEHPHEH@HtHEH@H8HEH@ HEH}uHEH@8HEH}eH)UHHH}u1)tZEtPEtFhHHEHpH}NuHZܽ)ӽ)uH}UHH H}u|)[H}PHE!E}+EHжHEƃ HEHx0 EƃHEHx8EƃHEHx0jEƃHEHx0MuH}HEH@@HEH@@EƃHEHx0vEƃ HEHx0HEH@8HEHEHx0uHEH@8HEH}u+EƃHEHx0HEH@8HHEH@8Hx0uyHEH@8Hx8ueuH}EƃHEHx0:EƃHEHx8%H}HEH@0HE!EƃHEHx0HEH@8HEH}uOEƃ HEHx0HEH@8HE!EƃHEHx0HEH@8HEH}uEƃ HEHx0rHEH@8HE?#))EƃHEHx0@))HEH@8HEH}uHEH@0HE!EƃHEHx0HEH@8HEH}uYHEHx0EEƃHEH@0Hx0HEH@0HxHE𿨶HUHHĀdH%(HE1E׹) tf0HH)HE< HEHHpHEH8= HEH@HEH}uEH[)HEHEHH@@HEH@HEH}uH (HEHEHHEHE@HE@ f=uHEH@Pf=/tkHE@ f=t]HE@ f=$tOHEH@hHuBHE@ H}Tt*}uEHH H}VHEH@HEH}EUUEHUdH3%(tUHH@EEH (HEHEHHEHE@<uqHE@ ft*HE@ ftHE@ f tHE@ f=u9}u ExHH H}VHEH@HEH}aHR)HEEHEH@ HEHEH@(HEHEH@HHEH@HEā}}/}rtq}r}.tq}@tkc}stQE-wPT}tK}E-w/3}t*}|E-wM MM.HEH@ HEH}+HEH@8HEH}}t}u@}u HEȰHHEȷHHEHHH0HUȿHE E&}u HEHHH0HMHEH@(HEH}bEtHHHEtHHEt HsUHH Hj)HE~HE@ ft|HEH@HEHL)HE(HEH0HEH8uHEH@HEH}uH}uH )HUHBHEH~)HEHEH}wHEH~)UHH H}uH~)HE3HEH8Hu2tHE@;Et]HEH@HEH}uƿkHEHUHEHEHEfPHEf@ HA~)HEHPHEH.~)UHHH~)HEwHEf@ ) tHHHEHHpHEH8HEH8蠺ƿHHEH8rHEH@HEH}uUHH0H}uH|*EHHHHHEHEH@(HEHE@t EHEH@HHEH@HHt~HEH@H-E܃}HcMܸH%HHE0H}Hg)Hg)Hg)UHH H}uHE@tHE@t EHE@t EHE@ƒHEPМ) tHEHHE0UHrHE@t>) tHE0HBHE@ƒHEPEYHE;EtGHEH@(HE2H.)HEHHHH8uuHEH@ HEH}uEEUHH H}uHE;EtoHE@tdHE@uVHE@ƒHEPHEH@(HE.H)HEHHHH8uHEH@ HEH}uUHH0H}HuUHEH@HE%HEHH;Eu HE@;EtRHEH@HEH}uԿ gHEHUHEHHUE܉BHEHPHEHPHUHEHBUHH H}HEH@HEĚ) tHEHHEp1HfHEpHEH8Tu?) tHEHHEpFH#HEpHEH8HHEH@HEH}gUHH@H}HuЉUH)EHHHHHEHEЋHHEHEЋ?EHEH@ HEԙ) tCEHHHEHMHH!HHEHEЋ0ZHREHHHEHMHH!HtHEЋHuH}UHH0H}HEH@ HE}HE@bHEH@0HEE,H)HEHHHH@EHEH@ HEH}u̓}EHE;EH)EHHHH@EHHEE?EHEHPEHHHHMHH!Ht~H>)EHHHHH@(HEE,H)HEHHHH@EHEH@ HEH}u̓}~HEH@ HtUHuH}EHE؋@ ;EHEH@8HEH}xUHH H}HEH@ HEHE@HEH@8HEH}uHEpH}UHH0H}HEH@(HEHEH@HHEH@HHHEH@H-E} wbHcMHHHUHE%HuHE؃Ht5EJH)HEHHHH8Jt EHEH@ HEH}CEEUHH H}HEH@0HEHA)HEHHHHHEHE@t|HEH@HtoHEH@HHt_HEH@HE}t#} }t.E-w! E4H}Kt EHEH@ HEH}DEEUHH@H}ȋ~) tHEHHH0uH#HEH@ HEHE@lHE@ZEEEEEEEHEH@(HEH)HE؋HHHHHEHE@ EHE@EHEH@Ht_HEH@HHtOHEH@HEă}s}r}(}ct"'}t }uH} EEHEH@ HEH}F}u}u}u }~^}uXH}uKHE@ƒHEP) t+HE8EUMuAAЉH藰HEH@8HEH}nUHH0H}HEH@ HEHE@HE؋@HH<a_HHEHPHEHE؋@9uEHE؋@HHEHE؋@?EHEHPEHHH‹MHHoE HEHPEHHHHEHE؋@;EHE؋@ H?HHE؋@ ?E{HEHHHE؋@HcиH)HHH=H)H4HEHHHE؋@HcиH)HHH=H)HHMHH!HE}?{ExH)EHHHH@uVEHHEE?EHEHPEHHH4HEHPEHHHHMHH!HEHE؋@ ;ExHEH@8HEH}UHH0H}HuEHE؋PZ)9~)HE؋@Z)Z)HH<.]HZ)EHZ)EHHHHEHE؋@;EHEH@0HEH)HEHHHHHEHE@tbEMHZ)EHHH4HZ)EHHHHHEHPEHHHHH!HEHE؋@;EHEH@ HEH}^HEЋHHEHEЋ?EHY)EHHH4HuY)EHHHHMHH HEkHEHPEHHHHH+Y)EHHHHH9t3EHEHPEHHH HX)EHHHHHEHE؋@;EEUHH H}H}EHEH@ HE8HE@t!HEHE@9tHuH}EHEH@8HEH}u}uH)HE@HHHH0H}XUHH X)yHX)HEYHE@ HEH@ HEEHE@ PHEP Hy)HEHHHHEHHE@HEH@8HEH}uE;H5)EHHHHHuH)EHHHHlEHE@ ;EHE@ HH?HHEP) t]HEPHEHHH0H胪HE@ ƒ?HEH=)HEp AA@HIH}H}H}HEH@ HEPHEH@0HEHEHP(HEHP0HUHEHB(HEHPHEHP HEH@HEH@8HEH}uHE@EH)H@t HE@H}\H}xH}HEH@ HE4HEH@0HEHEHP(HEHP0HUHEHB(HEH@8HEH}uHUEBHEH@(HEH}lHV)HEQHEH@ HEC-HX'X'#0HX'X'HEH@0HEOX'X'zX'qX'3H藥HEH8 补HEH@HEH}uHEHEԁ}t0}X' X'l6H*aW'W'I:H>HEHf=t HEHf=tHEHf=uH}2HEHf.HEHf@HEHf=HEHf=u0>HDHEHH@H0H=gW'HEHfcuMHEHH@0f=u9FHHEHH@0H@H0H=W'PH"HEH0H=V'0UHģHEH@H;EtHEH@HHEH}UHHH}H}HEH@(Ht HEHx(HE@"t DvHEHH0WHHEH@Ht(eHHEHpH=*V'0pHHEHxsHUHH=z(8ÐUHH HEO)E}Z}%}}}(tHB} } }tR} }  HERO))t xHG08O)HT)HEO) HHEHPH}p`HE N)HEHEf=tHEf= cHEf= u!HEH@f=AHEH@HEmHHU mHEV ^N)aHEHEf= Hu ^mHE N) HEHEf= HEf=HEf= uHEH@f= trHEf= u HEH@HE lHHU lHE.H)HEr zM)H)HEZ bM)H}u HUHEUHSH(H}H} HE-E܃}  EHŘHHEH@f= t"HEH@f=tHEH@f=uHEH@HEZ HEHpHEHx]ptHEH@HE0 HEH@f= u6HEHpHEH@HxptHEH@HPHEHPHEH@f= u&HEH@H@f= uHEH@HEHEH@f= HEH@f= HEH@HPHEH@Hp kHƺ jHEKHEH@f=t"HEH@f= tHEH@f= uHEH@HEHEHpHEHx otHEH@HEHEH@f=u*HEH@f= uHEH@HPHEHPHEH@f= HEH@H@f=tiHHEHPHEH@HPHEHP<HEHpHEHx?nt iHEHEHXHEHpiH[HHڿjiHEH}PZH[HEHEHpHEHxmt iHE{HEHxiHHEHxiHHڿhHYHZHEHEHphHZHHEHphHZHHڿhHoYH5ZHEHUHu^hHEH}DYH ZHEHEH@f= u.HEHpHEH@HxltHEH@HEfHEH@f= u.HEHpHEH@HxTltHEH@HE'HEH@f= u.HEHpHEH@HxltHEH@HEHEH@f= u.HEHpHEH@HxktHEH@HEHEH@f= uyHEH@f= uhHEH@HpHEH@HxktGHEH@HXHEH@HPHEH@HpfHHڿ fHEHEH@f= uvHEH@f= ueHEH@HpHEH@HxjtDHEH@HPHEH@HpUfHHEH@Hp HEH@f= u-HEH@HpHEH@Hx(gt HEH@HEHEH([UHH }HE}yMHEExHEEzUEHcHcHHȋjC)9uRB)ExIUEHcHcHHȋu'^H)EV}-t)?H AE}>u']H)E VHn E!E}[EHhH/\E\/E&&lEm||SET[]:E;->!E"EE E E }\H)EEEH[UHH H}H}EEHH@lHE*HEH8Huu HEHE{HEH@HEH}uϿHHEH}踐xHHHEHHEH8HuvEHH@lHEHPEHcHEH@lHEHEHEUHH H}HHEHEHHEHHEÐUHD)D)9}!D)HclEByD)qD)hD)EEUHHEE.EHl<(uEEHl<)umE D)9E|ǃ}tC)C)HHUHH5)lɏUHC)~C)C)UHH5C)aH5S)zHYJUHH0}Huq)BC)Dq))Љ7C)kHEHHHE܃}ft9}f }dt }n}vB) mHEElHEHHEHH< t6HEHHEHH<"tHEHHEHH< uHEHHEHH EHEHHEHH;EqHEHH0l蝎l賍%B)CB)A)2A)&HEHHHHZ/mHE}~HEHH<-yA)u(H?H5H+1,bA)uWA)tDA)UHHH}H}_HEE}}D}}}}t}} } } y} O} &} uH5w)(ŋHEHxH Y) HHEHxH51))JH5)(iHEHxH )H行HEHxH5))#H5)( HEHxZH )HEHEHx2H5y))NJH5c)(豊HEHxH E)HHEHxH5))k6H5)XUH )H蚋HEHxH5))H5)!H )HKHEHx8H5))͉H i)H {H L)%H^HEH@HH=$)*H݊;H )/H谊3HoHEUHH}EE}}Q}}};j}i}}-}  } }}} } } CHvFHbIHNLH:PH&ZH|]Hk!5_U)SVGX;%H*H识`H螆}ԆUHH H}HuoHsH}tHuH}ZH}J3)t.3)t$yH&=h3)'QlHE-*El;)9E|翘HH=9'5+;)";)UHHH}H}UHHH}HuHuH}衅UHH H}迠HUHEH@(HE$H}hH/HEH@ HEH}uտH HEH@0HE$H} HHEH@ HEH}uտHńHEH@@HE$H}H蟄HEH@ HEH}uտH}HEH@8HE$H}HWHEH@ HEH}uտ zUHH H}H}HI)HEHHEHI)n9)tYHEHH0HHEH@HE"HEH0H轃HEH@HEH}uH}1wI)nI)hI).I)9~ XI)I)UHH1I)HEH}tHEHHI)"I)I)HEUH5I)ƒ*I)HlNlUHH@}HuHUHEEȁ}t}tPHEHPHu}t!HEHPHu}t EEEЉEHEHPHu}luHEHPHu}Tt EEEԉERHEH@8HE6H}?HEHUHu؋}Vt EHEH@ HEH}uEEUHH H}H};?HEHG)HEsHEH@HtWHUHutAHE@ZG)HUHcLjVHE;G)2G)HEHHEH}uHEf= uHEH@HE[UHH H}H}{>HEHF)HEHEH@Ht~HUHuthHE<>vH&HE@yF)HUHcLjLHVHE]F)TF)JF) F)HEHHEH}[UHHH}H}tqHE-E} w[EHHHEHx?E)E)H}HEHxHEHxHEHx|UHH H}HE)HE0HEHH8Hu膁u HEHEsHEHHEH}uH3E)HE.HEH8HuEuHEH@HE.HEH@HEH}uHuPH-HEHEUHH H}HuH}4HEH}t1H}HHEHEHPHEHPHUHEHBUHH H}HEE}t} t }t CEAHEHxtHEHxt EEEEEEUHH0H}HuU܋E܉EH}u EE9H}HKHEH}l;H2<HEHEf= tHEf=t HEf=u6}uH <)lHH}EHEf=(}uH )lHH )qH~HEHxHuE}uH )tHD8HEHx=t'H r){HEHEHxHuE}t)HpHHTIHyHh@HHhHhHhAЉHxHhHP0HpHHHX%.H`H@H`H`HEdH3%(t#zUHH`dH%(HE1EH=)HEHEH@H}t"HEHH8Hyu =)uq=)9Eu-HEHH8HytH}HOyUH}HxHEHH0H}xHUuH})HEHHEH}HEHEHEH@HEHE;EuHEH@HSHEHHEHEH8HEHEH0HEH8?E}tB}yHEHHu؋}x HHEHHEH0HU؋}Y HHEHUHH}HuHE;EtHEHpHEH@HEfUHHH}HEH}uHEHPHEE}t}tHEHPhH)Hu}aHu%}hH)HEHEf=uHEH@HX HEHXHXHEHEf= u(Hu HE>HEf=u1H5A)H)BHEf=uHEH@H` HDž`H`HEH}H)HEWH)HEHEH;EHEfHEfHEf=uHEH@Hh HEHhHhHEHEf=uHEH@Hp HEHpHpHEHuH}= tHua$HUHutHu;HEf=uHEH@Hx HDžxHxHEH}HEf=uHEH@HEHEHEHEH}};HR)HEHEf=uHEH@HEHEHEHEHEHEf=u(HucHE>HEf= u1H5) dH)HEf=uHEH@HEHEHEHEH},Hn)HE<H^)HEHEH;EHEfHEfHEf=uHEH@HEHEHEHEHEHEf=uHEH@HEHEHEHEHEHuH}tHu$HUHul tHuHEf=uHEH@HEHEHEHEH}HEf=uHEH@HEHEHEHEH}H)HEHE&HEfHEH@HEHu%H}u"H)H@H)H)HEHUHEHBHEH@HEHEH@HHEH@HHEf=t HEf=u~HEH@HEHEH@HEfHEH@HPHEHPHEH@HPHEHPHEH@HPHEHPHu@HEHEHEH@HEH}H)Hu#H}uHHHEHPH)HPHPÐUHH H}EHz)HErHEH8HutNHi)HH^)HE@tHEH0H}t HEHE2HEHxHEHEH@HEEH}uHEHEUHH H}H}u HEHEH}0HEH}t HEHEH)HH) HEH}HHEHH} HHEHPHEHpHEH8t,HE@HEHprHEHHEHPH)HEHPHEH)HEHxaHEHEUHH5)hH4H5)H3UHH}HuH}tK}tEEUHH H}HuH}uH}u EH}tH}u EHEHEf9t EHEH@Ht8HEH@Ht+HEH@H0HEH@H8?2t E<HE-E} EHHE HEH@Ht HEH@HuHHEH@H0HEH@H81EHEHpHEHxEHEHpHEHxu EvHEHpHEHx}u ETEKHEHUHuE/HEH)/HEEUHH H}HuH}uH}u EH}tH}uEH}uHEf= u%EHEf= u EEHEHEf9t EHEH@Ht5HEH@Ht(HEH@H0HEH@H80t EKHEHpHEHx t"HEHpHEHxt EHuH}EEUHH H}HuH}uH}u EH}tH}u EHEHEf9t EHEH@Ht5HEH@Ht(HEH@H0HEH@H8(/t EBHEHpHEHxFt"HEHpHEHx-t EEEUHH H}HuH}u E_HEf=uBHEHpH}uHEHpH}t EEEEHuH}jEEUHH H}HuH}u E_HEf=uBHEHxHutHEHxHut EEEEHuH}EEUHH H}HuH}u E_HEf=uBHEHpH}uHEHpH}t EEEEHuH}bEEUHH }HuHUH}u ElEE}t}t}t&6HuH}E:HuH}E(HuH}E(HEEÐfffff.Hl$L|$H-I%L=I%Ld$Ll$Lt$H\$H8L)AIHI;*Ht1@LLDAHH9rH\$Hl$Ld$Ll$ Lt$(L|$0H8ÐHH8+UHSHHHI%Ht.iDHHHuH[ÐH,HQDXYOM_N`P^aZ[C\B]T  !"#$%&'()*+,-./0123456789:;<=>?@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: poppingu@@u@@@u@@u@@u@@u@@u@@u@@u@@u@@u@@u@@u@@u@@@@@@)@V@c@@@@@U@@@5@@@@@$@8@u@@u@@k@@@5@@@h@@@@4@U@v@@@@@@ @ @ @/ @u@@u@@? @t @ @9!@]!@!@!@!@!@!@"@H"@"@(#@`#@#@$@$@$@$@"%@2%@`%@%@&@&@&@&@&@ '@q'@'@(@J(@T(@(@(@D)@)@C*@+@+@+@&,@N,@v,@,@,@,@I-@]-@-@-@l.@.@/@3/@U/@d/@/@/@;0@J0@0@0@0@0@ 1@91@H1@u@@u@@u@@u@@1@1@1@1@1@2@12@[2@2@2@2@3@-3@W3@3@3@3@3@)4@S4@}4@4@4@4@5@c5@5@16@_6@6@6@7@7@|7@7@7@7@8@C8@|8@8@8@9@R9@_9@o9@9@9@9@9@9@ :@ :@J:@t:@:@:@:@;@J;@x;@;@;@<@u@@8<@a<@<@<@<@<@<@<@D=@=@=@>@M>@>@>@?@l?@?@?@#@@f@@procedure 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"); } else { printf("pan: precondition false: %s\n"); _m = 3; goto P999; } } now.{ _m = 3; goto P999; } } } ++--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: %sp@xp@r@p@p@r@r@r@r@r@r@r@r@r@r@r@r@r@r@r@r@r@r@p@r@p@p@r@r@r@]q@t@u@u@u@u@t@u@u@u@s@s@u@s@u@Zs@u@u@u@u@u@u@u@u@u@u@s@u@t@st@Ft@t@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@u@t@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::;<<>><=<>=>===!=???!!!&&|||@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~@D~@D~@D~@}@}@}@}@~@0~@~@}@w}@}@E}@,}@^}@|@|@|@|@bitbyteproctype %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 -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 -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 -or@ʯ@"@z@ϰ@Spin Version 5.2.4 -- 2 December 2009spin: 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_pr @@8@V@@ϲ@`@`@I@X@`@`@ͳ@@`@i@`@`@߱@!@@@`@!@H@T@`@`@`@`@`@`@@)@G@@`@@@+@:@g@@@ܳ@@=@@@@ @0@ʵ@@@nofilenamespin: 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%sunless@@@W@@ @W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@@@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@(@W@W@W@W@W@W@W@W@W@W@W@W@W@W@b@E@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@W@#@@@z@@@@@@@@@@@@J@b@@O@@]@@@ @]@@2@@@@@b@+@@@@7@@@@@@T@z@@@@(@@@g@@@E@O@ @l@@@@q@@2@l@@@#@@@-@@@@E@(@@@@%%%%Pages: (atend)%%%%PageOrder: Ascend%%%%DocumentData: Clean7Bit%%%%Orientation: Portrait%%%%DocumentNeededResources: font Courier-Bold%%%%EndComments%%%%BeginProlog50 dict begin/baseline 0 def/height 0 def/justify 0 def/lineLength 0 def/spacing 0 def/stipple 0 def/strings 0 def/xoffset 0 def/yoffset 0 def/ISOEncode { dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def currentdict end /Temporary exch definefont} bind def/AdjustColor { CL 2 lt { currentgray CL 0 eq { .5 lt {0} {1} ifelse } if setgray } if/DrawText { /stipple exch def /justify exch def /yoffset exch def /xoffset exch def /spacing exch def /strings exch def /lineLength 0 def strings { stringwidth pop dup lineLength gt {/lineLength exch def} {pop} ifelse newpath } forall 0 0 moveto (TXygqPZ) false charpath pathbbox dup /baseline exch def exch pop exch sub /height exch def pop newpath translate lineLength xoffset mul strings length 1 sub spacing mul height add yoffset mul translate justify lineLength mul baseline neg translate dup stringwidth pop justify neg mul 0 moveto stipple { gsave /char (X) def { char 0 3 -1 roll put currentpoint gsave char true charpath clip StippleText grestore char stringwidth translate moveto } forall grestore } {show} ifelse 0 spacing neg translate%%%%EndProlog%%%%BeginSetup/CL 2 def%%%%IncludeResource: font Courier-Bold%%%%EndSetupgsave /Courier-Bold findfont 8 scalefont ISOEncode setfont 0.000 0.000 0.000 setrgbcolor AdjustColor %d %d [ Spin Version 5.2.4 -- 2 December 2009 (%s -- %s -- MSC -- %d) ] 10 -0.5 0.5 0 false DrawText grestore %%%%Page: %d %d save 10 %d moveto %d %d lineto 10 %d lineto closepath clip newpath %f %f translate %f %f scale msc%s.pswcannot create file '%s'%%!PS-Adobe-2.0 %%%%Creator: %s --%%%%Title: MSC %s %%%%BoundingBox: 119 154 494 638 %s%d.trail%s.trailrcannot open trail file%%%%Trailer end %%%%Pages: %d %%%%EOF spin: wrote %d pages into '%s.ps' %d %d moveto %d setlinewidth 0 setlinecap 1 setlinejoin %f %f %f setrgbcolor AdjustColor stroke grestore closepath fill /Courier-Bold findfont 6 scalefont (%d) ] 10 -0.5 0.5 0 1 setlinewidth 0 setlinecap 1 setlinejoin 0.92 0.92 0.92 setrgbcolor AdjustColor stroke %d:%250s (%s) ] 10 -0.5 0.5 0 showpage restore max length of %d steps exceeded - ps file truncated max nr of %d steps exceeded abortingMSC: Y@?>,@?Ctoo many queues (%s)too many channel typesError: sending to an uninitialized chanSTDINinvalid use of STDINError: receiving from an uninitialized chan %s type-clash in %s, (%s<-> %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 statement#AAAAHAAAAunexpected: loose endsduplicate `else'cannot happen - if_seqdubious use of 'else' combined with i/o,AAAAAAAAjAunexpected 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 takenassignment%s: assertion violatedspin: text of failed assertion: assert(spin: bad node type %d (run) spin: trail file doesn't match spec?aborting1lAsAsAsA&mAmAsAsAsAlAmAsAlAsAlAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAoA sAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsA pAsAsAsAsAsAsAsAsAsAsAsAmAsAsAsAsAbqAsAsAsAsAsAsAsAsAsAsAsAsAoAoALqA;qAsAsAsAsAsAsAsAsAmAsAglAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsrAwqAqAqAsA,rAsAsAqA#pApApApAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAqApAsAsAsAsAsAsAsAsA4pAEpA^pAwpA"lAsAsApAsAsAsAsAsAsAsAqAsAsAsAsAnAoAnAnA'nASnAWmAmA{oAQoAsAsAsANlA %too few print args %s%c%d%o%u%xbad print cmd: '%s'printf string too longvA7vAXvAwAwAwAwAwAwAwAwAwAvAwAwAwAwAwAvAwAwAvAused: 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)#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/((double) 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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 (ot == EVENT_TRACE) boq = -1;#define continue { boq = oboq; return 0; }#define continue return 0#ifdef SEPARATE#include FORWARD_MOVESP999: if (ot == 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) for ALL_PResume: /* pick up here if preselect fails */ 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)) Cholds++; From = To = II; /* the process preselected */#ifdef NIBIS t->om = 0; trpt->tau |= 32; /* preselect marker */ printf("%%3d: proc %%d Pre", depth, II); printf("Selected (om=%%d, tau=%%d)\n", t->om, trpt->tau); printf("%%3d: proc %%d PreSelected (tau=%%d)\n", depth, II, trpt->tau); 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: P_RAND r_switch p_skip=%%d p_left=%%d\n", depth, trpt->p_skip, trpt->p_left); /* Main Expansion Loop over Processes */ if (trpt->p_skip >= 0) { trpt->p_skip--; /* skip random nr of procs */ printf("%%3d: 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("%%3d: P_RAND done at %%d\n", depth, II); break; /* done */ printf("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: BCS Bound II=%%d bcs=%%d pno=%%d [forced %%d]\n", continue; /* enforce bound */Veri0: /* 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("%%3d: 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) { eoi++; if (eoi > 0) printf("randomizer: suppressed, saw else\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 && 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("%%3d: up sched count to %%d\n", depth, (trpt+1)->sched_limit); { (trpt+1)->sched_limit = trpt->sched_limit; printf("%%3d: 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("%%3d: proc %%d exec %%d \n", depth, II, t->t_id); cpu_printf("%%3d: 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 (trpt->o_pm&128) /* fairness alg */ { now._cnt[now._a_t&1] = trpt->bup.oval; _n = 1; trpt->o_pm &= ~128; depth--; trpt--; printf("%%3d: 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; if ((now._a_t&1) && depth <= A_depth) return; /* to checkcycles() */ 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("%%3d: 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 %%d: Claim reached state %%d (line %%d)\n", (int) 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("%%3d: P_RAND -- explore remainder\n", depth); goto r_switch; /* explore the remaining procs */ printf("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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("%%3d: 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 /* 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("%%3d: 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; goto Again; if (_n == 0 || ((trpt->tau&4) && (trpt->tau&2))) cpu_printf("%%3d: 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("%%3d: 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 */ 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();#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 (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 %%d, fh %%d, zh %%d, zn %%d - ", Fa, Fh, Zh, Zn); printf("check %%d holds %%d\n", Ccheck, Cholds); printf("stack stats: puts %%d, probes %%d, zaps %%d\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; 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]); break; 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("%%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); 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: %%s (at depth %%ld)\n", str, printf("pan: %%s (at depth %%ld)\n", 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("%%d: 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("%%d: 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 #if defined(BITSTATE) && NCORE>1 /* seen this happen, likely harmless, but not yet understood */ 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; 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 */ { Trans *T4; 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) { 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 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 *T4 = (Trans *) 0; T1 = (Trans *) 0; T2 = (Trans *) 0; T3 = (Trans *) 0; for (T0 = trans[n][i]; T0; T0 = T4) { T4 = T0->nxt; if (strcmp(T0->tp, "else") == 0) { T3 = T0; T0->nxt = (Trans *) 0; } else { T0->nxt = T1; if (!T1) { T2 = T0; } T1 = T0; if (T2 && T3) { T2->nxt = T3; } trans[n][i] = T1; /* reversed -- else at end */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) { 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; inse