SpinWait - possible bug in implementation<div>I'd expect the calls to Thread.Sleep(0) and Thread.Yield() to be swapped around:<br/> <br/> public void SpinOnce()<br/> {<br/>     if (this.NextSpinWillYield)<br/>     {<br/>         CdsSyncEtwBCLProvider.Log.SpinWait_NextSpinWillYield();<br/>         int num = (this.m_count &gt;= 10) ? (this.m_count - 10) : this.m_count;<br/>         if ((num % 20) == 0x13)<br/>         {<br/>             Thread.Sleep(1);<br/>         }<br/>         else if ((num % 5) == 4)<br/>         {<br/>             <strong>Thread.Sleep(0);</strong> <br/>         }<br/>         else<br/>         {<br/>             <strong>Thread.Yield();</strong> <br/>         }<br/>     }<br/>     else<br/>     {<br/>         Thread.SpinWait(((int) 4) &lt;&lt; this.m_count);<br/>     }<br/>     this.m_count = (this.m_count == 0x7fffffff) ? 10 : (this.m_count + 1);<br/> }<br/></div> <div><br/> <br/> Alternatively, it would make sense if it always called Yield instead of Sleep(0).<br/> <br/> Joe</div> <hr class=sig> Write LINQ queries interactively - www.linqpad.net© 2009 Microsoft Corporation. All rights reserved.Tue, 30 Jun 2009 13:35:16 Ze6623d1f-6f30-4b52-a855-5870a879638dhttp://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#e6623d1f-6f30-4b52-a855-5870a879638dhttp://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#e6623d1f-6f30-4b52-a855-5870a879638dJoe Albaharihttp://social.msdn.microsoft.com/Profile/en-US/?user=Joe%20AlbahariSpinWait - possible bug in implementation<div>I'd expect the calls to Thread.Sleep(0) and Thread.Yield() to be swapped around:<br/> <br/> public void SpinOnce()<br/> {<br/>     if (this.NextSpinWillYield)<br/>     {<br/>         CdsSyncEtwBCLProvider.Log.SpinWait_NextSpinWillYield();<br/>         int num = (this.m_count &gt;= 10) ? (this.m_count - 10) : this.m_count;<br/>         if ((num % 20) == 0x13)<br/>         {<br/>             Thread.Sleep(1);<br/>         }<br/>         else if ((num % 5) == 4)<br/>         {<br/>             <strong>Thread.Sleep(0);</strong> <br/>         }<br/>         else<br/>         {<br/>             <strong>Thread.Yield();</strong> <br/>         }<br/>     }<br/>     else<br/>     {<br/>         Thread.SpinWait(((int) 4) &lt;&lt; this.m_count);<br/>     }<br/>     this.m_count = (this.m_count == 0x7fffffff) ? 10 : (this.m_count + 1);<br/> }<br/></div> <div><br/> <br/> Alternatively, it would make sense if it always called Yield instead of Sleep(0).<br/> <br/> Joe</div> <hr class=sig> Write LINQ queries interactively - www.linqpad.netFri, 26 Jun 2009 03:53:16 Z2009-06-26T03:54:27Zhttp://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#2b200c32-fcc8-48bf-8861-9d33372ac289http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#2b200c32-fcc8-48bf-8861-9d33372ac289Emad Omarahttp://social.msdn.microsoft.com/Profile/en-US/?user=Emad%20OmaraSpinWait - possible bug in implementationThanks Joe for the feedback. SpinWait tries different ways of yielding after a certain amount of spinning, it first call Thread.Yield and every X yields it calls Sleep(0) to give its CPU slice to higher priority threads and every Y yields it calls Sleep(1) to sleep the minimum allowed time (usually between 10 and 15 ms)<br/>where Y &gt;&gt; X we don't wanna move to Sleep(1) quickly.<br/>Regarding to swapping Sleep(0) with Yield this will make the default yielding using Sleep(0) which would be very expensive to use Sleep that frequent especially for short spinning time.<br/>Hope that answers your question.<br/><br/>EmadFri, 26 Jun 2009 18:28:30 Z2009-06-26T18:28:30Zhttp://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#a909da2d-312c-4c82-bbeb-c0a321a772e1http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#a909da2d-312c-4c82-bbeb-c0a321a772e1Joe Albaharihttp://social.msdn.microsoft.com/Profile/en-US/?user=Joe%20AlbahariSpinWait - possible bug in implementationI don't understand. Isn't Sleep(0) supposed to be <em>cheaper</em> than a Yield?  <br/> <br/> <a href="http://www.bluebytesoftware.com/blog/2006/08/23/PriorityinducedStarvationWhySleep1IsBetterThanSleep0AndTheWindowsBalanceSetManager.aspx">According to Joe Duffy</a> , &quot;Sleep(0) actually only gives up the current thread's time-slice if <em>a thread at equal priority</em> is ready to run&quot; while Yield (SwitchToThread) doesn't exhibit this problem.<br/> <br/> If this is not the case, then what's the difference between Sleep(0) and Yield?<br/> <br/> Joe<br/> <br/> <br/> <br/><hr class="sig">Write LINQ queries interactively - www.linqpad.netSat, 27 Jun 2009 01:22:28 Z2009-06-27T01:22:28Zhttp://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#edae777a-c5dc-4a93-8692-115aa69c0b04http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/e6623d1f-6f30-4b52-a855-5870a879638d#edae777a-c5dc-4a93-8692-115aa69c0b04Emad Omarahttp://social.msdn.microsoft.com/Profile/en-US/?user=Emad%20OmaraSpinWait - possible bug in implementation<p>No, it isn't. Yield will break the execution of the thread, place it at the end of the queue for its priority and looking for the highest priority ready thread in the <strong><span style="text-decoration:underline">same processor.</span></strong> However Sleep(0) will look for the highest priority ready thread in <strong><span style="text-decoration:underline">all processors.<br/><br/></span></strong>From the MSDN docs for Thread.Yield:<br/>&quot;Yielding is limited to the processor that is executing the calling thread. The operating system will not switch execution to another processor, even if that processor is idle or is running a thread of lower priority&quot;<br/><br/>Emad</p>Mon, 29 Jun 2009 20:23:54 Z2009-06-29T20:23:54Z