Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-18 16:44:59


--- In boost_at_[hidden], brent verner <brent_at_r...> wrote:
> On 18 Aug 2000 at 19:28 (-0000), William Kempf wrote:
> | --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> | > Earlier I suggested that the lock, wait condition, and notify
could
> | be
> | > combined into a single object with a templated constructor.
> |
> | This doesn't address the problem. Just combining them into a
single
> | object won't solve the problem of needing the mutex to be locked
> | during calls to wait() and notify().
> |
> | Besides, the lock can't be combined in this way, and combining
the
> | mutex and condition forces us to a one-to-one relationship.
Since it
>
> I have always (right or wrong) seen a one-to-one relationship with
> condition->mutex, but that mutex could usefully be locked outside
> of the condition... i.e. to suspend the conditions wait() state
> from a controlling thread, since the condition must lock then unlock
> its mutex to enter the waiting state.
>
> (I ramble... trying to see your point... excuse me... play along...)
> if a number of (different) conditions share a mutex, a thread
waiting
> on its condition will be run -- acquiring the mutex. the mutex
becomes
> a serialization point for the (different) conditions that use it...
> ah, I see... yes this would be useful. thank you for stretching my
> mind :)

A classic example is the bounded buffer example given for the monitor
construct. It's most often implemented with a single condition that
waits on two seperate predicates, not full and not empty. The code
can be made more efficient, however, by using two conditions that
wait on only one of the two predicates. (How much more efficient is
debatable and this may not be the best example when examined only for
efficiency.)

> | can be very beneficial to use multiple conditions with a single
mutex
> | I don't want to combine these two concepts. Not to mention not
> | wanting to force the overhead of a condition on everyone that
uses a
> | mutex.
>
> I agree with you. CV has a mutex. It would not be that difficult to
> have two ctors for a CV, would it?
>
> basic_mutex* __m;
> bool __del_m;
> basic_condition() : __m( new basic_mutex() ) : __del_m(true) { }
> basic_condition( basic_mutex* m ) : __m( m ) : __del_m(false) { }

No, this isn't difficult, but it doesn't address the problem. The
mutex must actually be locked by a thread before it can call wait()
or notify(). The wait() is the most obvious since it will do an
unlock/wait/lock operation. Since it's so obvious we immediately
tried to insure that we were locked at this point by simply passing a
lock into the wait instead of passing in the mutex.

The problem is, we also must insure that we're locked on the call to
notify. This isn't as easy to solve, at least cleanly. Basically,
the mutex and condition must have a one-to-many relationship (one
mutex to one or more conditions), so the mutex must be tied to the CV
at construction. At this time it no longer makes sense to pass a
lock into wait() since we've already got access to the mutex, though
we could do this just to insure we're locked at compile time. It
makes even less sense to pass a lock to notify(), though, since notify
() won't effect the lock/mutex in any way. Further, passing it in
like this is now an artificial improvement, since the lock may well
not be a lock on the specific mutex instance that we're tied to.

Right now the best I can see is throwing an exception if the mutex
isn't locked on a call to either method. Unfortunately this means
two things: we must have an is_locked() method on mutexes that
indicates if the thread that calls it owns a lock on the mutex, and
the check for the error will occur at run time instead of compile
time. I can live with these if we have to, but I was wondering if
anyone had any thoughts on how to get a compile time error out of
this.

Or do we take the pthreads approach and simply have the relationship
be an artificial one where if you don't follow the rules we simply
have undefined behavior?

Bill Kempf


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