|
Boost : |
From: Aaron W. LaFramboise (aaronrabiddog51_at_[hidden])
Date: 2004-07-05 17:27:28
Tyson Whitehead wrote:
> The current Win32 doesn't have the counter problems, and claims to be able to
> yield to lower priority threads, so it should be okay. The relevant lock
> routine is (m_.l_ is initialized to 0):
>
> while( InterlockedExchange(&m_.l_, 1) ){
> // Note: changed to Sleep(1) from Sleep(0).
> // According to MSDN, Sleep(0) will never yield
> // to a lower-priority thread, whereas Sleep(1)
> // will. Performance seems not to be affected.
> Sleep(1);
> }
For what its worth, while it avoids deadlocking problems, this code is
also wrong.
Synchronization code should never sleep. That code above will actually
sleep for the minimum amount of time Windows allows, which is usually
10ms. I measured the performance of this spinlock a while back when
improvements to GCC's Windows mutexes were being discussed on the MinGW
lists, and in some cases where there is substanctial contention over
short-lived locks, the performance degradation is quite unacceptable.
Certain naïve benchmarks might not notice, though, because during the
period waiters are sleeping, the lock will be accessable.
I think the code above could lead to severe slowdowns in some usage
cases, and could lead to difficult to diagnose intermittant 'blips' of
bad performance in others.
In any case, my point is that spinlocks are always going to be wrong in
these sorts of situations unless coupled with some other primative. In
fact, spinning at all is usually the wrong thing to do. On single CPU
systems, it is always a waste of precious time. On multi CPU systems,
it can cause very undesirable memory bus slowdowns.
The best general locking strategy I have seen--which is used by Linux
futexes and GCC for Windows' new locks--is where a normal scheduler
locking primative is wrapped by a quick userspace atomic operation to
avoid locking in the noncontended case. The downside is that, on
Windows for example, this will require 8 bytes of storage. I'm not sure
how shared_ptr uses mutexes, but this might not be acceptable.
These spinlocks need to be fixed. Is anyone working on this?
Aaron W. LaFramboise
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk