From: Anthony Williams (anthony_w.geo_at_[hidden])
Date: 2006-10-08 05:29:27
Thanks for your feedback.
"Cory Nelson" <phrosty_at_[hidden]> writes:
> On 10/5/06, Anthony Williams <anthony_w.geo_at_[hidden]> wrote:
>> I have revamped the code on the threads_rewrite branch for the mutex and
>> 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?
I would certainly think it worth having multiple mutexes supporting various
levels of locking. Howard's proposal (N2094, see
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html) has 4
levels --- simple mutex, mutex with shared/exclusive locks, mutex with
shared/exclusive locks where the shared ones can "try" to convert to an
exclusive lock, and mutex with shared/exclusive/upgradeable locks. This is an
implementation of the latter, since I deemed it the hardest to get right.
> 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.
Yes, it's worth considering. I would be intrigued to see what difference it
made. I have a dual-core system and a single-core system, so I could see how
it performed on both with/without spinning. Any ideas for how to construct a
> 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.
Howard's proposal has them as public members, so that's what I implemented.
I can see the arguments both ways. Making the functions private is
easy, and what boost does already.
There are certainly use cases where pure scoped locks get in the way.
-- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
Boost list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk