src/Pure/Concurrent/single_assignment.ML
author wenzelm
Wed, 04 Jul 2018 22:44:24 +0200
changeset 68589 9258f16d68b4
parent 67009 b68592732783
child 70696 47ca5c7550e4
permissions -rw-r--r--
more frugal single-assignment according to David Matthews: dispose mutable lock/cond eventually;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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;