
On 10/5/06, Anthony Williams <anthony_w.geo@yahoo.com> wrote:
I have revamped the code on the threads_rewrite branch for the mutex and read_write_mutex.
The mutex code is now "swap-based", to eliminate the hand-off problems highlighted by Alexander Terekhov and Peter Dimov. It can be seen in CVS at boost/thread/win32/basic_timed_mutex.hpp on the thread_rewrite branch, or in the CVS web viewer at
It keeps track of the "active count" of threads with an interest in the mutex, in order to try and avoid signalling the semaphore unnecessarily.
The read_write_mutex code is based on ideas from the code offered by Peter Dimov and Cory Nelson. However, I have extended it to include upgradeable locks, and more closely mirror the interface proposed in the C++ Standard threading proposal N2094. At the moment it does not support try_ or timed_ variants. The code can be seen in CVS at boost/thread/win32/read_write_mutex.hpp on the thread_rewrite branch, or in the CVS web viewer at
In all cases, the code tries to change state using compare-and-swap instructions. If the current state is blocking the state change (e.g. there is already a writer when we try to lock a reader), then the lock blocks on one of three win32 Event objects. The shared event is a manual reset event, so once readers are allowed access, they are all freed until a thread obtains an exclusive lock and resets the event. There is a limit on how many threads can have a shared/upgradeable lock (0x1fff), and how many can be waiting for a write lock (0xfff). Given the nature of read-write mutexes, this could easily be adjusted to allow more shared locks, and fewer waiting writers.
I've just looked the reader-writer lock over, and while it generally seems "usable" to me, I've got a few nitpicks: 1) This seems like a real big general-purpose class that goes against the C++ism of not paying for what you aren't going to use. Creating three events (these are kernel objects) for each lock makes it a rather heavy instance - I feel like using of a lot of them for fine-grained locking won't be realistic. Given that the need to upgrade a lock is uncommon and usually easily worked around, and the ease a user can cause deadlock when upgrading, would you consider a separate lightweight non-upgradeable class to go alongside it? 2) It doesn't spin at all - giving an app a chance to stay away from WaitForSingleObject on multithreaded systems will be a good boost to scalability under typical use. Win32 critical sections have a default spin count of 4000 on multithreaded systems. With multi-core getting more and more common I think this is an important aspect to consider. 3) I don't like the lock(), unlock() etc member functions being public.. forcing scoped_lock is a great cheap idiom for exception safety and saving people from deadlocks. Even with scoped_lock also available - it isn't something found in other languages so I fear new developers will flock to using the simpler and more familiar public members instead.
Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Cory Nelson