Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2000-08-21 11:54:01


From: William Kempf <sirwillard_at_[hidden]>>
 --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> > From: "William Kempf" <sirwillard_at_m...>
> > > --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> > > > From: "William Kempf" <sirwillard_at_m...>
> > > > > --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> > > > > ...
> > > > > > Maybe I'm missing something, but I don't see why something
> like
> > > > > > following wouldn't work:
> > > > > >
> > > > > > struct mutex {
> > > > > > struct condition {
> > > > > > condition(mutex*);
> > > > > > bool wait(int);
> > > > > > void notify();
> > > > > > };
> > > > > > struct timeout_exception : exception {};
> > > > > > struct wait {
> > > > > > wait(mutex*, lambda_functor predicate,
> > > > > > condition in,condition out,int timeout=-1)
> > > > > > : mtx(mtx), in(in), out(out) {
> > > > > > mtx->enter();
> > > > > > do {
> > > > > > if (in.wait(timeout))
> > > > > > throw(timeout_exception());
> > > > > > } while(!predicate());
> > > > > > }
> > > > > > ~wait() {
> > > > > > out.notify();
> > > > > > mtx->exit();
> > > > > > }
> > > > > > mutex* mtx;
> > > > > > condition in;
> > > > > > condition out;
> > > > > > };
> > > > > > void enter();
> > > > > > void exit();
> > > > > > };
> > > > >
> > > > > You've attempted to solve the problem for wait which was
> already
> > > > > solved by passing in a lock instead of mutex, but have
> ignored
> > > the
> > > > > notify().
> > > >
> > > > What problem with notify() have I not solved? I've
> > > > set it up so that notify() is called only inside the
> > > > mutex. I left it without saying that during the calls
> > > > to wait() and notify() the lock (or locks) on the mutex
> > > > must be temporarily released.
> > >
> > > I missed the call to notify() in the destructor of wait. I asked
> you
> > > once before why you'd do that, and it makes even less sense here.
> >
> > Makes perfect sense to me. See the example code below.
> >
> > > You've set it up so the only way to notify a condition is by
> first
> > > waiting on a second condition. I don't see how this would even
> > > work. Who would notify your "in" condition? How would they
> insure
> > > at compile time that the mutex was locked? I see nothing solved
> here
> > > and see little purpose in having an "out" condition.
> >
> > Typically the conditions start out signaled, so the very
> > first attempt to wait on them returns immediately.
>
> This is not good. In your example below that means that notempty is
> signaled to begin with, but we are empty.

And the boolean expression fails.

> > > BTW, notify() does *NOT* temporarily release the mutex.
> >
> > Right, sorry.
> >
> > Here is the classic two-condition example, where after waiting on
> > nonfull you need to notify nonempty, and after waiting on nonempty
> > you need to notify nonfull.
> >
> > class buffer : mutex {
> > int p,c,n;
> > vector<int> buf;
> > condition nonfull, nonempty;
> > public:
> > buffer(int n) : p(0),c(0),n(0),buf(n){}
> > void send (int m) {
> > wait entry(this,(free1 == buf.size())(n),nonfull,nonempty);
> > buf[p] = m;
> > p = (p+1)%buf.size();
> > ++n;
> > }
> > int receive() {
> > wait entry(this,(free1 == 0)(n),nonempty,nonfull);
> > int i = buf[c];
> > c = (c+1)%buf.size();
> > --n;
> > return i;
> > }
> > };
>
> And if we have only one condition? What will you do then, use an
> artificial second condition just to satisfy the need for two
> conditions? What if we have three conditions we must wait on?

I previously presented a single condition variation, but
left it out of this example to keep it simple. Sorry.

I don't see any difficulty with more than two conditions.

> Again, I see no purpose to signal a second condition on exit of the
> wait in a general fashion. It may work in some specific cases, but
> it's pointless in most.

In a multi-queue setup you will always want to signal a condition
at the end of each handler. How else to make any progress?


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