From c9276407e6d70100824881c5bf457010b28ee052 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 30 Dec 2016 10:26:59 -0800 Subject: [PATCH] TIMER: Timing corrections and enhancements - Add support to query remaining usecs on pending events. - Generalized the sim_interval adjustment in sim_idle to allow more than a single decrement. - More overhead reduction when idling. - Carry usec values as double through out to fully support long wall clock delays. --- doc/simh.doc | Bin 247296 -> 249856 bytes scp.c | 46 ++++++++++++++--- scp.h | 7 ++- sim_timer.c | 140 +++++++++++++++++++++++++++++++++++---------------- sim_timer.h | 6 +-- sim_tmxr.c | 8 +-- 6 files changed, 150 insertions(+), 57 deletions(-) diff --git a/doc/simh.doc b/doc/simh.doc index 506803a0d04c99fce5b1bdf40ef1c5a529eef54f..c890c4f4aca40051e91244e9b9057b20985a115c 100644 GIT binary patch delta 32196 zcmb{52S5{9*y#PqL{JnIRFGotT|lI`Yr(o}Z@cQ+dl!3KHEUlLYt*ssy7t}`#oon^ z1q=4BC}78a|4)(u1oeCG`(5HMnUc($^PDqh&XmNzLNoofFw<1;;L{j7tpD)$Ho(H0GRYzKrpz5~$U0E>?dunD^V|Fn3p%sqQ9o zR%5l=JBKTZ%3^l&Du4ge*GeN4Wg8z%7^NsHY@c&A*H^Qc!;KZy-NVfvjs6ABu~0W= zma51Te<@!Z`Y1|vbK^AmGD|X&|COppLj6n18{{wbZ0mGc;0vRoOc|^w7gTMUQLSOR zG|W10dO_iFt!u)a-En&-3*NdnI@sAo=pCC@+G*GZpL z0)(KTYKcTabJ29}Qe+?P_oxd;Z{C%*pQ@Jj-t3z`#x7lecc7oYe;IFc0q27Hh>y9U zb1{9y*F4s_gg#Q*ywka`KH_JNaW1ZplriUW@zqEC%}rg(=pzBGo|XLid{ zM4wZ}Ts=!k{j>hI&-$CkWJ!E`fO%_{#8m~FA7?3~e>TYMp7m$jNPxGwc~(8=0Y2tw zS@q8Z_?i!AEvvt+v^lM7;)tL5S64l=0cFf4*K+#X{LP146PFfXe&?!(At2CP#w~Ht zLFO)QMQy1M^tPtnx3qb&o1Vr%AM-gky>tS7&34)J^#ztT|CG(!w!T0=bKh+GQUlAF zmuJ&UC(z$~J6kFJZ2@L?_oDhppt**7MSUd5JUwwvkhl4eduiL8ARqG=cOQMk*Bt1P zIH$C^uZO;#AV2e3kMjE4%9vkzB!0%9`ipU$chUa6`t>QE zyM0Liw%t2yE*w%tHQR?|^la6pZQoYke2=+s$nnj&d;6+c+O+G}Wk8#L9a{D4(xXGG z{(U>N>ucWIr-=K&Hr>1DZr44eUANpaCwG^gxh*p{Kkc(QW9BYB`!Ts)w^r>twCmHM zM~9yMHm@6z+mP|=X`}9r47)qhkaL7qF;=~mE**^#d^LwO>IUPS3RSgzPO3*P29)2@ z8G8Jpr0I$N=?qF~*UmE4O`f&#E^1+W7wd3dJ9V>sGVHRQ`bquPM++tY=wvT7yXNem zX8P7U3nYJMc?Y$~x89U0CED41s)Hr*&Q7YEcGf|4@c2d!tmzGV;h=gM^>^pe2izRH z(eT@+Ggvbv3o0DT4oRPqG92H`lf7f_WFN7F@<$1AQnMM7)_=_|X>FQi{jHKs`Jb&{ zo1DoO2`NUO?*>6hRtm?`m(yA<$&=)1 z>?-@Vq@r+)vQG+5SiFmxD_P)z(a%GNKLX9hit$9qas`5l(eR>_-v|2;zsA@n9U_=o;65w>5C?&tDe`l)0MKcawSU_ zt%av{*6T-`zV^aPeg5@Fa%+w`lD8ct8T(d5JY73)uIgqB!S6Z#XUY4Y#mOaeQqIHT zbEuh;RqZeI7!#vnX%j{!o076kNV)wLcKoU!B|`tBlCw*;4lO=c@(R@}Tgn8zq(`nN zF=c{MmY1dBx7T{+`F4>1cd32nnv?)7K9Bk#MF|&f?~(L|lqpOZvXYJu-ILyJshV0S zdzWw3iPX81{m_pZ{Cr=v6ivKRuBldm~j(INcw^WdMZkBlt)F>3sICN=!uEF6eSchdTBY!sJ@N1 zuKH)@s>oxJtG3D>!M3X?lWs)a8mdws*^>1blw{MhCZDdqS;=T^!+Mobrx?m^^H&R} zD=90l4_WCX9Ph0tC(yEwqO^ibUq#7`4cORMGn7z^Xr(I9)&$m8oixV`JU#iFr()w( zCqvY%4627^-0PI2SN}V#56J62t#<{rwzjZ5pSo2-buqVA(`u(Gs17yRt)wrgWT=)` z>C|3YT!jglMxRw%!a7BNM?U=>X-e3J^f_s*#F9Hj+0N@3bnB-meefqP;Wp~`SCnR0gWYH_fG8mXkr*=}&Y}i!s);37D#OI7RF>r2tHHD zaDa0wZrb+BYDJS#p_^%`c4;lAg7k`%C$Wkt3`qp_Ia0-BTyc}q(NlYx;mdf6=ScG> zrHD+(MJ{qf&ruPE%c9ay#iUecU_55x0kV=^H{^pie9!`IF$=S?659}ucWBF5l@Pqd zd*r6-6+j{Qq8+B;A1uK}>_DU`SW%q+QWP_;;q|lo*Da4{=k7l{y7TBW9vki-y?^xC zl4tkln=Oxt^OGLe=TDT=RNA64JPoU=2DnjymU+FV0ro(^{`kjr7z)ZM21+=Cce(A{KGTL^Aax&tUj8=gux73d=@vrU@lEdsJ$)7FklQ zr>%WJHONs;ZKk!>Xt%x;WOR2a)lXadyUZw|7P8hThMcsRAk{&8QeAa1QQApuk8Dkr z^Mqa!r2F`QG_27Pp6H5h&{H#?R4l-MWSvO!1`lKo<@91ak4Fjd_pY7i zae~JI%h0xKt9V^BXVGMg9X7WAqB+K4a~5fT{Hk`<9{j4hXQV~B*`_?DD$o8}co{Xj zJ&gimmS#kIdO}U7m90u8=uwq0)~KpxYF4roN$zJ$dML@B1WEQsNRr1UOYU%zXTmeY zqU9u75&SWknt=AmF_lJCOq2akcJ0j1`hIA_ZdQ7-p6cWkr6l`1oorY+tnI7E_Adoq zcwh1v-yhkdZ7ii$)}ED9GZ;Lz=$dMNZDw_q3Toi@z5Rw3@{<48{2+_EPZbYU#92Yn$iWA}Sfad}&cLjBz z=3Ij6(`%_T0@6Cv9&8;7woQ}ffc}Y-wxOn)&g5?0O&Bv&GbHXXXd(<`+RKxLR>v>s zMC?1GEV2Iy4TyO|jKXN>@or{|bqij5peM2~A(u$AR8j0u6vgn7ec<`BYBnuLLy~j7 ztfccBLzebzehucbC3qSxNqsM9IHN_Dr3}vAV*2-<%%|+KXb0-6KTE5ZzMv(Oo!alo zd?PWd=`C3`(qSz~_d+U(p78pM*;sLdgx-PsG9rQw=z_WU55KRVa-r8MMHzq*Sb)U{ z!)_ci@pKyJa2YT09-ra9nmU5KsDxip8=cn@K^(skeK828$vjQR2JFCTL?R9eaN0nZ7^M(^rf7wwc=!6*y=T{+orgTmync3s345Mx zd$w+m?cY6lz4z5a-lMyxK2x;FI_k2JDpKywge}W*nsKno|T%l@Taey&eoE86UtML(rU1EuBF%i z|L5tzfoYf0E;7%0Y)Xoew}gClr{A{1dA48%G_AtR;a zg3R!S6tNVql&F-Vl$?~Bl-ON6p1N(+A~&e3wc3Sf4i^5dPSN&EBzdQItM=NhFg24F z-I(S}-o9Esf=8B5(ZFw1lug)<7`#BaO^Q+l(=ZEBxQd*c6(v7g8GhRpB?ybK9EWin z#di=REWl!{!A2zDGmPOJhlRILl+6rm$C{mN8rXwFSiehAwxIAn0*((zyPp~hUo<>G ze-6vB9%pbKw{ag&4=7rNIcknf4`SaWd)(3Tgs9oF-my%Q=R2`ic)r3z%UxB?k>T$Q zjr1LecD0#WuxmHMFU286A;lm?AmNwLOV}mk5^f2#gjqr>QI&{FG$oP`ZIP5HhC(8_ zpC}!`Y@#s-uXad3t>WkYJXyLQKR1=#iS5Zrb4tsMCqZg@?O0Pa(DaHAb|88k zlSMF`=(!R(H+aJb9T1B1Fzn_e0ZiD4C|p9zJv2I)jNOPq_PuP+s0Y0y-YbcJ+Uc^? zWXrbQvNU~Pj^3&4UvKLF4@X%CnQx(HP29lUNutyaALuosG_|89HJ}#S(0^!)l7|%K zXOzQMY(vJw^u=)kmvIFRkI)uk8^X}-D7^rTL!)Dg@*B1vQ#7@N>ZSebPnMm#ktXMc zHG-~_JY zHewKmH~0uWYkSDj3Ct!N^Py*}8QJKBIY-#s|6^bSwm{EYbMn*;gD@QbVJS9Y8_2J6 z2#q7CM;L)IIE^c~fyZcaoF)^)P~imgPEn~b%VutUW~{Vjdrx|cZ1s_MB6*v% z0oFD_=E}JK(5A-FMGC6Rj%>$F)m2LX;c>PcYglJR;NhriL7%u669VkS=G zI-Vg8@o*tHc~A}#sER0jlKl?!puHw=n~2e7Y_!BeYtxvMWD9pmb=yoOTib-8+B?{L z4(qNTb`I;q(B$wKYj{NdmGLX%wfM>LqoR0P33*j)f1C(;n`yM7?H$Ld zrt4GG3|eRxwYXNYjoLulGfvH`{ndtAdgdTSoz?N9zAICFr5LhYqFB%hlW`JGWG@EBcmS7&t(-kHMN{8V<6)6|a$i0&l6MXpb(KiTOBy zV|apC*eB3xqYTQTCEDU&EXQ{2#sTc1+8%hNP@~BN5sFs$~)I?mnT1U;H{WOeXn>&L2Zrv_) zwq}OV&YX@=^P244I(KQ5MkzO$tWU#qY=DGCLL%XiP)Hag1d@Hpx@23jEZLQ;?m+Di z^uCp%U*Xfc1Pt|9W~FHnf*WMU_=ykU!Da|eUc0;AF!l+oCmfdo4eUlc|W48<@k zz(0tFyOTj_iLqFUN63=Vpaf?$X!UQaWs;vm{>JG-%Q*zj8FHP?oqD`So-8NUYum2e z`e~&mawNo)llE9nVm~mc9;P&MjrFGC5BBbsLZl!+A&3l=M=*XtZPbTk&YetoKr;9a zd&r<DUU>4xXC1P%AMV^YI^6!I+tC8dPr53p!ll&3>DE!g3gOAoSap|K4mWO4wHe>`PMAK%c<*ch_*59Qg!IVq_y?8 z)~i`);f|QtG8Io*$bXPnN*pDG!7yPS=HnwiA$>N3k_)*p1yeBxtFRiXJLQaA$c=#* zggKatl~{$uO;h`DNX;odLqDxzU)d;2st4r&#L{ocpgruy6=WLs>{6zZsG5+3jm2Ut z!)mNYArep=J_x`@Y)3&>SOSuOe;^51jqV->r5A=`H2%hBgyAhdA+M*wq!jivC~L6} zTM&*5xQcstf)ic_Eg<38MSvJ>#i zNrl1??8bgvz!iAqB9&-?HV8p)gyyE9$7&?RrFg_Vj7zwY5EYjYm2jHJ5oVuG@s`Ao zc%+)av94QZPg6hX3slh7k5IE}5!Y4E&UN(2t|oG85ROZDgFFPO7KUO4&f^0<;|q=x zFbSdrPJ$)@lVC}p^dL1LAPsXEv}q;O!ik5owquIgauSGJsJMIcZ+h*PE~f3aCxJaxR{z92(CR0@e&U&U3fR@spXCt5a<@%ZdbYBz zO}6#Dv#wJK%tNI@H_XC3Y(Y2<;V|wa262c-a9;Kg7>$YOn$Mv0gc-9VKG)?BOc=!67U{%i&1m18~fo{oJ`;y>`G|m=ct8!A6PDpL|RUb z>L)|3mrEjIWvc$*7+E%em|=Hh1Mrl~@@eJ7RCeuR8?|Wnx|Fyj@)C84^mDvG2_jk& zjWG$2(1~CU$3E=GCwxXBg8C=cU@!Jzsx6>PdA$M0LI!Pr19ntNeOuc3I>|;Y7gbU` zCA~SR=eviC_m8K^-K3^zkxf;%o}R2tDGonKkp@C9*5eE>r8t*CFPYbr zP6(0jg^ENu*cRXdc zG<`J1+!Ujh?T#bp@$A}TTd=5u)6}d+8g1?DPpYfQQ%|Fj^rVNRGY9fRPjAOklpqG< zFN9(nR(rEO;xin5*rt5h!J|ETVlh@Dur#qjeYC_od_hJ(6V=m?Jw7I3AsoxFO`#6j z;4n_(3exz~(BNmZMi(r^R^$yZC`C~RzoR|6qCft`94x>d9KbQ0H1QOJIM@fWfx;L5 z7=YopjmIzsv7Nn&dzJ7Y;nfX!z9BIbiPYV|O%) z-O*RmY+)5k)pn7Gx zv9PZ~okR@caIPvxj+j`@pv=S#+(WbKECc6%p&xELHFJm4Ir6AxIjdtEkqN0!=lp+9 z`S?m(6`@uuW;=KDyHu7VFcF2nFb-2O4YRSde2N~JlVO6^yN_B>yA{dVmx^=MAzFcX z>XqE~oUqMr__ZT}x1NGa$48ZASc`q-!!piSUl=m(V`M*$A)1ME)$9hX=)Y=I#%QKo z!wuYG&O+W^^%f(yaYqo}yO>CPL$M6Yu@{%{60b0axJ&#aiLbOU&hV;6{C_354?Ljy{`0fF>a%Y-dlqP8}eq=02LPAuNtwweT9KOsA-$zxlk zzPi_}&b}5q3AiIS3L-zNFN}I)^4GXXm>v0{o;Y2cB>TsOn%78l>p$VF!HKt+_ zMv;%1ScP3kz(*+L%N}J>9+KCV=!N>^wH*dw0uJIRP9PF?#KFN5i`Mjx7^sED@NY=K z&(Ft=NH{;qkf|;zLqR^u|>B3Bc3y~u~T zn1^&tQ#8XLw1xhvBUgq!6R!x@3H!1_H5g2i@77p}_1K4lxQu9YCtU+Eo;1zHSzLym z#^R*WAB{*$bM!(#OvE%K;4>DHt_|3YgSd}JO{fiNNNid>ZBA`(!J%|ZgR%qX@Uj(! zg7XyGHF&n6#vol=`Y5Q5U+@Q7;WVO=u^jBIx`&+coTcy@{lu<_hWC{&Q3}%U2bo>&-3lrle;aGWv0AYf0j2`hqrQZMSAl! zf3J{u0!PX2)>(^KOV4`hLA9tBznoSrCYYOWs!IVnpci`EV&h3{BtEl=%N%$R2Z={1 zTTGhrY9Q|_j^Y?5llLiDft5H7`}V{P<1iQ3k+nne3Zu<0L2|gDQb(i3u-)z8yjqP9 zk@wX=O`OCj3?^Jdu%A#Jz=JMSZ2Z=hejpsWu~&r;d@-{JJ5S{3X;5;aIDW%0EW|}P zgcy{nAslwJSDR}U!#KU9Uo7T|vF-A*liZKd$0Q|m2@b3>6AHr*zoI5;;XWiedvOvs z5re0AjpRxEMA8f-!3~~x($Ap8B5QvdEi^+Lgkoxc>hBH)_TxSt;~hT1X#mX~0`L=h zqd%r$Cc>}_*Kr3gkpRzuY}5!wH8epBnD93iVJWs@$G~86&%jmW9Yni~vM3L~Kk0p- zF`8jIINeT#ydHZo_F}}v{fOPI_1>xmq?cW%b;qn#T&tGVhIHY4ytGn-WA%%*J`7?L%p!6+#h)+fe%&lwxRrkvIlBLS6;d zE2r9!O=_MnZgy}nXd5=F^-MBr6b>T-$MFb{k%izF#~+x8?YM^oI1*rg^uknZ!!^8s z2QjRO#uyF>v;;W{Pmy#HSJ6&&cP)_#M-57SGXTDC-%TqN`*{64#~VTqn0! zaCP~25_cv{^)X2`n2ktWge)TgvYZ~)Whu{jbsI+eiH_)rt=Nq>NHd%r4vL`}I^#Sp z;TrCOTR0R)cpx|WW2lJ@<_rVp;rEfzc!f9k4A-$VA!v*? z=#J52EhlueeOtNp_~)H;Os7V$!R+3tRx&l9NGu_g@JZ+-Y!WgF*G6o@W^BP$6eZ`y zFb&gjj|kjHCvw{vpOfW054m22)vzZsX_4&eB$q0+vkmypX3`l7>-P`j1fYI4Ch5xM zzHajQ{*Z|2fssIrM*`lVDH;9)AMg=d$FX&w=-;FpTd)=F#&hTomkIP3(E~kk1V<-O zO(Qv{DmT%EvH8#&9nG>P;0TW6F=Fro#J4&$)`n;~i0jbm^p9iGUK z!th09jK$wrhD{*NCS?}`2hoj0_eC}mnhPc2ho)$bzA#}TrePa)-~bNcB(C5-VvuPf z0e}~BAU6uY8~rg5(GII;lH(nD6W?lk<5_u=z7Tn=14&SMz9t z*Q(Cl8&H-?E>bDkl2l)XMyftcqJAJ`3e6o(PNkawCo|nL6q`Zoj8>SBXk5d9nS=yu zXR#we6^$JTYRQo8=B6b;|hUPWJYg{#8w={13ZNfIWL2Xs04{bEi}V$jMk_)FBy0Xbv7+B8lo-6U?QHwc@B*& zq{yujELA{CSZJW7*@nNkr5wM<|JjN58AW0{&VJ@v9Jm<5aAR5;YzJSAB?826R zhz~9z3Ud~+y};!^VhCT9Mz%$4`S=GZPePScCrihXn+~P-$ex;g<6(85Nka1q+eyP2 zdGqA9<#FZ7SsuqMkJ}90eqx=H z`qjfaLq2F7I{QQpl9mr0to7|e2RfrW`eP7g zU^b593XJR7z)%_0P!Dae1lI2v+~+VxhOS(=a>n-fYFLiKZST|upHW?$^$FJ3`?1nn zD=l}ddTCG3bJR_NDhF^7zp$EL;j)1?279p&8#WR@{IQ9)7}YoPUNqgpG_2jq-U~y* zxaffiJ7|jG9L}~qd2jNLc74g6}XYZ9H@)- zID+FikIQf+=h;yUP0$8|@DgvK5D`06!mk*FQP_$jsJ)Fu;19G!H}o>`v;jNu0-sTm zkp7G=7>tpai89;CEh?cJ8lnkiV==Dc0o*8x{HTvMn2!H&0#a9!R}rVLCTP9SP)|ml zQS)+}r=sn@&i?J`8ETDu^bFi7)gtJQUbu}ocu>MQPzV7Sg5lVJJ$Qu#`0Sz~$5hO~ zYuN3k7l8^Gg_*dAM`*N%0^7r;J)ePvSb|k}0pnh(E%Ks224fgT;RLQB%Rc6#JSt%Z zmf|XIpvit3d5pjqMBpOc;S+Klpfh)%C$)lshUkT%ScoNL71)W4CuxrsQUY47^J-v~=Rh4~bb zK4l1-R#LU21>q{Y+?V2H9iq$Zr|}J5ACoLX-u?w?_=p=Sp&@LGQ0APaTaHy&hiZ}Z zc+n1BkmnqI6qJN7W??Cg;5eS(J+hpq>Z2YSVc>bH>YogZ!7OaY4(!2G#KZLhfkz&c zMlCeJL`=ah?89+fhjNjI4BqfVQ#3;hbU;6(jiRvO9%W*`%0Ok*LLJn_@92aqmsmOS z!ykN6LLPT5&v6fs63@o0h5XP z6x_jG3?rb!;X$B0aR3J)!D$IS|I^8<8KIZi5+Ge?ZB|Kjc;cDXk#f<%(x+)-lE}0~ zC+MG?%kWAJ=hG9QFKGtDOVR!c+Y!28AQoXAuHY(eBOdv#5`7dyc`U#NI7icKLQphy zs2l?$FbgqIuhG2WFN9(PwjctLxPeb_yv{ZRZ}{MMG)D;f-e8-;7_7kt9E96Vb_;lm z^tY%-x2Qu=cW8hy;sG&7&_j+b@$v1)xQ|Z~pWoVsWSTtQTAt%>$6b~ww;4!!oQ?Y! zcjUm49h;9xRk8e~ck4WBfQwSOhC4T)TZg$7p|UpYy4u*3bi74pS?+^RyhYSD$9ilg zbE-;_>Veh+Jd>c#LOSB-fWa7oySRrz#7kl-F+7fskQmk{CJk;FvMaqA=mQCyE5VUK z6+`2jmOinUoOrZ+t&9F|Np2tJs4M9Uz0I`AE17#HTJ>qi2b56k!b^M|Z7L*DpNw!s z<1>P86L6ftSzM$r^g?;eaP&QPa416I6n$WjnRa=9&R$}P3G z!6cQW8f0Cv9$AMwDzWT3wspvIud}?z_yU)w1Q&%N%Xh-$Sk@0ScE_=QMI7Sc98Vfh z1y%72dZT|lo6g@1jK>6gLEGmvt(byESd1lDij8o4LAM2y@edXu9CcqyP^^!ek0ULQ z0~;Q54fG$|l~AsSPJ3**C_3%&D9gk2SgUqdZL96Nt5(voUst^inYG?``Te1FG2Bn? zOT3hu$V{Fpqd!JL&+BG}cixn%Xh~7?1N$=c{KR{3 zM^X7ogQ~p2TVzsI#TgMej^}VUs)`3zrjhq0`+K8=nI5Sl3?|8ltW{rQ&_@D^mIy&8 zG#o}G%CqL0P`}W`3fAliJtg6+^(a=c#?`Xcr;naqO?;eudXn+IPs8-2XhE@Roc2!) z*C5Zva1y}nuA1F}Lw;!w6{E|6Fbi3FDWd!wq3^&(xu6h5&xN zK2Y&f{P_{A(;19?G9{a!l;Jen^XF<$r>`bztzW6VQcU{qbIM7x(inTCSXdd$!ct81 z|JE8J-=tie=KV3%q~7+%uhZeLoz0M9t^VK2f`95P_-m=M;GZfB{+x1@czl%wiCn56 z`D>}N;Ga4R{#vRm1fMR7N%0l3`vJm*KECi;`LSX7F1g6eHQ0goMeJcw=sk0E2ItxLmvJhm; z!dIJLujgu?uQsco)X5J@o&2Db$!BA=BtO~01GL*O)jnTMX!+`^waJH4YynJ4k#K1S zQf&b;(YghEwfr-0QY}BlCM>H=QU9f?%O;#z7HVyln8bq~_r^@d7h!ud8oL?77CRgB zI~a0@9rG|=PiLqYwk)qP+$kOZeF-hA60ddkHr6u9FQv-QSzi0g`cr}O6JPS1NAhDQ z@{11IZR=NW<%@;#6)jgcjwEt(N}&Whq##b+{K9crL%MjK>Bs-cUS+KH0+O5%m$Q{} z?nzE<$T6ez`K9wB`vqygjT}($twVk*1T0%|Kzd|=qvo^C=q2AAQdp(pg*?cI0w{!{ zAQ^JQtm20N{EYGlMio>?4b(;>{Ent*f!1h?_UH(*pmafZ^h6(aMalr}v5zspw6QO- z7$(0iDZfJ~KPG4WjW+qYD)|8-`JEr{eb(P%kst7oUvrROQIK!1%Qwa4OV{#MX8EG2 ze7R7*!zbUnl5aD~*HGl^9daYSBN>xBgyn8qxv^31K-^cJPM6$Ucnfl~pWFi`xAw?w zG*v_B4fNyKccA6+z2zFNTvL-PC2}rX&PK{f4LOG(hk??Mm)^4UUZuArJrwCK$UaaC zB@G$3hZC|Q8{ApH;=zC?vV+7bIgtxg1|=`@qaX^S2#TRN$c$17-ta|flmQu30uh9= z_z7f~uTCmTMN~p%kYA;mGf%(ZSJXr;%_q$0W%x~tEN#pZ+?**b(F$$Q4unSOgs$j@ z9w1aoFZ4!V5H_Vh28QMEGrm z&W0%M=n{NA&*um8e19;n^bh9wnSL;{%n#=I|6pFg59S4?nAb*cWhD1ODP|_k^Z!9) z=wSTdbH3V*vc@7`h1p;Een|WY`}c}KlKB03-;apD67c;n`_syPf1%%xh}4bmeNI~J zujiSPLK&cZzp@1UATj|zhzxz26e~==J|biKPOT20j(?rfRb-Ik7__IpL6 zk7)>BBt1RY>W{JXf#$M1q`&v)dVb7hGkfms{L&Qtn3B8r<)Yo}Huv&NHi!B7m1F$k z(*<^=^l83aq91gHA9=Y;_kcc4U49hCgFeF}`fPLAOK+n~aF2e>JGui;3b1dbEAR^) zwJRkI^_18WT-BjJV5G;^jQ#w1_VYX0$2-zPdtaMA3_UbY`ZcAHo}IYd&0;>xNd!8M zQJiO7^n{ZMahzXFpzre0pnceA{G>IkWb`&oBx@JQnrKVbx|6lP$l64*ww$)>@FYXC>$!$=B|-ARk%lN!DJHwF_je1X;^ihqLFuaYBu3HHJ4?yFk`fk~Igq zV-LyN4zf0qti85o&2kQ-uOmGqzAt<9y(PQ+SWH?AnVG=%XEn&O7Oa))KL1;XgiX=F)ofGXmA}v zR}f?HHw*+i4c?8j{4}{q@d%}(j^$JN6%|}F^D}SwZ61{ktLF1dDJVwg*%!0^;}=x0 zpOQL?bGU?;cn9~zbTd&2zn};DU@~T48+PFa?k%Q|YQKaYH;TarZO{%=F&(?H7Z33m znU_+FQ31hdj@I}SBQO^WaTKTEu#AHf6h%q2Kr2kb6cbPDu^CZ_hRzAk=7zR#=MFxQj>Vwvr;lCTvFxUZC764sS3Gvk(Q-Ri1LLrYDXb=!;$02gfzk z7vw=fltWd>?*NZN1WvZd*7iz|bB1z|c6hF!LUM zV+q?i7&?TB2S_DmLc?|3Mc#unI2eD3(Bb+~e%T1F5!4}+IKjajp^zp#cybgJ{W*QIEJTq0auRZ zJW&Qep%MPTFpR>#CZ3k!5RTy$-XqU7Qi$@X4Eepn7sz^@8jj{@jaitFV>k=L4UURY z1vM}NV{il~a0R#V9B*K9yGdJ&@tA?zxQC**sI3@?!5EK;n1=;ei}l!x14wh5HU%B; zQjahni&5nsn;~MJvQoUmXLvrN-aVuIgBYlQCTNL)7>0ka1P5>wPY@6HSU!jVl*2~I z7hGN=0R`enJldlRW?~)=;3%FT7WVN}@OTqt!$4WIL|goe88Lh9~(w z7CCM&0YCJ^pV*3UJi=47;JCgGLfyGd5Ap*eoA3hfP}+lA^w1GqF$;5X7)Nl0(*V(! z#A$#jn3t2C;J*wk$6DON1ITYt6h%q+pa6T&B3O>qaHOLkKhH3SJ?a9;uLZ1z{9?d8 zxNt%w3mTv)TA($?Ar!6H1GmF(#Z1gB#*E^G32A(}XpcvTL1#`n^uQd<$4achPVB=c z$VrJH$oJBp;2F9FvPZ`zY{jG?>H}QMQsy|vNsDN>n}X@RpfqPL%0Rv_n+{p4F%yfh z1id(s(Fcv`8Z<@Sn$#H#ti{z*jIPby%eKBj$G@8d}FNy)4U;gvv!RZ%o`EfhLNq=>?ZPcS$dBrf?@@)IA1>euT6g7Y7D7?&qph>Et-dij zO&;m<$e;9e#43HZlE%^(%CB8(Z0sEno2!Z4@g<*|e94sZ;jB!rvcdjVv5f0e&iRtb zS*z8=_***HN-Z+(>GtYe*rX=L3kI)#b!Rkvk>ka#Z@fRO^&iIN>B0(+Fb-Dbd7Bzm zrJeC~8m-qTqrG-5#8^D6=LlnIRbyUOEoT>_eVBV^V{I3Mvvzi*(LMP)p7b|*h7BKV z?BZm|ANFXh(Wv@KIxLyBJxRiok4q+#k4r+en|~W8PwVAu$S?n0a!uoxFZs3b@kSrb zWrDG|c6hw8pbV8XN7%W^SV_xM^^z+*9_@?S{}nP8lhLry5u8@DV*p1)L7oo&lp{V^>6MB{X|^xfyR zmOq)SO*$nTxba6$0ZTzT&oic+Ixp<;Bx5T>+7%z@eSeVual2et=oDiw zgTs6lE^*1P*-bN!%9LAiRPrD%^2urAx$5C<(~Uh027j%m*;vT#atvQf*XEjyxpF>n z`9=QoYF5U&`2|HtTI7}VgwDYxly8fsTJOHeR1nc)RhH=@?@XIF1uI33>l%UeDkxB5@AqaRD+vidT+zl*_n+ ztBA%m$ox+!++q4%+dP^7z&fmr+hOc5E8N)K;jd~+E6MeJt$(=DWEiZy=EZ&jZ~K|w zyxYm7c^=@NO#;+F^_F}iOy0o04&n>)Bpeg delta 32559 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 Kjk;)@qW(YAHKUIJ diff --git a/scp.c b/scp.c index 6d4c5aa1..e3cc6378 100644 --- a/scp.c +++ b/scp.c @@ -8927,7 +8927,7 @@ do { sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Processing Event for %s\n", sim_uname (uptr)); AIO_EVENT_BEGIN(uptr); if (uptr->usecs_remaining) - reason = sim_timer_activate_after_d (uptr, uptr->usecs_remaining); + reason = sim_timer_activate_after (uptr, uptr->usecs_remaining); else { if (uptr->action != NULL) reason = uptr->action (uptr); @@ -9058,23 +9058,33 @@ t_stat sim_activate_after_abs (UNIT *uptr, uint32 event_time) return _sim_activate_after_abs (uptr, event_time); } -t_stat _sim_activate_after_abs (UNIT *uptr, uint32 event_time) +t_stat sim_activate_after_abs_d (UNIT *uptr, double event_time) { -AIO_ACTIVATE (_sim_activate_after_abs, uptr, event_time); +return _sim_activate_after_abs (uptr, event_time); +} + +t_stat _sim_activate_after_abs (UNIT *uptr, double event_time) +{ +AIO_VALIDATE; /* Can't call asynchronously */ sim_cancel (uptr); return _sim_activate_after (uptr, event_time); } t_stat sim_activate_after (UNIT *uptr, uint32 usec_delay) { +return _sim_activate_after (uptr, (double)usec_delay); +} + +t_stat sim_activate_after_d (UNIT *uptr, double usec_delay) +{ return _sim_activate_after (uptr, usec_delay); } -t_stat _sim_activate_after (UNIT *uptr, uint32 usec_delay) +t_stat _sim_activate_after (UNIT *uptr, double usec_delay) { +AIO_VALIDATE; /* Can't call asynchronously */ if (sim_is_active (uptr)) /* already active? */ return SCPE_OK; -AIO_ACTIVATE (_sim_activate_after, uptr, usec_delay); return sim_timer_activate_after (uptr, usec_delay); } @@ -9176,11 +9186,35 @@ for (cptr = sim_clock_queue; cptr != QUEUE_LIST_END; cptr = cptr->next) { else accum = accum + cptr->time; if (cptr == uptr) - return accum + 1; + return accum + 1 + (int32)((uptr->usecs_remaining * sim_timer_inst_per_sec ()) / 1000000.0); } return 0; } +double sim_activate_time_usecs (UNIT *uptr) +{ +UNIT *cptr; +int32 accum; +double result; + +AIO_VALIDATE; +result = sim_timer_activate_time_usecs (uptr); +if (result >= 0) + return result; +accum = 0; +for (cptr = sim_clock_queue; cptr != QUEUE_LIST_END; cptr = cptr->next) { + if (cptr == sim_clock_queue) { + if (sim_interval > 0) + accum = accum + sim_interval; + } + else + accum = accum + cptr->time; + if (cptr == uptr) + return 1.0 + uptr->usecs_remaining + ((1000000.0 * accum) / sim_timer_inst_per_sec ()); + } +return 0.0; +} + /* sim_gtime - return global time sim_grtime - return global time with rollover diff --git a/scp.h b/scp.h index 3d1041a0..9f8ecadf 100644 --- a/scp.h +++ b/scp.h @@ -122,12 +122,15 @@ t_stat _sim_activate (UNIT *uptr, int32 interval); t_stat sim_activate_abs (UNIT *uptr, int32 interval); t_stat sim_activate_notbefore (UNIT *uptr, int32 rtime); t_stat sim_activate_after (UNIT *uptr, uint32 usecs_walltime); -t_stat _sim_activate_after (UNIT *uptr, uint32 usecs_walltime); +t_stat sim_activate_after_d (UNIT *uptr, double usecs_walltime); +t_stat _sim_activate_after (UNIT *uptr, double usecs_walltime); t_stat sim_activate_after_abs (UNIT *uptr, uint32 usecs_walltime); -t_stat _sim_activate_after_abs (UNIT *uptr, uint32 usecs_walltime); +t_stat sim_activate_after_abs_d (UNIT *uptr, double usecs_walltime); +t_stat _sim_activate_after_abs (UNIT *uptr, double usecs_walltime); t_stat sim_cancel (UNIT *uptr); t_bool sim_is_active (UNIT *uptr); int32 sim_activate_time (UNIT *uptr); +double sim_activate_time_usecs (UNIT *uptr); t_stat sim_run_boot_prep (int32 flag); double sim_gtime (void); uint32 sim_grtime (void); diff --git a/sim_timer.c b/sim_timer.c index a48fd0fe..d205c108 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -748,6 +748,7 @@ static uint32 rtc_clock_time_idled_last[SIM_NTIMERS+1] = { 0 };/* total time idl static uint32 rtc_clock_calib_skip_idle[SIM_NTIMERS+1] = { 0 };/* Calibrations skipped due to idling */ static uint32 rtc_clock_calib_gap2big[SIM_NTIMERS+1] = { 0 };/* Calibrations skipped Gap Too Big */ static uint32 rtc_clock_calib_backwards[SIM_NTIMERS+1] = { 0 };/* Calibrations skipped Clock Running Backwards */ +static uint32 sim_idle_cyc_ms = 0; /* Cycles per millisecond while not idling */ UNIT sim_timer_units[SIM_NTIMERS+1]; /* Clock assist units */ /* one for each timer and one for an internal */ @@ -869,8 +870,8 @@ if (rtc_hz[tmr] != ticksper) { /* changing tick rate? * rtc_hz[tmr] = ticksper; _rtcn_configure_calibrated_clock (tmr); if (ticksper != 0) { - rtc_clock_tick_size[tmr] = 1.0/ticksper; - rtc_currd[tmr] = (int32)(sim_timer_inst_per_sec()/ticksper); + rtc_clock_tick_size[tmr] = 1.0 / ticksper; + rtc_currd[tmr] = (int32)(sim_timer_inst_per_sec () / ticksper); } } if (ticksper == 0) { /* running? */ @@ -946,6 +947,8 @@ if (last_idle_pct > (100 - sim_idle_calib_pct)) { return rtc_currd[tmr]; /* avoid calibrating idle checks */ } new_gtime = sim_gtime(); +if ((last_idle_pct == 0) && (delta_rtime != 0)) + sim_idle_cyc_ms = (uint32)((new_gtime - rtc_gtime[tmr]) / delta_rtime); if (sim_asynch_timer) { /* An asynchronous clock, merely needs to divide the number of */ /* instructions actually executed by the clock rate. */ @@ -967,8 +970,9 @@ rtc_gtime[tmr] = new_gtime; /* save instruction time /* instructions which was returned the last time it was called. */ if (delta_rtime == 0) /* gap too small? */ rtc_based[tmr] = rtc_based[tmr] * ticksper; /* slew wide */ -else rtc_based[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) / - ((double) delta_rtime)); /* new base rate */ +else + rtc_based[tmr] = (int32) (((double) rtc_based[tmr] * (double) rtc_nxintv[tmr]) / + ((double) delta_rtime));/* new base rate */ delta_vtime = rtc_vtime[tmr] - rtc_rtime[tmr]; /* gap */ if (delta_vtime > SIM_TMAX) /* limit gap */ delta_vtime = SIM_TMAX; @@ -1119,7 +1123,9 @@ for (tmr=clocks=0; tmr<=SIM_NTIMERS; ++tmr) { } fprintf (st, " Current Insts Per Tick: %s\n", sim_fmt_numeric ((double)rtc_currd[tmr])); fprintf (st, " Initializations: %d\n", rtc_calib_initializations[tmr]); - fprintf (st, " Total Ticks: %s\n", sim_fmt_numeric ((double)(rtc_clock_ticks_tot[tmr]+rtc_clock_ticks[tmr]))); + fprintf (st, " Ticks: %s\n", sim_fmt_numeric ((double)(rtc_clock_ticks[tmr]))); + if (rtc_clock_ticks_tot[tmr]+rtc_clock_ticks[tmr] != rtc_clock_ticks[tmr]) + fprintf (st, " Total Ticks: %s\n", sim_fmt_numeric ((double)(rtc_clock_ticks_tot[tmr]+rtc_clock_ticks[tmr]))); if (rtc_clock_skew_max[tmr] != 0.0) fprintf (st, " Peak Clock Skew: %s%s\n", sim_fmt_secs (fabs(rtc_clock_skew_max[tmr])), (rtc_clock_skew_max[tmr] < 0) ? " fast" : " slow"); if (rtc_calib_ticks_acked[tmr]) @@ -1229,6 +1235,7 @@ return SCPE_OK; } REG sim_timer_reg[] = { + { DRDATAD (IDLE_CYC_MS, sim_idle_cyc_ms, 32, "Cycles Per Millisecond"), PV_RSPC|REG_RO}, { NULL } }; @@ -1389,17 +1396,15 @@ return SCPE_OK; w = ms_to_wait / ms_per_wait */ -t_bool sim_idle (uint32 tmr, t_bool sin_cyc) +t_bool sim_idle (uint32 tmr, int sin_cyc) { -uint32 cyc_ms = 0; uint32 w_ms, w_idle, act_ms; int32 act_cyc; if (rtc_clock_catchup_pending[tmr]) { /* Catchup clock tick pending? */ sim_debug (DBG_CAL, &sim_timer_dev, "sim_idle(tmr=%d, sin_cyc=%d) - accelerating pending catch-up tick before idling %s\n", tmr, sin_cyc, sim_uname (sim_clock_unit[tmr])); sim_activate_abs (&sim_timer_units[tmr], 0); - if (sin_cyc) - sim_interval = sim_interval - 1; + sim_interval -= sin_cyc; return FALSE; } if ((!sim_idle_enab) || /* idling disabled */ @@ -1412,14 +1417,12 @@ if ((!sim_idle_enab) || /* idling disabled */ ((rtc_elapsed[tmr] < sim_idle_stable) ? "not stable" : ((sim_clock_queue != QUEUE_LIST_END) ? sim_uname (sim_clock_queue) : "")), rtc_elapsed[tmr], rtc_ticks[tmr]); - if (sin_cyc) - sim_interval = sim_interval - 1; + sim_interval -= sin_cyc; return FALSE; } if (_rtcn_tick_catchup_check(tmr, 0)) { sim_debug (DBG_CAL, &sim_timer_dev, "sim_idle(tmr=%d, sin_cyc=%d) - rescheduling catchup tick for %s\n", tmr, sin_cyc, sim_uname (sim_clock_unit[tmr])); - if (sin_cyc) - sim_interval = sim_interval - 1; + sim_interval -= sin_cyc; return FALSE; } /* @@ -1446,14 +1449,14 @@ if (_rtcn_tick_catchup_check(tmr, 0)) { means something, while not idling when it isn't enabled. */ sim_debug (DBG_TRC, &sim_timer_dev, "sim_idle(tmr=%d, sin_cyc=%d)\n", tmr, sin_cyc); -cyc_ms = (rtc_currd[tmr] * rtc_hz[tmr]) / 1000; /* cycles per msec */ -if ((sim_idle_rate_ms == 0) || (cyc_ms == 0)) { /* not possible? */ - if (sin_cyc) - sim_interval = sim_interval - 1; - sim_debug (DBG_IDL, &sim_timer_dev, "not possible idle_rate_ms=%d - cyc/ms=%d\n", sim_idle_rate_ms, cyc_ms); +if (sim_idle_cyc_ms == 0) + sim_idle_cyc_ms = (rtc_currd[tmr] * rtc_hz[tmr]) / 1000;/* cycles per msec */ +if ((sim_idle_rate_ms == 0) || (sim_idle_cyc_ms == 0)) {/* not possible? */ + sim_interval -= sin_cyc; + sim_debug (DBG_IDL, &sim_timer_dev, "not possible idle_rate_ms=%d - cyc/ms=%d\n", sim_idle_rate_ms, sim_idle_cyc_ms); return FALSE; } -w_ms = (uint32) sim_interval / cyc_ms; /* ms to wait */ +w_ms = (uint32) sim_interval / sim_idle_cyc_ms; /* ms to wait */ /* When the host system has a clock tick which is less frequent than the */ /* simulated system's clock, idling will cause delays which will miss */ /* simulated clock ticks. To accomodate this, and still allow idling, if */ @@ -1464,8 +1467,7 @@ if (rtc_clock_catchup_eligible[tmr]) else w_idle = (w_ms * 1000) / sim_idle_rate_ms; /* 1000 * intervals to wait */ if (w_idle < 500) { /* shorter than 1/2 the interval? */ - if (sin_cyc) - sim_interval = sim_interval - 1; + sim_interval -= sin_cyc; sim_debug (DBG_IDL, &sim_timer_dev, "no wait\n"); return FALSE; } @@ -1475,9 +1477,8 @@ else sim_debug (DBG_IDL, &sim_timer_dev, "sleeping for %d ms - pending event on %s in %d instructions\n", w_ms, sim_uname(sim_clock_queue), sim_interval); act_ms = sim_idle_ms_sleep (w_ms); /* wait */ rtc_clock_time_idled[tmr] += act_ms; -act_cyc = act_ms * cyc_ms; -if (act_ms < w_ms) /* awakened early? */ - act_cyc += (cyc_ms * sim_idle_rate_ms) / 2; /* account for half an interval's worth of cycles */ +act_cyc = act_ms * sim_idle_cyc_ms; +act_cyc += (sim_idle_cyc_ms * sim_idle_rate_ms) / 2; /* account for half an interval's worth of cycles */ if (sim_interval > act_cyc) sim_interval = sim_interval - act_cyc; /* count down sim_interval */ else @@ -1813,7 +1814,7 @@ if (stat == SCPE_OK) { cptr->usecs_remaining = 0; sim_debug (DBG_QUE, &sim_timer_dev, " remnant: %.0f - next %s after cosched interval: %d ticks\n", usec_delay, (sim_clock_cosched_queue[tmr] != QUEUE_LIST_END) ? sim_uname (sim_clock_cosched_queue[tmr]) : "", sim_cosched_interval[tmr]); - sim_timer_activate_after_d (cptr, usec_delay); + sim_timer_activate_after (cptr, usec_delay); } else { sim_debug (DBG_QUE, &sim_timer_dev, " - next %s after cosched interval: %d ticks\n", (sim_clock_cosched_queue[tmr] != QUEUE_LIST_END) ? sim_uname (sim_clock_cosched_queue[tmr]) : "", sim_cosched_interval[tmr]); @@ -1868,16 +1869,13 @@ clock_gettime (CLOCK_REALTIME, now); static t_bool _rtcn_tick_catchup_check (int32 tmr, int32 time) { -double tnow; - if ((!sim_catchup_ticks) || ((tmr < 0) || (tmr >= SIM_NTIMERS))) return FALSE; -tnow = sim_timenow_double(); if ((rtc_hz[tmr] > sim_os_tick_hz) && /* faster than host tick */ (!rtc_clock_catchup_eligible[tmr]) && /* not eligible yet? */ (time != -1)) { /* called from ack? */ - rtc_clock_catchup_base_time[tmr] = tnow; + rtc_clock_catchup_base_time[tmr] = sim_timenow_double(); rtc_clock_ticks_tot[tmr] += rtc_clock_ticks[tmr]; rtc_clock_ticks[tmr] = 0; rtc_calib_tick_time_tot[tmr] += rtc_calib_tick_time[tmr]; @@ -1890,12 +1888,16 @@ if ((rtc_hz[tmr] > sim_os_tick_hz) && /* faster than host tick */ sim_debug (DBG_QUE, &sim_timer_dev, "_rtcn_tick_catchup_check() - Enabling catchup ticks for %s\n", sim_uname (sim_clock_unit[tmr])); return TRUE; } -if (rtc_clock_catchup_eligible[tmr] && - (tnow > (rtc_clock_catchup_base_time[tmr] + (rtc_calib_tick_time[tmr] + rtc_clock_tick_size[tmr])))) { - sim_debug (DBG_QUE, &sim_timer_dev, "_rtcn_tick_catchup_check(%d) - scheduling catchup tick for %s which is behind %s\n", time, sim_uname (sim_clock_unit[tmr]), sim_fmt_secs (tnow > (rtc_clock_catchup_base_time[tmr] + (rtc_calib_tick_time[tmr] + rtc_clock_tick_size[tmr])))); - rtc_clock_catchup_pending[tmr] = TRUE; - sim_activate_abs (&sim_timer_units[tmr], (time < 0) ? 0 : time); - return TRUE; +if (rtc_clock_catchup_eligible[tmr]) + { + double tnow = sim_timenow_double(); + + if (tnow > (rtc_clock_catchup_base_time[tmr] + (rtc_calib_tick_time[tmr] + rtc_clock_tick_size[tmr]))) { + sim_debug (DBG_QUE, &sim_timer_dev, "_rtcn_tick_catchup_check(%d) - scheduling catchup tick for %s which is behind %s\n", time, sim_uname (sim_clock_unit[tmr]), sim_fmt_secs (tnow > (rtc_clock_catchup_base_time[tmr] + (rtc_calib_tick_time[tmr] + rtc_clock_tick_size[tmr])))); + rtc_clock_catchup_pending[tmr] = TRUE; + sim_activate_abs (&sim_timer_units[tmr], (time < 0) ? 0 : time); + return TRUE; + } } return FALSE; } @@ -2274,15 +2276,10 @@ return inst_per_sec; t_stat sim_timer_activate (UNIT *uptr, int32 interval) { AIO_VALIDATE; -return sim_timer_activate_after (uptr, (uint32)((interval * 1000000.0) / sim_timer_inst_per_sec ())); +return sim_timer_activate_after (uptr, (double)((interval * 1000000.0) / sim_timer_inst_per_sec ())); } -t_stat sim_timer_activate_after (UNIT *uptr, uint32 usec_delay) -{ -return sim_timer_activate_after_d (uptr, (double)usec_delay); -} - -t_stat sim_timer_activate_after_d (UNIT *uptr, double usec_delay) +t_stat sim_timer_activate_after (UNIT *uptr, double usec_delay) { int inst_delay, tmr; double inst_delay_d, inst_per_usec; @@ -2715,3 +2712,62 @@ for (tmr=0; tmra_is_active == &_sim_wallclock_is_active) { + double d_result; + + pthread_mutex_lock (&sim_timer_lock); + if (uptr == sim_wallclock_entry) { + d_result = uptr->a_due_gtime - sim_gtime (); + if (d_result < 0.0) + d_result = 0.0; + if (d_result > (double)0x7FFFFFFE) + d_result = (double)0x7FFFFFFE; + pthread_mutex_unlock (&sim_timer_lock); + return (1000000.0 * (d_result / sim_timer_inst_per_sec ())) + 1; + } + for (cptr = sim_wallclock_queue; + cptr != QUEUE_LIST_END; + cptr = cptr->a_next) + if (uptr == cptr) { + d_result = uptr->a_due_gtime - sim_gtime (); + if (d_result < 0.0) + d_result = 0.0; + if (d_result > (double)0x7FFFFFFE) + d_result = (double)0x7FFFFFFE; + pthread_mutex_unlock (&sim_timer_lock); + return (1000000.0 * (d_result / sim_timer_inst_per_sec ())) + 1; + } + pthread_mutex_unlock (&sim_timer_lock); + } +if (uptr->a_next) + return (1000000.0 * (uptr->a_event_time / sim_timer_inst_per_sec ())) + 1; +#endif /* defined(SIM_ASYNCH_CLOCKS) */ + +if (uptr->cancel == &_sim_coschedule_cancel) { + for (tmr=0; tmr<=SIM_NTIMERS; tmr++) { + int32 accum; + + accum = sim_cosched_interval[tmr]; + for (cptr = sim_clock_cosched_queue[tmr]; cptr != QUEUE_LIST_END; cptr = cptr->next) { + if (cptr != sim_clock_cosched_queue[tmr]) + accum += cptr->time; + if (cptr == uptr) { + if (accum > 0) + --accum; + return uptr->usecs_remaining + (1000000.0 * ((rtc_currd[tmr] * accum) + sim_activate_time (&sim_timer_units[tmr])) / sim_timer_inst_per_sec ()); + } + } + } + } +for (tmr=0; tmrdynflags & UNIT_TM_POLL)) || (!sim_asynch_enabled)) { - return _sim_activate_after (uptr, usecs_walltime); + return _sim_activate_after (uptr, (double)usecs_walltime); } return SCPE_OK; #else -return _sim_activate_after (uptr, usecs_walltime); +return _sim_activate_after (uptr, (double)usecs_walltime); #endif } @@ -3880,11 +3880,11 @@ t_stat tmxr_activate_after_abs (UNIT *uptr, uint32 usecs_walltime) #if defined(SIM_ASYNCH_MUX) if ((!(uptr->dynflags & UNIT_TM_POLL)) || (!sim_asynch_enabled)) { - return _sim_activate_after_abs (uptr, usecs_walltime); + return _sim_activate_after_abs (uptr, (double)usecs_walltime); } return SCPE_OK; #else -return _sim_activate_after_abs (uptr, usecs_walltime); +return _sim_activate_after_abs (uptr, (double)usecs_walltime); #endif }