
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
http://boost.cvs.sourceforge.net/boost/boost/boost/thread/win32/basic_timed_...
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
http://boost.cvs.sourceforge.net/boost/boost/boost/thread/win32/read_write_m...
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