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 {

      struct lock { // enforce mutual exclusion
              int timeout_ms=-1);

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

      struct wait { // wait on condition queue
                                     // if predicate is true
         wait(monitor* this_monitor,
              lambda_functor predicate,
              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()


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

Boost list run by bdawes at, gregod at, cpdaniel at, john at