| author | wenzelm |
| Wed, 10 Apr 2019 15:10:43 +0200 | |
| changeset 70105 | eadd87383e30 |
| parent 68675 | 4535a45182d5 |
| child 77998 | cad50a7c8091 |
| permissions | -rw-r--r-- |
| 28578 | 1 |
(* Title: Pure/Concurrent/synchronized.ML |
2 |
Author: Fabian Immler and Makarius |
|
3 |
||
| 56685 | 4 |
Synchronized variables. |
| 28578 | 5 |
*) |
6 |
||
7 |
signature SYNCHRONIZED = |
|
8 |
sig |
|
9 |
type 'a var |
|
10 |
val var: string -> 'a -> 'a var |
|
| 28580 | 11 |
val value: 'a var -> 'a |
|
68597
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
12 |
val assign: 'a var -> 'a -> unit |
| 28580 | 13 |
val timed_access: 'a var -> ('a -> Time.time option) -> ('a -> ('b * 'a) option) -> 'b option
|
14 |
val guarded_access: 'a var -> ('a -> ('b * 'a) option) -> 'b
|
|
| 28578 | 15 |
val change_result: 'a var -> ('a -> 'b * 'a) -> 'b
|
16 |
val change: 'a var -> ('a -> 'a) -> unit
|
|
17 |
end; |
|
18 |
||
19 |
structure Synchronized: SYNCHRONIZED = |
|
20 |
struct |
|
21 |
||
| 56692 | 22 |
(* state variable *) |
| 28578 | 23 |
|
|
68597
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
24 |
datatype 'a state = |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
25 |
Immutable of 'a |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
26 |
| Mutable of {lock: Mutex.mutex, cond: ConditionVar.conditionVar, content: 'a};
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
27 |
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
28 |
fun init_state x = |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
29 |
Mutable {lock = Mutex.mutex (), cond = ConditionVar.conditionVar (), content = x};
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
30 |
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
31 |
fun immutable_fail name = raise Fail ("Illegal access to immutable value " ^ name);
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
32 |
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
33 |
abstype 'a var = Var of {name: string, state: 'a state Unsynchronized.ref}
|
|
35015
efafb3337ef3
removed slightly adhoc single-assignment feature, cf. structure Single_Assignment;
wenzelm
parents:
33060
diff
changeset
|
34 |
with |
| 28578 | 35 |
|
|
68597
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
36 |
fun var name x = |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
37 |
Var {name = name, state = Unsynchronized.ref (init_state x)};
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
38 |
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
39 |
fun value (Var {name, state}) =
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
40 |
(case ! state of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
41 |
Immutable x => x |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
42 |
| Mutable {lock, ...} =>
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
43 |
Multithreading.synchronized name lock (fn () => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
44 |
(case ! state of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
45 |
Immutable x => x |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
46 |
| Mutable {content, ...} => content)));
|
| 28578 | 47 |
|
|
68597
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
48 |
fun assign (Var {name, state}) x =
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
49 |
(case ! state of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
50 |
Immutable _ => immutable_fail name |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
51 |
| Mutable {lock, cond, ...} =>
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
52 |
Multithreading.synchronized name lock (fn () => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
53 |
(case ! state of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
54 |
Immutable _ => immutable_fail name |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
55 |
| Mutable _ => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
56 |
Thread_Attributes.uninterruptible (fn _ => fn () => |
|
68675
4535a45182d5
updated to polyml-5.7.1-7 (see also afa7c5a239e6);
wenzelm
parents:
68597
diff
changeset
|
57 |
(state := Immutable x; RunCall.clearMutableBit state; |
|
68597
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
58 |
ConditionVar.broadcast cond)) ()))); |
| 28580 | 59 |
|
| 28578 | 60 |
|
61 |
(* synchronized access *) |
|
62 |
||
|
68597
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
63 |
fun timed_access (Var {name, state}) time_limit f =
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
64 |
(case ! state of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
65 |
Immutable _ => immutable_fail name |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
66 |
| Mutable {lock, cond, ...} =>
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
67 |
Multithreading.synchronized name lock (fn () => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
68 |
let |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
69 |
fun try_change () = |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
70 |
(case ! state of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
71 |
Immutable _ => immutable_fail name |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
72 |
| Mutable {content = x, ...} =>
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
73 |
(case f x of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
74 |
NONE => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
75 |
(case Multithreading.sync_wait (time_limit x) cond lock of |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
76 |
Exn.Res true => try_change () |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
77 |
| Exn.Res false => NONE |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
78 |
| Exn.Exn exn => Exn.reraise exn) |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
79 |
| SOME (y, x') => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
80 |
Thread_Attributes.uninterruptible (fn _ => fn () => |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
81 |
(state := Mutable {lock = lock, cond = cond, content = x'};
|
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
82 |
ConditionVar.broadcast cond; SOME y)) ())); |
|
afa7c5a239e6
more frugal assignment of lazy value: fewer mutexes, condvars;
wenzelm
parents:
64276
diff
changeset
|
83 |
in try_change () end)); |
|
33060
e66b41782cb5
support single-assigment variables -- based on magic RTS operations by David Matthews;
wenzelm
parents:
32738
diff
changeset
|
84 |
|
| 62918 | 85 |
fun guarded_access var f = the (timed_access var (fn _ => NONE) f); |
| 28580 | 86 |
|
87 |
||
88 |
(* unconditional change *) |
|
89 |
||
90 |
fun change_result var f = guarded_access var (SOME o f); |
|
| 28578 | 91 |
fun change var f = change_result var (fn x => ((), f x)); |
92 |
||
|
35015
efafb3337ef3
removed slightly adhoc single-assignment feature, cf. structure Single_Assignment;
wenzelm
parents:
33060
diff
changeset
|
93 |
end; |
|
33060
e66b41782cb5
support single-assigment variables -- based on magic RTS operations by David Matthews;
wenzelm
parents:
32738
diff
changeset
|
94 |
|
| 28578 | 95 |
end; |