<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Condition variables and monitors for Delphi</title>
	<atom:link href="http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/</link>
	<description>Our products, programming &#38; business.</description>
	<lastBuildDate>Tue, 09 Feb 2010 18:35:10 +0000</lastBuildDate>
	
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Tobias Gurock</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-35396</link>
		<dc:creator>Tobias Gurock</dc:creator>
		<pubDate>Fri, 27 Feb 2009 07:34:35 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-35396</guid>
		<description>I&#039;m aware of instructions reordering and cache related problems. However, I still think the pthreads guys got the code right. For example, they are aware of possible race conditions: 

&quot;In the line where you state, &quot;else if ( nWaitersBlocked &gt; nWaitersGone ) { // HARMLESS RACE CONDITION!&quot; there is no race condition for nWaitersGonebecause nWaitersGone is never modified without holding mtxUnblockLock. You are correct that there is a harmless race on nWaitersBlocked, which can increase and make the condition become true just after we check it. If this happens, we interpret it as the wait starting after the signal.&quot;

I agree that the code is pretty complex and difficult to verify but the equivalent C implementation has shipped with pthreads for several years now.</description>
		<content:encoded><![CDATA[<p>I&#8217;m aware of instructions reordering and cache related problems. However, I still think the pthreads guys got the code right. For example, they are aware of possible race conditions: </p>
<p>&#8220;In the line where you state, &#8220;else if ( nWaitersBlocked &gt; nWaitersGone ) { // HARMLESS RACE CONDITION!&#8221; there is no race condition for nWaitersGonebecause nWaitersGone is never modified without holding mtxUnblockLock. You are correct that there is a harmless race on nWaitersBlocked, which can increase and make the condition become true just after we check it. If this happens, we interpret it as the wait starting after the signal.&#8221;</p>
<p>I agree that the code is pretty complex and difficult to verify but the equivalent C implementation has shipped with pthreads for several years now.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: René</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-35297</link>
		<dc:creator>René</dc:creator>
		<pubDate>Thu, 26 Feb 2009 20:35:51 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-35297</guid>
		<description>The thing is even if the mutual exclusion would be guaranteed, there is no guarantee that the memory write-cache is synchronized between physical processors, cores or  hyperthreads unless you are using the SAME synchronization mechanism every time the same variable is accessed. (See also http://msdn.microsoft.com/en-us/magazine/cc163715.aspx)</description>
		<content:encoded><![CDATA[<p>The thing is even if the mutual exclusion would be guaranteed, there is no guarantee that the memory write-cache is synchronized between physical processors, cores or  hyperthreads unless you are using the SAME synchronization mechanism every time the same variable is accessed. (See also <a href="http://msdn.microsoft.com/en-us/magazine/cc163715.aspx)" rel="nofollow">http://msdn.microsoft.com/en-us/magazine/cc163715.aspx)</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tobias Gurock</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-35197</link>
		<dc:creator>Tobias Gurock</dc:creator>
		<pubDate>Thu, 26 Feb 2009 07:25:54 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-35197</guid>
		<description>Yes, the implementation is complex, maybe too complex. If I recall correctly there was a discussion about this particular case on the pthreads list/forum. There&#039;s a link in Threads.pas to some implementation notes from the pthreads developers. Good suggestion with TMonitor.Wait. In .NET/Java, Wait throws an exception if the current thread does not hold the lock, I think that would be a good feature to add to Threads.pas as well.</description>
		<content:encoded><![CDATA[<p>Yes, the implementation is complex, maybe too complex. If I recall correctly there was a discussion about this particular case on the pthreads list/forum. There&#8217;s a link in Threads.pas to some implementation notes from the pthreads developers. Good suggestion with TMonitor.Wait. In .NET/Java, Wait throws an exception if the current thread does not hold the lock, I think that would be a good feature to add to Threads.pas as well.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: René Grob</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-35110</link>
		<dc:creator>René Grob</dc:creator>
		<pubDate>Wed, 25 Feb 2009 21:18:28 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-35110</guid>
		<description>Well, may be my comment above was a bit exaggerated. My point of view is that everything what is not clearly threadsafe is not threadsafe. I have some doubts concerning the function &quot;WaitConditionVariable&quot;. It just seems to be a too complicated implementation. In the function &quot;InternalPulseConditionVariable&quot; the variable ACond.WaitersBlocked is read and written without the guarding lock of &quot;ACond.BlockSemaphore&quot;. I don&#039;t see a consistent synchronization mechanism to access &quot;ACond.WaitersBlocked&quot;. Besides TMonitor.Wait(..) should check that it has the ownership of the critical section or enforce it by explicitly reentering it.</description>
		<content:encoded><![CDATA[<p>Well, may be my comment above was a bit exaggerated. My point of view is that everything what is not clearly threadsafe is not threadsafe. I have some doubts concerning the function &#8220;WaitConditionVariable&#8221;. It just seems to be a too complicated implementation. In the function &#8220;InternalPulseConditionVariable&#8221; the variable ACond.WaitersBlocked is read and written without the guarding lock of &#8220;ACond.BlockSemaphore&#8221;. I don&#8217;t see a consistent synchronization mechanism to access &#8220;ACond.WaitersBlocked&#8221;. Besides TMonitor.Wait(..) should check that it has the ownership of the critical section or enforce it by explicitly reentering it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tobias Gurock</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-35079</link>
		<dc:creator>Tobias Gurock</dc:creator>
		<pubDate>Wed, 25 Feb 2009 09:28:27 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-35079</guid>
		<description>Hello René,

thanks for your comment. Can you give any code lines which contain a race condition? Would be much appreciated. This code is basically a port of the pthreads win32 condition variables implementation.</description>
		<content:encoded><![CDATA[<p>Hello René,</p>
<p>thanks for your comment. Can you give any code lines which contain a race condition? Would be much appreciated. This code is basically a port of the pthreads win32 condition variables implementation.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: René Grob</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-35078</link>
		<dc:creator>René Grob</dc:creator>
		<pubDate>Wed, 25 Feb 2009 08:53:07 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-35078</guid>
		<description>I looked at the source code. I have the impression that a lot of non-atomic operations are used to simulate an atomic operation. There are a lot of possibilities of race conditions. I consider the code to be NOT THREADSAFE. There is an API function &quot;SignalAndWait&quot; which is atomic, but unfortunately it can only be used with a Mutex not with a CriticalSection.</description>
		<content:encoded><![CDATA[<p>I looked at the source code. I have the impression that a lot of non-atomic operations are used to simulate an atomic operation. There are a lot of possibilities of race conditions. I consider the code to be NOT THREADSAFE. There is an API function &#8220;SignalAndWait&#8221; which is atomic, but unfortunately it can only be used with a Mutex not with a CriticalSection.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tobias Gurock</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-24946</link>
		<dc:creator>Tobias Gurock</dc:creator>
		<pubDate>Sat, 27 Sep 2008 21:09:57 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-24946</guid>
		<description>To your comment above, the producer signals the condition variable only when the related predicate/condition is already true. It actually shouldn&#039;t matter at all (performance differences aside as mentioned by your discussion) if the signal is issued within the lock or after - except if the internal implementation requires holding the lock.

While the producer adds an item to the queue, the whole section is locked and the client cannot enter the same lock. Once the item has been added, the mutex is unlocked and the consumer can enter the critical section. Since the condition is true, it shouldn&#039;t matter if the producer is preempted right before signaling the condition variable because the consumer does not wait anyway.

Being able to signal the condition variable after releasing the lock seems to be an implementation specific feature since in Java and .NET, for example, you are required to hold the lock while signaling the condition variable. The new condition variable API which ships with Windows Vista, on the other hand, supports this feature as well (See SleepConditionVariableCS and WakeConditionVariable):

&lt;blockquote&gt;You can wake other threads using WakeConditionVariable or WakeAllConditionVariable either inside or outside the lock associated with the condition variable. It is usually better to release the lock before waking other threads to reduce the number of context switches.
&lt;/blockquote&gt;

As a side note, I just learned that the new Delphi 2009 finally got support for condition variables with a new TMonitor record. Also, if you are developing against Windows Vista, it&#039;s probably a better idea to directly use their new condition variable API.</description>
		<content:encoded><![CDATA[<p>To your comment above, the producer signals the condition variable only when the related predicate/condition is already true. It actually shouldn&#8217;t matter at all (performance differences aside as mentioned by your discussion) if the signal is issued within the lock or after &#8211; except if the internal implementation requires holding the lock.</p>
<p>While the producer adds an item to the queue, the whole section is locked and the client cannot enter the same lock. Once the item has been added, the mutex is unlocked and the consumer can enter the critical section. Since the condition is true, it shouldn&#8217;t matter if the producer is preempted right before signaling the condition variable because the consumer does not wait anyway.</p>
<p>Being able to signal the condition variable after releasing the lock seems to be an implementation specific feature since in Java and .NET, for example, you are required to hold the lock while signaling the condition variable. The new condition variable API which ships with Windows Vista, on the other hand, supports this feature as well (See SleepConditionVariableCS and WakeConditionVariable):</p>
<blockquote><p>You can wake other threads using WakeConditionVariable or WakeAllConditionVariable either inside or outside the lock associated with the condition variable. It is usually better to release the lock before waking other threads to reduce the number of context switches.
</p></blockquote>
<p>As a side note, I just learned that the new Delphi 2009 finally got support for condition variables with a new TMonitor record. Also, if you are developing against Windows Vista, it&#8217;s probably a better idea to directly use their new condition variable API.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tobias Gurock</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-24912</link>
		<dc:creator>Tobias Gurock</dc:creator>
		<pubDate>Fri, 26 Sep 2008 11:29:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-24912</guid>
		<description>Thanks the link Ivan, I will look into it. As far as I understand it, the PulseAll is not required to be inside the lock (according to the pthreads implementation).</description>
		<content:encoded><![CDATA[<p>Thanks the link Ivan, I will look into it. As far as I understand it, the PulseAll is not required to be inside the lock (according to the pthreads implementation).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ivan Levashew</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-24910</link>
		<dc:creator>Ivan Levashew</dc:creator>
		<pubDate>Fri, 26 Sep 2008 11:21:22 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-24910</guid>
		<description>I&#039;ve found a discussion on this topic:

http://thread.gmane.org/gmane.os.ecos.general/13018</description>
		<content:encoded><![CDATA[<p>I&#8217;ve found a discussion on this topic:</p>
<p><a href="http://thread.gmane.org/gmane.os.ecos.general/13018" rel="nofollow">http://thread.gmane.org/gmane.os.ecos.general/13018</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ivan Levashew</title>
		<link>http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/comment-page-1/#comment-24844</link>
		<dc:creator>Ivan Levashew</dc:creator>
		<pubDate>Wed, 24 Sep 2008 11:43:12 +0000</pubDate>
		<guid isPermaLink="false">http://blog.gurock.com/postings/condition-variables-and-monitors-for-delphi/266/#comment-24844</guid>
		<description>Producer might Pulse condvar when consumer has owned mutex but is not waiting on condvar yet. Consumer will have to wait the whole timeout or infinitelly.

Timeout in ThreadsDemo is 250 so it won&#039;t cause serious problems in this particular case.</description>
		<content:encoded><![CDATA[<p>Producer might Pulse condvar when consumer has owned mutex but is not waiting on condvar yet. Consumer will have to wait the whole timeout or infinitelly.</p>
<p>Timeout in ThreadsDemo is 250 so it won&#8217;t cause serious problems in this particular case.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
