Well, I certainly saw strange behaviour. The trylock code seemed to be the
prime culprit - it tried to decrement the "waking" count, but it could end
up doing it too late so that people had already seen a increment from a
concurrent "up()".
I'm not saying the new code is bug-free, but it works for me where the old
one did not - and your claim that it is obviously broken is also obviously
wrong, see later..
> Your new semaphores seems completly buggy to me and I am surprised your
> kernel works without crash or corruption with them.
Well, you're not counting right..
> task1 task2 task3 -> effect -> count sleepers
> ----- ----- ----- ----- --------
> 1 0
>
> ------- task 0 does a down() ------------------ 0 0
> ------- here task 1,2,3 try to get the lock ---
>
> down() -1 1
> (I avoided the details here)
> schedule()
> down() -2 1
> spin_lock()
> sleepers++ -2 2
> add_neg(1) -1??? 2
> sleepers = 1 -1 1
> schedule()
> down()
> spin_lock()
> sleepers++ -1 2
Wrong counting. The "down()" decremented count, so you have
-2 2
which is exactly right, and explains why there will _not_ be two users in
the critical region at the same time.
Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/