more on "Future values";
authorwenzelm
Sat, 21 Jun 2014 21:33:00 +0200
changeset 58690a6b1847b6335
parent 58689 5c8f4a35d8d7
child 58691 4817154180d6
more on "Future values";
src/Doc/Implementation/ML.thy
     1.1 --- a/src/Doc/Implementation/ML.thy	Sat Jun 21 12:19:34 2014 +0200
     1.2 +++ b/src/Doc/Implementation/ML.thy	Sat Jun 21 21:33:00 2014 +0200
     1.3 @@ -2161,4 +2161,127 @@
     1.4  *}
     1.5  
     1.6  
     1.7 +text %mlref {*
     1.8 +  \begin{mldecls}
     1.9 +  @{index_ML_type "'a future"} \\
    1.10 +  @{index_ML Future.fork: "(unit -> 'a) -> 'a future"} \\
    1.11 +  @{index_ML Future.forks: "Future.params -> (unit -> 'a) list -> 'a future list"} \\
    1.12 +  @{index_ML Future.value: "'a -> 'a future"} \\
    1.13 +  @{index_ML Future.join: "'a future -> 'a"} \\
    1.14 +  @{index_ML Future.map: "('a -> 'b) -> 'a future -> 'b future"} \\
    1.15 +  @{index_ML Future.cancel: "'a future -> unit"} \\
    1.16 +  @{index_ML Future.cancel_group: "Future.group -> unit"} \\[0.5ex]
    1.17 +  @{index_ML Future.promise: "(unit -> unit) -> 'a future"} \\
    1.18 +  @{index_ML Future.fulfill: "'a future -> 'a -> unit"} \\
    1.19 +  \end{mldecls}
    1.20 +
    1.21 +  \begin{description}
    1.22 +
    1.23 +  \item Type @{ML_type "'a future"} represents future values over type
    1.24 +  @{verbatim "'a"}.
    1.25 +
    1.26 +  \item @{ML Future.fork}~@{text "(fn () => e)"} registers the unevaluated
    1.27 +  expression @{text e} as unfinished future value, to be evaluated eventually
    1.28 +  on the parallel worker-thread farm. This is a shorthand for @{ML
    1.29 +  Future.forks} below, with default parameters and a single expression.
    1.30 +
    1.31 +  \item @{ML Future.forks}~@{text "params exprs"} is the general interface to
    1.32 +  fork several futures simultaneously. The @{text params} consist of the
    1.33 +  following fields:
    1.34 +
    1.35 +  \begin{itemize}
    1.36 +
    1.37 +  \item @{text "name : string"} (default @{ML "\"\""}) specifies a common name
    1.38 +  for the tasks of the forked futures, which serves diagnostic purposes.
    1.39 +
    1.40 +  \item @{text "group : Future.group option"} (default @{ML NONE}) specifies
    1.41 +  an optional task group for the forked futures. @{ML NONE} means that a new
    1.42 +  sub-group of the current worker-thread task context is created. If this is
    1.43 +  not a worker thread, the group will be a new root in the group hierarchy.
    1.44 +
    1.45 +  \item @{text "deps : Future.task list"} (default @{ML "[]"}) specifies
    1.46 +  dependencies on other future tasks, i.e.\ the adjacency relation in the
    1.47 +  global task queue. Dependencies on already finished future tasks are
    1.48 +  ignored.
    1.49 +
    1.50 +  \item @{text "pri : int"} (default @{ML 0}) specifies a priority within the
    1.51 +  task queue.
    1.52 +
    1.53 +  Typically there is only little deviation from the default priority @{ML 0}.
    1.54 +  As a rule of thumb, @{ML "~1"} means ``low priority" and @{ML 1} means
    1.55 +  ``high priority''.
    1.56 +
    1.57 +  Note that the priority only affects the position in the task queue, not a
    1.58 +  thread priority. When a worker thread picks up a task for processing, it
    1.59 +  runs with the normal thread priority to the end (or until canceled). Higher
    1.60 +  priority tasks that are queued later need to wait until this (or another)
    1.61 +  worker thread becomes free again.
    1.62 +
    1.63 +  \item @{text "interrupts : bool"} (default @{ML true}) tells whether the
    1.64 +  worker thread that processes the corresponding task is initially put into
    1.65 +  interruptible state. Note that it may change this state later while running,
    1.66 +  by modifying the thread attributes.
    1.67 +
    1.68 +  With interrupts disabled, a running future task cannot be canceled.  It is
    1.69 +  the responsibility of the programmer that this special state is retained
    1.70 +  only briefly.
    1.71 +
    1.72 +  \end{itemize}
    1.73 +
    1.74 +  \item @{ML Future.value}~@{text a} wraps the value @{text a} as finished
    1.75 +  future value, bypassing the worker-thread farm. When joined, it returns
    1.76 +  @{text a} without any further evaluation.
    1.77 +
    1.78 +  The overhead of this pro-forma wrapping of strict values as future values is
    1.79 +  very low.
    1.80 +
    1.81 +  \item @{ML Future.join}~@{text x} retrieves the value of an already finished
    1.82 +  future, which may lead to an exception, according to the result of its
    1.83 +  previous evaluation.
    1.84 +
    1.85 +  For an unfinished future there are several cases depending on the role of
    1.86 +  the current thread and the status of the future. A non-worker thread waits
    1.87 +  passively until the future is eventually evaluated. A worker thread
    1.88 +  temporarily changes its task context and takes over the responsibility to
    1.89 +  evaluate the future expression on the spot; this is done in a thread-safe
    1.90 +  manner: other threads that intend to join the same future need to wait until
    1.91 +  the ongoing evaluation is finished.
    1.92 +
    1.93 +  Excessive use of dynamic dependencies of futures by adhoc joining may lead
    1.94 +  to bad utilization of CPU cores, due to threads waiting on other threads to
    1.95 +  finish required futures. The future task farm has a limited amount of
    1.96 +  replacement threads that continue working on other tasks after some timeout.
    1.97 +
    1.98 +  Whenever possible, static dependencies of futures should be specified
    1.99 +  explicitly when forked. Thus the evaluation can work from the bottom up,
   1.100 +  without join conflicts and wait states.
   1.101 +
   1.102 +  \item @{ML Future.map}~@{text "f x"} is a fast-path implementation of @{ML
   1.103 +  Future.fork}~@{text "(fn () => f ("}@{ML Future.join}~@{text "x))"}, which
   1.104 +  avoids the full overhead of the task queue and worker-thread farm as far as
   1.105 +  possible. The function @{text f} is supposed to be some trivial
   1.106 +  post-processing or projection of the future result.
   1.107 +
   1.108 +  \item @{ML Future.cancel}~@{text "x"} cancels the task group of the given
   1.109 +  future, using @{ML Future.cancel_group} below.
   1.110 +
   1.111 +  \item @{ML Future.cancel_group}~@{text "g"} cancels all tasks of the given
   1.112 +  group for all time. Threads that are presently processing a task of the
   1.113 +  given group are interrupted. Tasks that are queued but not yet processed are
   1.114 +  dequeued and forced into interrupted state. Since the task group is itself
   1.115 +  invalidated, any further attempt to fork a future that belongs to it will
   1.116 +  yield a canceled result as well.
   1.117 +
   1.118 +  \item @{ML Future.promise}~@{text abort} registers a passive future with the
   1.119 +  given @{text abort} operation: it is invoked when the future task group is
   1.120 +  canceled.
   1.121 +
   1.122 +  \item @{ML Future.fulfill}~@{text "x a"} finishes the passive future @{text
   1.123 +  x} by the given value @{text a}. If the promise has already been canceled,
   1.124 +  the attempt to fulfill it causes an exception.
   1.125 +
   1.126 +  \end{description}
   1.127 +*}
   1.128 +
   1.129 +
   1.130  end