Boost logo

Boost :

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


From: "William Kempf" <sirwillard_at_[hidden]>
> --- In boost_at_[hidden], "Greg Colvin" <gcolvin_at_u...> wrote:
> > ...
> > I am fairly sure we can design a monitor/condition interface
> > that is no less efficient than the primitives.
>
> Hardly. A monitor will require the functionality to wait. In other
> words, it requires a CV...

It was only yesterday I hit on a way to provide for multiple
conditions safely. Here is my current interface (which I was
going to put off posting) in which the monitor class can be a
mutex or critical section, the lock class can do simple mutual
exclusion, and the wait class can work with the condition class
to provide multiple explicit queues. (WARNING, Uncompiled Code):

   class monitor {
   protected:

      struct lock { // enforce mutual exclusion
         lock(monitor*,
              int timeout_ms=-1);
         ~lock();
      };

      struct condition { // queue of waiting threads
         // ...
      };

      struct wait { // wait on condition queue
                                     // if predicate is true
         wait(monitor* this_monitor,
              lambda_functor predicate,
              condition,
              int timeout_ms=-1);

         wait(monitor* this_monitor,
              lambda_functor predicate,
              entry_condition, exit_condition,
              int timeout_ms=-1);

         ~wait(); // signals exit condition
      };

      struct timeout : exception {} // may be thrown by wait()

      ~monitor();
   };

The use of protected access serves as strong encouragement to
code in a monitor style by deriving from the monitor base class
and guarding every accessible member function with a lock or wait.
Here is an example that uses two condition variables (WARNING,
Uncompiled Code):

   class buffer : monitor {
      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 if_full(this,(free1==buf.size())(n),nonfull,nonempty);
         buf[p] = m;
         p = (p+1)%buf.size();
         ++n;
      }
      int receive() {
         wait if_empty(this,(free1==0)(n),nonempty,nonfull);
         int i = buf[c];
         c = (c+1)%buf.size();
         --n;
         return i;
      }
   };


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