[Contents]
[Prev] [Next] [Limbo Basics] [Limbo Programming] [Language Definition]

Monitors

Statically allocated storage within a module is accessible to all the functions of that module, and there is no explicit mechanism in Limbo for synchronizing concurrent updates to this storage from several tasks. However, it is straightforward to build a variety of concurrence-control mechanisms by using channel communications.

An example is a module that implements a Monitor abstract data type. Each instance of Monitor has a lock and an unlock operation; calling lock delays if another task holds the lock; calling unlock releases the lock and enables any other task attempting to execute lock.

implement Mon;

Mon: module{
	Monitor: adt {
		create:	fn(): Monitor;
		lock:	fn(m: self Monitor);
		unlock:	fn(m: self Monitor);
		ch:	chan of int;
	};
};

Monitor.create(): Monitor {
	m := Monitor(chan of int);
	spawn lockproc(m.ch);
	return m;
}

Monitor.lock(m: self Monitor){
	m.ch <- = 0;
}

Monitor.unlock(m: self Monitor){
	<-m.ch;
}

lockproc(ch: chan of int){
	for (;;) {
		<-ch;		# wait for someone to lock
		ch <-= 0;		# wait for someone to unlock
	}
}

It would be used like this:

mp : Mon;
Monitor : import mp;
mp = load Mon "...";
lck := Monitor.create();
. . .
lck.lock();
# region of code to be protected;
# only one thread can execute here at once.
lck.unlock();

The create method of Monitor allocates an instance of a Monitor containing an initialized channel. It also creates a thread executed in the lockproc routine, which repeatedly reads from the channel, then writes on it. The values transmitted over the channel are of no interest; it is the pure fact of communication that is put to use. The lock routine sends a message; in the idle state, the lockproc thread reads it and the sender proceeds. Meanwhile, lockproc tries to send a message over the same channel. If another thread attempts to lock there is no reader for the channel, and so its transmission will block. At some point, the thread that gained the lock calls unlock which receives from the channel. Depending on timing, this reception enables execution of either lockproc or one of the threads attempting to send via lock.



[Contents]
[Prev] [Next] [Limbo Basics] [Limbo Programming] [Language Definition]

Copyright © 1998, Lucent Technologies, Inc. All rights reserved.