fcbotelho/lwlock — pull request #20 by ngrg (2014-08-17 09:17:22+00:00)
Title: Fix bug in delegate + counter code.

The old value when running the delegate loop needs to be tracked finely and needs
cooperation of the delegated jobs. This is to avoid falsely dropping the delegate lock
when the value changes back to the stale old value read before running queued jobs and we
end up not relooping. Concretely: we could have, in the counter case, the available value starts
at 1, we have 2 waiters, the 1st uses the count, it becomes 0. The 2nd sees 0 and says it should
block. Another thread calls free and makes it back into 1. The delegate thread then does the swap
to see if it should continue looping or break out. The atomic swap will succeed since the old value
was 1 and it is once again 1. The delegate loop will break when it should have looped back to assign
the 1 available to the waiter. By having the called values provide the value after their atomic ops,
we avoid this. We would be trying to swap with old value 0 when it has changed to 1, fail in swap, loop
again and assign the 1 to the new waiter.