My "simplified" version oversimplified out an assignment tracking the
count at the point of notification. This turns out to still be needed
to avoid mixups with intervening interrupts/signals. Also, counts
should be "long" to avoid overflow. Here's a better, still cheap,
version, with field blandly renamed to "count" because it changes
role. As before, this requires use of FIFO monitor wait queues. (The
ordering of lock (re)acquisition queues doesn't matter here though.)
1. Associate with each monitor
long notifyCounter;
2. Associate with each wait-queue Node
long count;
3. On entry into wait, make and enqueue wait-queue Node node, setting
node.count = monitor notifyCounter;
4. Before each return from notify of thread with Node node, do
node.count = monitor.notifyCounter++;
5. On exit from wait, if the thread associated with Node node
was interrupted after a notify, notify the head of wait-queue if
head.count <= node.count
When a thread is on wait-queue, its count is the generation number at
which it entered, but when taken off the queue, its count is the
generation number at which it was notified.
The head.count <= node.count check is now clearly (I hope) true only
if the thread at the head of the queue entered wait after the thread
that was later interrupted but before it was notified: We know that
head entered wait after node did because queue is FIFO. And we know
that head entered before node was notified because the counts are
accessed only while the lock is held, so the relevant reads and writes
are totally ordered.
-Doug
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:54 EDT