1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
package examples.pilib
import scala.concurrent.pilib._
/** Solution of exercise session 6 (first question). */
object semaphore {
class Signal extends Chan[Unit] {
def send = write(())
def receive = read
}
/** Interface. */
trait Semaphore {
def get: Unit
def release: Unit
}
/** First implementation. */
class Sem1 extends Semaphore {
private val g = new Signal
private val r = new Signal
def get: Unit = g.send
def release: Unit = r.send
private def Sched: Unit = choice (
g * (x => { r.receive; Sched }),
r * (x => Sched)
)
spawn< Sched >
}
/** Second implementation. */
class Sem2 extends Semaphore {
private val a = new Signal
private val na = new Signal
def get { a.receive; spawn< na.send > }
def release: Unit = choice (
a * (x => spawn< a.send >),
na * (x => spawn< a.send >)
)
spawn< a.send >
}
/** Test program. */
def main(args: Array[String]) {
val random = new util.Random()
val sem = new Sem2
def mutex(p: => Unit) { sem.get; p; sem.release }
spawn< {
Thread.sleep(1 + random.nextInt(100));
mutex( {
println("a1");
Thread.sleep(1 + random.nextInt(100));
println("a2")
} )
} | {
Thread.sleep(1 + random.nextInt(100));
mutex( {
println("b1");
Thread.sleep(1 + random.nextInt(100));
println("b2")
} )
} >;
}
}
|