# HG changeset patch # User cin # Date 2013-11-13 21:15:07 # Node ID ee04e1fa78da52ee25bf6dbb4786c9a2403163ae # Parent f0568ff069a51973c64a7a6093b48c751a6cb198 fixed dispatch pool race condition diff --git a/Implab.Test/AsyncTests.cs b/Implab.Test/AsyncTests.cs --- a/Implab.Test/AsyncTests.cs +++ b/Implab.Test/AsyncTests.cs @@ -244,7 +244,7 @@ namespace Implab.Test { [TestMethod] public void ChainedMapTest() { - using (var pool = new WorkerPool(4,4,0)) { + using (var pool = new WorkerPool(0,100,0)) { int count = 10000; double[] args = new double[count]; @@ -255,7 +255,7 @@ namespace Implab.Test { var t = Environment.TickCount; var res = args - .ChainedMap( + .ChainedMap2( x => pool.Invoke( () => Math.Sin(x * x) ), diff --git a/Implab.v11.suo b/Implab.v11.suo index 1a41f7b2d0cb05a0444b1048004dea186d59b1e0..12ae8b2c29f54ee7562c00d4b4e5890f43c7d69a GIT binary patch literal 114688 zc%1EB3wRsVmA=aR;gAPO${PcLLa-Fc582KGBFk11VkgFO3=1ZSERP+lHzhol@}@}xbfKkbXg6)yHX*QW>BsKJhF#zTTH-zD&Rl6U8c8#f zY)jU?{*LFNJ9F;y+;h+U@0mlto__3sCr*2ZsKO;=G&wOak&IK^8>Ngejga%>4Q>0o?$r+0+fXp{?`L-AU0wp7bkt!T;M+!juYiH=;41t z5pNFA7jQjJe*Qf9ctX`qrpwQr1II5DsrZ@pKNXH=0-X(10yIg! ze=Z!y0IdQ#gGh1)?@yMGJK=~WPzGcMvH;BkvI5zF%7H3?DuJqi>_F8(H9*+R<^wGN zS_rg=pll=LQlP~^4xl<9Cr~|51CR@73D8oYWk8n!EeC1@S|O)tB^+B6`E8ZY+u%3_ z=n9}Kfv#4>X@~Po8f7$?0ekZn70(+L*Lc2FuG_D}ahrUO^iBEvW;kvK`ZmxGpzi?P z0`y&=?*ZMac!tsU;ohA% z>mLI>s<{8SeEy_-{3#rN0`xS{GeFM*JqPqW&0==Yoe!qNvKt8?#$5-X^f0K`| z%g0~J$6v|EU(3fg;rJV%-^$mA;rJgwzX$pQ&|C8TKPvcQe|TGQ&BCAMdqWw9QvM(N z>l?Q*`M*DR^52BKzeM!Qzaxape|BC+>)#KYJiyfrM-l#faNeCZ?-)vfKbHL%1N^Tg zlI+KDIh25uf-sy#Ae`<=}xdc|ZmW39Yjd_~W}yGr<4fF|K@m1`O5Z5Pr2{$pfm=WP zms&*f5vC}NV%m9k)te9gvn)Co`@n68L-4oMup)Z;%s`(^n&)%efaERO%! zAK3UmUcQg{!n73H_&=Kz&iKzmaR;vd4ZZ%SrQ`hterNjMU&+wvfw>s}aVX*AzZCTF z&!_RfPA=U|d>{m6?x8I* z2zL^L74nbsZ8OPC|6K|EL|V=Pxz)RAo<*vE`+$GyFeiijqs>%2NjjJMUk}Y?2#zuC z`ob9*@JIW~g@p0v^^`9#LI2W&=nsoAzN&Wv0=o6j%%Smm{`Q!Y5yPk+T zgHisu4%zT`L%;LNy>J86KqnphTHt@T=6I_PX#c?Z7PHyv;iYg1`3-wT~*H7mMsG(axPYu#>3Z+D|thrm@*)Z{cwqyIHZ_nLz()#C0PyXm= z6Cv@VQkUY|-@hs>bh>DH@_9qSaIj0XwE4mjkKZju zI(vf4QV* z&6+xh4A(B7;O{h{z?w9f9CuFCQ)EfQY9}=P_Gq!h7oqwpu|V6Yk`abDSmj=_PF1L< z)|j?l_x{Ga_gFn=mAdXJQ5Nd?rxP-JLhQP%v`q+weZjyYo6Tayzp_$i#4kod!lHl> z5knq-S!r{m!|(Gh7y4U+Jwjkn2R^u+=(7iGKAkv&)`K)sO|0A9JSittW z2k4gupUZVXxrOt8lpi?%$GN?7{*UuYod2VK!{+~3E@%(H`9IqIQTI3*=%iuJ3kxTX zoVRDz-fb%%Ke%b~(XHbr4|V^`w*Rykd48F!=-^}rr`=()lur3O>H9)*pX+KXIlTAX z3op8Be9gVDS9KpD8dVh&0J-bG8Oa|ezgYbleO|r(<%TR^QDSCrWYV$zWmx~j7Q)uQ zTreAKfLUB6{C9$`V}=pW3P%^5q3%-;*K4A)#KhUr{0#ITTrV3HG{V0XuAAU@4^(u5 z{U;;+dyITcum7bEsDH9G6}|j12OH&cC+!^A721Hm0Qa4ArY)^P>Z*SeuG!2sz+b8V zvzo=cVn+?qt{Kuj56-0h;rh;Jvi)HduC>rE{)MTH0<% zNdQuZ;-gbu5gu&*w1_2HHDkHv-~ImZLx1^3gFrRp1i6R8maUPa`ZC{${B^^z zE6Q)mym{l6KU;G79mfxUaNyWuk7)9X=N6IA+o9L?!CyUDVT6Ah9XlelYi*DlI5VEe z?SYKJlMhYq{;(+YTAV?@U+{{cRD~@|gn$t8c`fxmdczayUt50l)pA6)7=od#th6`m z4Tk)_j+io5saqGTuJ%-UtL(Pgib}y+Q+rL>)f%Z->IttCJso}_H@xbh;84={%Eh6y zL*r0}m;`2h(`t=qf5Q=o*`W2bKU|YJCIc{1@n4VmKka{ITq1^_yG?lHadd@m&c+cB(N)8BqU3OwvpP{QV?0 z|45(z^z9FEQwt36M_a~C@_8HZYX(j&p!YR{R^ueg;r|l2W6=o%s*xF%k2J&w) ziRGW^8rR^W)OcBsnBWZd_IW}=XaZ^*Zr^nR8BHeKno22>j}6yGJbs_p&t9w*h2kUwY#epBwV(!8H#N0RwwxLXAyx)a7e z2R$Ya7iPf!DWD#ifBNx1{rGE?|307_h+h8b$6s8_M=eb+|DOSMvy0>lIuAT&I@xyo z&_%a?c;_Q#p$;{?#8y<7N&AiOv!8tQ*J}^H*Z0_w-G8|8?44WwN0U!7`(L{;`4``N zmeE2N71n@wY5dexzr5|f7h1pg`mZkO`E=d|Wtu6=&i>bynf#3}$E8%7_bDX6jL<6` zOYS>q{?Ar?5&HZz=e?RK$AEhbI-m`9%cwV(EC<}s!+YVEAk~(VhfLbPa{jI6-$bQS zknTfK%A{m^AkM!LYtGhF^zcXBt2GJ#I@&lqP!)Z^*C)@!l_`l2l^Nv!8ziQGVILPM z=Kvj;nT!pqERo5qvh#sI;^9vF@81BHh6XXT!6J^X)2V)8G(mDkgjk7XaAsYo9Xe~fZ@ z8W|k?QR>k@GyKo>BsTwUrP8LCTKy&TWvs=uMR$e8S|(FDS-|zL3y8EAMlXM~7yM8@ z=j%Vkz5b&f|E`EGWUGfh)GgY8+jz`EMXG{Ap~TwWRquWqqs{&e({j1Vme>ahAN_f9bKH~oWe*(ISNPYlt|35ATtp-{Hv=#`h8XZ7hpiUy~ z3qhnj_Rn=dKA`nLJwUzkdvQd-QL&Fm{sizIuBVHNv~85nah$zQKHn@Kzd|JW^HpB| zMPL8v@dxSkU!(H>F%r}N)A3J@{)yRNn2!=Y{GT9F`Rn0dp+o=0Hg>52{{Kq!<1Z?7 z;BS!cVgvmDlf>}9_zd6wkvcG647uF@@ix%w!;~LoXlQb^qHJdC(J?;<8|5XbGL;>2 z5zOBzA-0On3J#rIt=4N8@wG+_!jyfLogt3HBszxLO2GF6>Y@GBAN?& zRlCZXs$4*0i+|EMXyo168@!sJR4=EX<4APLQyLE&Gf20C$_eG3c=krDhZaL`#JOLc z)7|{(hs__mZaQ??9W%GBXmu`!Ztf_x~bM$QTr-LSw zqUM3K6E%sL2E3W(t{>{(2_?BI8WVMrE{K7pI*vZk0Ig;f_0c40Aq$|DRMWP?&dTAe zoVFrq4P{^eHJUzo*|d+2mGJ?!9hAczv<8)a@KCCvUK6BiHSLNNtMlAR)0pawW7KTr zu%xbW8R|+#m#FbMlqY(iDH!)llt*GKjRAV%K>+y7Ec$+Z&=ZV*dNdzWj}mDN#zn%N zbO49`sD&r?>}g5TmwKBOKG_m&t*LhmNNb5o3{^Yr30RNq8OcFQLcSc-ZW5w(AE9Hp zvc4uq%O@TPfxn?HogU`IYDKTS!T8e>xW+V%SS)O_@!K@mv&-oIC&@FRUvBaKxLBto zNl|i$2|hJbvvp~0%wy%FucenL-m6{CTH8Sqd)KK+drXMl>!)5zJhYdx=jt08m*KN( zqir&lKWtT{igo@{nCEN)DP@PbPCNCy&_#2?yg-(!S{Lg}O>~7eMAztp@C?F25?gJm z7Tq3g!R>HA3~$5xlEh-N45el_T_NkB`8O%#mA7DWhiDebvt}>camuTVdh)osK=YV7 zXV^ZQoX*CPlS}1&rIx{R8&7U0>OCc8pLzFr_AlMNaYy&dKldE^_GC%#u@EDAj}n%p zeLr3o@-}`xD>u4O2~p}o3xHn>T|uI#*Ua^zI5+?4^dbqxn@%r^l|*(L5|&YN=rP8a zo-oQKg5wHHTgX(KDvmMeVncnk9SE%~>2-KDPqar~Pio<>4yX#Aw*r~r+zGj=g|kXH zVh=MzIXd7s+(GVwyBN~}e^n5(jy_c@uYMNG7`oGN9ureuO7Tfys4;wdDb-ygz#Ds4 zDcz|rrP4`zelP8F)wFI=LTZ(ocA3TUo0tYmTpE-quuzTLL*FA(jga}Yv`~Z*-euA% zv6Q(UG8Da8c^`vv{N=4we=Eh+m7(LRr3H)>nTh(Fb_}%!J2E6dCOZ133-SBprROAxXikr-}FCb@S&tKiGKFTZy_k>e4M#j})lwK}f2fqej~Y zdG4Tn8?`dDSZ1P`OKY&1YUTq2O3gez?b_v#oo1em&988DakNz>THv)-4>0x=&Dila zsN{1MwJoWmK>NRh@YJK@m<{#m*yx|Sbq}pR?=R3=ir;Hxp(ykaossFOxwQq8>rCdD z-3607?Vi_2>-Ji1)0OkMu3+-0rDr>-k3Jle`$lw)vhiL|9=i%Qj~I8OjQr7)(@4SQ zl+`9XlhEaC|7#$so#`8K3V$}F#~w1+8c{l%$jFnFxIU0BuGZ|kP^D;gHiu%8HfJT2 zjFGpDq&A}-c@x_Vi&1=bs*$H{Ox37eWjw7C7`e0DSqY_){28s185vfZ$qA(({jQbc zkv2P?mL%`7nCWcSg^T7u1YdeI2e%h}gw>x%S zbH(DF2WCv{GD{feN@7H#V|LkOyAk7mjmJH|wdLIrgL_8LQbuskx!Rj}Hj#GDOB|5f zO1i5&MEUhc<$)!^%XJ}IwogvTEqX1$b|1?pi+hHSxXH@|$DR0+jBmpjXSVLL&(*HV zp~ot_NEQ59;fP@|Z?$dboez>;_=mDSyfp!Bu1oSYGeCFZTpz#|OKUO{aC|vI)(irkMk!1Ok zM3SlK*ZC(vPXj#z^eoT;pyz>J0D2MVC7_=Y$p`a(BKbl_elNrE6`)sveoiDGeXkM8 zN8c~xI3qD||9{2p|8MwKR#C4so_~FMv=X7Dtxa1&ZZ^>Qr(M>j?eM<_S{rK96%>bs z+H^U@X`rj&E=Vov-xW{?E{N@b7*2&YU6}p@xc^5MiqrpNet9`59DRMH;1AM&|0VSd zJd^KVpssbJe4hUM7q)c#>HHUc!0Y9Y`rY+9`B$fT7k+;X{nsxtz#sL>h)(|HI={bT zr2J8zW%h@`#Ge%Y3SS}Y(JM^7gZnKioc@plbF z6Gt~?k8Ua)EhoMv3uBdv`~Tho)#FT}-|E4= zMRRY_#`oaluPuhJ6Y+H-zD~r~iTFBEv3~y}H@5h~nfGu{>q==R?R(+hf8iQE*XWIC z^dsf_FNG-2_^6b-Q7QfVZH8L9+E2Sa6v9Jz0Qc$ zU}*PDsd&tBg*FA2e~s;@Sr-x>YRJ0Xa;a~a~1?33W&JlBdRO{yl1ko# zevt$GYB@z^)Q~xvGoCpL%xVS2W8gRH=g@Mir}_2Jlz9_cOk%sVr1&GM`esI9@6z7?+=d)E3FQ52<|*JR#$pvO{W4~X{a1x8fLoh3KMFFG*Wl^bmLJ5=T6DWJDD}$Y=bjN zi^59u@C-=;4V)nIoT-u4f(SZQA8m_FM-CDR8RMgR(n^q!T~xNA2FLVlhM2+r#Zt10 zrdeI1oe9sNL~5Yp9KPF4V+&ON5h_`4qbM~%x!BLm)|g!4NABL{FEI#4qoSMuYbCuvFyFO zHhiKq%c?)XZjy^!{XTq;`a_VZ;;J1gnB-2Reuvhx?}#TJbUt%v`rgyXuGgmyysS1O zD}(xZb$(JjDurG$$t1O06N=R{+_Zg1qGN9<)PSVL;krf2pG%bOV^sX*VlQo3F+IZ< z{V^Z(Q;z@Q=m(Df;`pz^$|=Wxar_s@f8}G(dVF1YEvU2hSs^d$7#O#b~y_e=ZJ;}XQq)Us`lh9K|4ZH=( zM$>}Gq-uBkH>Cz|1DJN%W?drmkyDXys&VpUUYlU-L&igC3A4;Mu~IUy%bij1-W z7Z>GFL+_g5?U<5kS_1VDqZ;m40NH75ETt`m^dXM_9eMa)j{oBLFOL7>_%DwC;`lF) z{~|?)|Kjt1KL6+Qe?I@`^Z(+U|Lf!G$T`!g+YtyqktM^UNF86qbD{^aW z`R_*#cg*}`N@;NSi*J^{w0eqWsVRdIiR7TYsezVo1C@z&^t^&vd2O=Z;-J4dA5+mWPYg+X1R7M^her*f!U8`VL|=_pwv_h6JMD3j}{Hf4rmIsA&}4*F{qq^H7w zhJxM2LA6pJZJtgjn{HV{okCLi2VWpphMBfGTeMuTB&s16juLC=oi#K!7I=T^>Sxv4 zLXXlcDXd{1lduY{8SqC;(?WSt5+IjA4kyua(7Ud{#-I3g1(6=BpnmFU)0D2ICK}HT zgUZ>tp?k-sNyw-Ya;K?&z7_ticU4tcT{c&Zxu&|(Zmx9HTg|n0Tcx?Cs>)UAtgNec zS*x~eUe?>^_jI&N2a7k{7YeT5?494fF&OG;_enp>hdxipruvS&tt1GvBe+W{BKMJ9~V9;+M zVYdxI!g|GPBSJ(lkg9uFs_Yf6+H$AWX|~(yT;|Fer`7DJsIE5G)Z43_6;8X|R&Qmg zva||ev0ZVVGJO^iV|&8=0WY2zsmz-PugpThUSHTqNquk7($eb*c)Ep7<4M{+Xi4%J zPs}ZYml&@n;1&FE>Nk?0L6lLUV0TCehkXH`C~Ob{q9@dCq*>oF6w(v>Ti%E$A1ksz zQ1o^Agph$$-9JuAK*S^!mL0^+Z~+tIzL|Ry!jfM6ajqN9~hlB(Fvt?Q|={bop4Hza3LM z6Hi31OZOij63U@IKefnowQzhNc8PM#K)#NB+F2-3+&NEfOoQ2wvQ#Y6_XY$E(O#T~ z>TLSdBS;=?WA%BbY^F~;TBvYwa1gt2Hdp1BWh} z0+teXoj)m(?&d>^e015xPvZ+TMJyOEKZgFxG_^Q2DJALFsU-Z*R1!ldsRO%@=~B5a z`^T1OVEtBeTl7_f=Q7~AsW06n_@>`6c3tNlOQZei5)xYrJ`AP(x6!fdq{Q%AUjZ|V28UH#Gu3P$H-y!n_KV; zUQtL8b(*3q7v-NH-v{x3wqyIHZ_nLz()#C0PyXm=le+x76xV|<%Ey_g1g27LBG%M& z{D*VIDU&8c3_3%aG&w=XFd9nK&r|uiDM_Qc98N*Nw+4g$u%*@47q)22U;WRwMtptE zkaL(h=1e(Ql%h*$v$nV+L98IGAAG|(3o$O!8Soc%4YBfHou#5|0RN@e0Y+C_$>F{4 zUU<=6<7@7Hy{h|2QW;D`YDN9j8q?P6-rsol9;@f9QrA5t%6FZAIw7+s#CH;qTeBzl8p4G!%IM<@j%o|K|8_ zj{oNPZ;t=w_-~H?=J;=p|IRloO+F#q@*DD%x1hTG#5m>QT7F(3@$wFmlfN*ne8s@! zCo(DT;YJ+)okRThqtWZ*`}PsZyA#KMbNqMl;lE=&VcPzuh=knX_-~H?=Fn7*|K|Ab z!N7m>kUDVuH^+Z-{C9f%HwG>Iw-$C_ZQA$6t~maf$gJxbdIEf`3%v bze#rGuf$Jr{5Qvc7aab3nDKkVjsO0CIj5A! diff --git a/Implab/Parallels/ArrayTraits.cs b/Implab/Parallels/ArrayTraits.cs --- a/Implab/Parallels/ArrayTraits.cs +++ b/Implab/Parallels/ArrayTraits.cs @@ -167,5 +167,46 @@ namespace Implab.Parallels { return promise.Anyway(() => semaphore.Dispose()); } + + /* + this method is pretty fast, but it may cause a stack overflow if an element transformation is made faster then the next operation is + be chained, in this case the syncronous callback invocation will occur + + public static Promise ChainedMap2(this TSrc[] source, ChainedOperation transform, int threads) { + if (source == null) + throw new ArgumentNullException("source"); + if (transform == null) + throw new ArgumentNullException("transform"); + if (threads <= 0) + throw new ArgumentOutOfRangeException("Threads number must be greater then zero"); + + var promise = new Promise(); + var res = new TDst[source.Length]; + var index = -1; // we will start with increment + var len = source.Length; + var pending = len; + + Action callback = null; + callback = (current) => { + if (current < len) { + transform(source[current]) + .Then( + x => { + res[current] = x; + if (Interlocked.Decrement(ref pending) == 0) + promise.Resolve(res); + else + callback(Interlocked.Increment(ref index)); + }, + e => promise.Reject(e) + ); + } + }; + + for (int i = 0; i < threads; i++) + callback(Interlocked.Increment(ref index)); + return promise; + } + */ } } diff --git a/Implab/Parallels/DispatchPool.cs b/Implab/Parallels/DispatchPool.cs --- a/Implab/Parallels/DispatchPool.cs +++ b/Implab/Parallels/DispatchPool.cs @@ -151,7 +151,10 @@ namespace Implab.Parallels { } } else { // if there is no sleeping threads in the pool - StartWorker(); + if (!StartWorker()) + // we haven't started a new thread, but the current can be on the way and it can't process the queue + // send it a signal to spin again + SignalThread(); } } @@ -281,7 +284,6 @@ namespace Implab.Parallels { m_hasTasks.Dispose(); else SignalThread(); // wake next worker - unit = default(TUnit); break; } diff --git a/Implab/Parallels/MTQueue.cs b/Implab/Parallels/MTQueue.cs --- a/Implab/Parallels/MTQueue.cs +++ b/Implab/Parallels/MTQueue.cs @@ -44,7 +44,7 @@ namespace Implab.Parallels { // this is the last element, // then try to update the tail if (first != Interlocked.CompareExchange(ref m_last, null, first)) { - // this is a ace condition + // this is a race condition if (m_last == null) // the queue is empty return false;