author | wenzelm |
Wed, 04 Jul 2018 22:44:24 +0200 | |
changeset 68589 | 9258f16d68b4 |
parent 67009 | b68592732783 |
child 70696 | 47ca5c7550e4 |
permissions | -rw-r--r-- |
35014
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/Concurrent/single_assignment.ML |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
3 |
|
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
4 |
Single-assignment variables with locking/signalling. |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
5 |
*) |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
6 |
|
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
7 |
signature SINGLE_ASSIGNMENT = |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
8 |
sig |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
9 |
type 'a var |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
10 |
val var: string -> 'a var |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
11 |
val peek: 'a var -> 'a option |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
12 |
val await: 'a var -> 'a |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
13 |
val assign: 'a var -> 'a -> unit |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
14 |
end; |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
15 |
|
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
16 |
structure Single_Assignment: SINGLE_ASSIGNMENT = |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
17 |
struct |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
18 |
|
68589
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
19 |
datatype 'a state = |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
20 |
Set of 'a |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
21 |
| Unset of {lock: Mutex.mutex, cond: ConditionVar.conditionVar}; |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
22 |
|
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
23 |
fun init_state () = |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
24 |
Unset {lock = Mutex.mutex (), cond = ConditionVar.conditionVar ()}; |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
25 |
|
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
26 |
abstype 'a var = Var of {name: string, state: 'a state Unsynchronized.ref} |
35014
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
27 |
with |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
28 |
|
68589
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
29 |
fun var name = Var {name = name, state = Unsynchronized.ref (init_state ())}; |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
30 |
|
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
31 |
fun peek (Var {state, ...}) = (case ! state of Set x => SOME x | Unset _ => NONE); |
35014
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
32 |
|
68589
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
33 |
fun await (v as Var {name, state}) = |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
34 |
(case ! state of |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
35 |
Set x => x |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
36 |
| Unset {lock, cond} => |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
37 |
Multithreading.synchronized name lock (fn () => |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
38 |
let |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
39 |
fun wait () = |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
40 |
(case peek v of |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
41 |
NONE => |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
42 |
(case Multithreading.sync_wait NONE cond lock of |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
43 |
Exn.Res _ => wait () |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
44 |
| Exn.Exn exn => Exn.reraise exn) |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
45 |
| SOME x => x); |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
46 |
in wait () end)); |
35014
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
47 |
|
68589
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
48 |
fun assign_fail name = raise Fail ("Duplicate assignment to " ^ name); |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
49 |
fun assign (v as Var {name, state}) x = |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
50 |
(case ! state of |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
51 |
Set _ => assign_fail name |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
52 |
| Unset {lock, cond} => |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
53 |
Multithreading.synchronized name lock (fn () => |
35014
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
54 |
(case peek v of |
68589
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
55 |
SOME _ => assign_fail name |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
56 |
| NONE => |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
57 |
Thread_Attributes.uninterruptible (fn _ => fn () => |
9258f16d68b4
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
wenzelm
parents:
67009
diff
changeset
|
58 |
(state := Set x; RunCall.clearMutableBit state; ConditionVar.broadcast cond)) ()))); |
35014
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
59 |
|
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
60 |
end; |
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
61 |
|
a725ff6ead26
explicit representation of single-assignment variables;
wenzelm
parents:
diff
changeset
|
62 |
end; |