Boost logo

Boost :

From: Roland Schwarz (roland.schwarz_at_[hidden])
Date: 2006-12-08 08:08:09


Yuval Ronen wrote:
> Well, I wouldn't dare argue with Butenhof, but:
>
> A. Even he says that with morphing, there is no difference. You
> mentioned that such morphing would require some OS support, and I agree.
> No doubt that synchronization primitives require OS support, and such
> support might not be available. Perhaps this point makes this discussion
> more appropriate for a POSIX forum, for example. I apologize if it has
> gone OT. Peter, in his post, claims that even with morphing there's a
> difference, because there's an optimization to avoid kernel call that
> can't be used when morphing is used in this case. Whether this
> optimization is a good enough reason to influence the CV interface is
> something that can be argued about.

Sorry, but I do not understand your point.

>
> B. Butenhof is talking about a theoretical, ideal OS, which Windows is
> known to be not... But seriously, if notify() requires the mutex to be
> locked - the same mutex locked during wait() - then the CV
> implementation can use this fact to synchronize its own members. I've
> been able to implements a CV on Windows with only one semaphore - rather
> than the current impl which uses 2 semaphores and an additional mutex.
> This means that there are much less sync objects to play with, and a
> simpler, more efficient code. Surely, as I'm not an expert, I might have
> some bugs in my impl, but I guess you can see the opportunities in
> requiring the user some stricter locking, to make the impl simpler.

There is a very long history of attempts to get condition variables
correct on windows. Most of them (just the seemingly simple and logical
ones) failing badly due to subtle bugs. Since there is no formal prove
available I think the most reasonable thing is to use the best known
algorithms which had undergone a extensive peer review. If you think you
can come up with something better, please move ahead, but be prepared
that it will be very hard to a) either give a formal prove of
correctness for your algorithm or b) survive review by the more
knowledgeable than I am.

> True, but requiring the mutex to be locked upon entering notify(), makes
> it more difficult for the user to forget locking.

This is what I don't quite understand:
How does it help when the condition holds a reference to a mutex to make
it more difficult for the user to forget locking?
You need to have the mutex locked _before_ you call the signal!

> Having
> the CV contain a reference to the mutex makes it hard to accidentally
> lock a different mutex for wait() and notify().

Ok, lets be more explicit:

   mutex m;
   condition c(m);

waiting:

   lock l(m);
   c.wait();

Ok, no need for l& in call to wait. But is this really better to avoid
mistakes? See:

   mutex m1;
   condition c1(m1);
   mutex m2;

waiting:

   lock l(m2);
   c.wait(); // ouch! this will lock the wrong one, and there is no
     apparent glue in the source.

Now to signaling:

   mutex m:
   condition c(m);

   lock l(m);
   c.notify_one(); // How is this different from current interface? How
do you make use of the referenced mutex?

> And locking while
> notifying has some objective advantages - it makes our threads respect
> the priority policy better, as Butenhof explains.

This again I cannot understand how it relates to your suggested change
in interface. I suggest being more explicit.

> Of course I didn't mean that the signal() will lock, signal, and unlock.
> I meant that the user will lock before calling notify().

Again: How does the referenced mutex help to achieve this goal?

About initialisation
...
> Easy:
>
> class foo {
> foo() : m(), c(m) { }
>
> mutex m;
> condition c;
> };

Agreed.

But you are giving away the possibility of sharing a condition variable
among several predicates. Altough this is not a recommended practice
since you can easily get it wrong, it is nevertheless a valid usage
scenario, which would be ruled out by your suggested change.

I do not think that we should forbid the alert user to use the interface
in uncommon (but not wrong) ways.

Roland


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk