On 3/2/11 8:50 PM, Martin Simmons wrote:
I think that the implementation of condition-wait has some major problems:
Thanks very much for the comments.
I have an [updated patch][1] that attempts to address these issues for further review for inclusion in BORDEAUX-THREADS.
[1]: http://detroit.slack.net/~evenson/abcl/bordeaux-threads-abcl-20110318a.diff
- If no other threads are trying to claim the lock, then
condition-wait will return immediately rather than waiting.
I couldn't reproduce this behavior. In ABCL, the THREADS:OBJECT-WAIT implementation is mainly a simple wrapping of the underlying [java.lang.Object.wait()][2] which clearly should wait.
[2]: http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#wait%28%2...
- If two threads are waiting in condition-wait and two other threads
call condition-notify, then it is possible that only one thread will return from condition-wait because the call to acquire-lock in one of them might return nil causing it to wait again.
The DO looping construct has been replaced with a simpler subsequent BT:ACQUIRE-LOCK that should solve this bug.
- If condition-notify is called by one thread when a waiting thread
is just about to enter the threads:synchronized-on form (but before it gets synchronized), then the notify will be lost. This happens because the underlying threading primitives have no "memory" of calls to notify when nothing it waiting (which is also the expected semantics for POSIX condition variables BTW).
THREADS:SYNCHRONIZED-ON is now the first form executed by BT:CONDITION-WAIT so the window here is considerably narrowed.
Also, I think condition-notify should be using threads:object-notify rather than threads:object-notify-all.
We now use THREADS:OBJECT-NOTIFY.
That is a particularly scary statement. Narrowing the window really means you are less likely to discover the bug in testing and more likely (because of Murphey's law and longer use) to discover it in production use. Can this be fixed without the reliance on luck?
On Fri, Mar 18, 2011 at 3:12 AM, Mark Evenson evenson@panix.com wrote:
On 3/2/11 8:50 PM, Martin Simmons wrote:
- If condition-notify is called by one thread when a waiting thread
is just about to enter the threads:synchronized-on form (but before it gets synchronized), then the notify will be lost. This happens because the underlying threading primitives have no "memory" of calls to notify when nothing it waiting (which is also the expected semantics for POSIX condition variables BTW).
THREADS:SYNCHRONIZED-ON is now the first form executed by BT:CONDITION-WAIT so the window here is considerably narrowed.
On 3/18/11 2:38 PM, Blake McBride wrote:
That is a particularly scary statement. Narrowing the window really means you are less likely to discover the bug in testing and more likely (because of Murphey's law and longer use) to discover it in production use. Can this be fixed without the reliance on luck?
On Fri, Mar 18, 2011 at 3:12 AM, Mark Evensonevenson@panix.com wrote:
On 3/2/11 8:50 PM, Martin Simmons wrote:
- If condition-notify is called by one thread when a waiting thread
is just about to enter the threads:synchronized-on form (but before it gets synchronized), then the notify will be lost. This happens because the underlying threading primitives have no "memory" of calls to notify when nothing it waiting (which is also the expected semantics for POSIX condition variables BTW).
THREADS:SYNCHRONIZED-ON is now the first form executed by BT:CONDITION-WAIT so the window here is considerably narrowed.
The current implementation is about as bare as one can get:
(defun condition-wait (condition lock) (threads:synchronized-on condition (release-lock lock) (threads:object-wait condition)) (acquire-lock lock))
I think all implementations of CONDITION-WAIT would have such a window as the environment gets setup to make the control transfer.
Maybe one could turn the CONDITION-WAIT into a macro?
On 18 March 2011 16:46, Mark Evenson evenson@panix.com wrote:
THREADS:SYNCHRONIZED-ON is now the first form executed by BT:CONDITION-WAIT so the window here is considerably narrowed.
The current implementation is about as bare as one can get: (defun condition-wait (condition lock) (threads:synchronized-on condition (release-lock lock) (threads:object-wait condition)) (acquire-lock lock)) I think all implementations of CONDITION-WAIT would have such a window as the environment gets setup to make the control transfer. Maybe one could turn the CONDITION-WAIT into a macro?
Where's the race window? condition-wait is always called with the lock held.
On 18 March 2011 10:12, Mark Evenson evenson@panix.com wrote:
- If no other threads are trying to claim the lock, then
condition-wait will return immediately rather than waiting.
I couldn't reproduce this behavior. In ABCL, the THREADS:OBJECT-WAIT
That obviously shouldn't happen. The wait should block until a notify arrives.
- If two threads are waiting in condition-wait and two other threads
Two threads can't be waiting in condition wait, the wait must be surrounded by the same lock, so two threads can't arrive to the condition wait simultaneously.
- If condition-notify is called by one thread when a waiting thread
is just about to enter the threads:synchronized-on form (but before it gets synchronized), then the notify will be lost. This happens
Sure, but condition variables require a lock-check-wait-check cycle. Lost nofitications shouldn't be a problem because the check will pass if the condition was already signalled.
Or are these conditions drastically different from how pthread conditions work?
On 3/18/11 4:39 PM, Ville Voutilainen wrote: […]
Or are these conditions drastically different from how pthread conditions work?
They are defined by BORDEAUX-THREADS to be *exactly* pthread conditions. You can read a bit more [in the default-implementations docstrings][1].
[1]; http://common-lisp.net/gitweb?p=projects/bordeaux-threads/bordeaux-threads.g...
armedbear-devel@common-lisp.net