Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2000-08-09 18:59:59


From: <jpanzer_at_[hidden]>
> Thomas Holenstein wrote:
>
> > > Ok, to help people get a feel for what we want, I've written up a
> > > strawman concept description for Mutex and ReentrantMutex.
> > >
> > > http://www.lsc.nd.edu/~jsiek/Mutex.html
> >
> > Ok. When I could extend the class lock with notify() and wait(), I
> > can get something very much like a monitor with IMHO minimal effort.
> > I'll show you what I mean at the classical buffer: (This is mostly
> > stolen from Greg)
> >
> > public class SharedBuffer {
> > int p, c, full;
> > vector buf;
> > public
> > buffer(int n) : p(0), c(0), full(0), buf(n) {}
> >
> > void send(int m) {
> > X::lock l(*this);
> > if (full == buf.size()) l.wait();
> > buf[p] = m;
> > p = (p+1)%buf.size();
> > ++full;
> > if (full == 1) l.notify();
> > }
> >
> > int receive() {
> > X::lock l(*this);
> > if (full == 0) l.wait();
> > int i = buf[c];
> > c = (c + 1)%buf.size();
> > --full;
> > if (full == buf.size()-1) l.notify();
> > return i;
> > }
> > };
> >
> > I like this idea, to be honest. It's just a very bit different than
> > Jeremys, but I think it adds much flexibility.
>
> I like this (X should be SharedBuffer above, right? In which
> case SharedBuffer has to either inherit from something or
> provide the required nested typedefs, etc. itself.)
>
> I think that the wait/notify would be something applied to
> the resource, not the lock object.

Right. So it would go even more like my example:

  class SharedBuffer : mutex {
     int p, c, full;
     vector buf;
  public:
     buffer(int n) : p(0), c(0), full(0), buf(n) {}

  void send(int m) {
    lock l(*this);
     if (full == buf.size()) wait();
     buf[p] = m;
     p = (p+1)%buf.size();
     ++full;
     if (full == 1) notify();
   }

   int receive() {
     lock l(*this);
     if (full == 0) wait();
     int i = buf[c];
     c = (c + 1)%buf.size();
     --full;
     if (full == buf.size()-1) notify();
     return i;
   }
 };

Note the the explicit notifications above are an
example of my claim that performance is being gained
at the risk of deadlock. A good implementation of
the lock class could provide automatic notification
that is plenty fast enough if no thread is waiting.

> There are two things required of SharedBuffer above,
> mutual exclusion and notification. I think these
> should be separable for efficiency (sometimes you want
> mutual exclusion but don't need notification, and
> notification may require additional data for X.) Should
> this be a separate concept like "Waitable"?
>
> >
> > This way, you can get practical the same interface as with a monitor,
> > (but effectively, you are more flexible, as you don't need to lock
> > complete procedures)
> >
> > If some people want a timeout, I'd suggest throwing an exception after
> > a specified time.
>
> I think this would be a perfect place to use exceptions.

I think you just add a version of wait that takes a timeout
and returns a boolean indication of timeout. Then the caller
can decide whether to try again or give up. Where timeouts
are needed they are not exceptional.


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