forked from scala/scala
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemaphore.scala
72 lines (58 loc) · 1.43 KB
/
semaphore.scala
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
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")
} )
} >;
}
}