
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