author | wenzelm |
Thu, 18 Aug 2011 17:53:32 +0200 | |
changeset 44270 | 3eaad39e520c |
parent 44266 | d9c7bf932eab |
child 44271 | 89f40a5939b2 |
permissions | -rw-r--r-- |
44247 | 1 |
(* Title: Pure/Concurrent/par_exn.ML |
2 |
Author: Makarius |
|
3 |
||
4 |
Parallel exceptions as flattened results from acyclic graph of |
|
5 |
evaluations. Interrupt counts as neutral element. |
|
6 |
*) |
|
7 |
||
8 |
signature PAR_EXN = |
|
9 |
sig |
|
44249
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
10 |
val serial: exn -> serial * exn |
44247 | 11 |
val make: exn list -> exn |
44270
3eaad39e520c
more careful treatment of exception serial numbers, with propagation to message channel;
wenzelm
parents:
44266
diff
changeset
|
12 |
val dest: exn -> (serial * exn) list option |
44247 | 13 |
val release_all: 'a Exn.result list -> 'a list |
14 |
val release_first: 'a Exn.result list -> 'a list |
|
15 |
end; |
|
16 |
||
17 |
structure Par_Exn = |
|
18 |
struct |
|
19 |
||
44249
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
20 |
(* identification via serial numbers *) |
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
21 |
|
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
22 |
fun serial exn = |
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
23 |
(case get_exn_serial exn of |
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
24 |
SOME i => (i, exn) |
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
25 |
| NONE => let val i = Library.serial () in (i, set_exn_serial i exn) end); |
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
26 |
|
44270
3eaad39e520c
more careful treatment of exception serial numbers, with propagation to message channel;
wenzelm
parents:
44266
diff
changeset
|
27 |
val the_serial = the o get_exn_serial; |
3eaad39e520c
more careful treatment of exception serial numbers, with propagation to message channel;
wenzelm
parents:
44266
diff
changeset
|
28 |
|
3eaad39e520c
more careful treatment of exception serial numbers, with propagation to message channel;
wenzelm
parents:
44266
diff
changeset
|
29 |
val exn_ord = rev_order o int_ord o pairself the_serial; |
44249
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
30 |
|
64620f1d6f87
identify parallel exceptions where they emerge first -- to achieve unique results within evaluation graph;
wenzelm
parents:
44248
diff
changeset
|
31 |
|
44247 | 32 |
(* parallel exceptions *) |
33 |
||
44264 | 34 |
exception Par_Exn of exn list; |
35 |
(*non-empty list with unique identified elements sorted by exn_ord; |
|
36 |
no occurrences of Par_Exn or Exn.Interrupt*) |
|
44247 | 37 |
|
44264 | 38 |
fun par_exns (Par_Exn exns) = exns |
39 |
| par_exns exn = if Exn.is_interrupt exn then [] else [#2 (serial exn)]; |
|
44247 | 40 |
|
41 |
fun make exns = |
|
44264 | 42 |
(case Balanced_Tree.make (Ord_List.merge exn_ord) ([] :: map par_exns exns) of |
44247 | 43 |
[] => Exn.Interrupt |
44264 | 44 |
| es => Par_Exn es); |
44247 | 45 |
|
44270
3eaad39e520c
more careful treatment of exception serial numbers, with propagation to message channel;
wenzelm
parents:
44266
diff
changeset
|
46 |
fun dest (Par_Exn exns) = SOME (map (`the_serial) exns) |
3eaad39e520c
more careful treatment of exception serial numbers, with propagation to message channel;
wenzelm
parents:
44266
diff
changeset
|
47 |
| dest exn = if Exn.is_interrupt exn then SOME [] else NONE; |
44247 | 48 |
|
49 |
||
50 |
(* parallel results *) |
|
51 |
||
44266
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
52 |
fun release_all results = |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
53 |
if forall (fn Exn.Res _ => true | _ => false) results |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
54 |
then map Exn.release results |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
55 |
else raise make (map_filter Exn.get_exn results); |
44247 | 56 |
|
44266
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
57 |
fun plain_exn (Exn.Res _) = NONE |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
58 |
| plain_exn (Exn.Exn (Par_Exn _)) = NONE |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
59 |
| plain_exn (Exn.Exn exn) = if Exn.is_interrupt exn then NONE else SOME exn; |
44247 | 60 |
|
44248
6a3541412b23
clarified Par_Exn.release_first: traverse topmost list structure only, not arbitrary depths of nested Par_Exn;
wenzelm
parents:
44247
diff
changeset
|
61 |
fun release_first results = |
44266
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
62 |
(case get_first plain_exn results of |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
63 |
NONE => release_all results |
d9c7bf932eab
clarified Par_Exn.release_first: prefer plain exn, before falling back on full pack of parallel exceptions;
wenzelm
parents:
44264
diff
changeset
|
64 |
| SOME exn => reraise exn); |
44247 | 65 |
|
66 |
end; |
|
67 |