Suggestion for Condition variables

Graham St Jack grahams at acres.com.au
Sun Feb 26 21:39:20 PST 2006


Here is a suggestion for an extension to D to handle pthread-like 
condition variables in a way that fits neatly with the "synchronized" 
keyword.

I use threads a lot, and quite often find that I need conditions, but 
even though all the functionality is there in the locks library, it is 
galling that I can't use the same mutex as the "synchronized" keyword.

The alternatives seem to be to:
* Eliminate or ignore the synchronized keyword and use a library all the 
   time.
* Make the language "aware" of the library, and provide a way of getting 
an object's mutex.
* Add some more keywords to handle conditions directly.

My suggestion is for the last, because I like synchronized, and because 
I don't like making the language aware of the libraries.


So, the suggestion is to add:

* A "condition" keyword that behaves for the most part just like a bool 
data type, but is actually a condition variable.

* A "waitfor" keyword. It would be used like:
   waitfor (condition_name);
   to wait for the condition to become true, and
   waitfor (condition_name; timeout_value);
   to wait for the condition to come true, or the timeout period to 
expire. Timeout could be ulong nanoseconds, for instance.

Here is a simple example with two conditions in a class in 
fast-and-loose pseudo-code. The two conditions are used to show how 
simple this arrangement can be compared to trying the same thing in 
Java, which has  a limit of one condition per object.

The example Queue class is used to facilitate the transfer of data 
between two threads - a supplier and a worker. The supplier calls 
finalize() when it wants the worker to terminate, blocking until all the 
work has been done.


class Queue {

   bool finalizing;
   condition ready;
   condition done;

   // add an item to the queue - called by a supplier thread
   synchronized void add(int item) {
     ...add item to back of a queue...
     ready = true;
   }

   // remove an item from the queue - called by a worker thread
   synchronized int remove() {
     waitfor (ready);
     if (...queue is empty...) {
       done = true;
       throw new FinalisedException();
     }
     int item = ...remove item from front of queue...
     ready = !(...queue is empty...) || finalizing;
     return item;
   }

   // finalize the queue - normally called by the supplier thread
   synchronized void finalize() {
     finalizing = true;
     ready = true;
     waitfor (done; timeout_value);
     if (!done)
       throw new TimeoutException();
   }
}

The compiler can do all the necessary stuff like:
* re-evaluating the condition after waking up, and waiting again if the 
condition has been cleared by a critical race.
* making it an error to use conditions outside of synchronized methods.

I think this is much tidier than the Java approach, and it is certainly 
a whole lot easier than using pthread conditions - even through a library.



More information about the Digitalmars-d mailing list