| author | wenzelm | 
| Wed, 17 May 2017 23:05:30 +0200 | |
| changeset 65860 | ce6be2e40d47 | 
| parent 62359 | 6709e51d5c11 | 
| child 69449 | b516fdf8005c | 
| permissions | -rw-r--r-- | 
| 52584 | 1 | (* Title: Pure/System/message_channel.ML | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Preferably asynchronous channel for Isabelle messages. | |
| 5 | *) | |
| 6 | ||
| 7 | signature MESSAGE_CHANNEL = | |
| 8 | sig | |
| 52800 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 9 | type message | 
| 56333 
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
 wenzelm parents: 
52800diff
changeset | 10 | val message: string -> Properties.T -> string list -> message | 
| 52584 | 11 | type T | 
| 52800 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 12 | val send: T -> message -> unit | 
| 52584 | 13 | val shutdown: T -> unit | 
| 14 | val make: System_Channel.T -> T | |
| 15 | end; | |
| 16 | ||
| 17 | structure Message_Channel: MESSAGE_CHANNEL = | |
| 18 | struct | |
| 19 | ||
| 52800 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 20 | (* message *) | 
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 21 | |
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 22 | datatype message = Message of string list; | 
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 23 | |
| 56333 
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
 wenzelm parents: 
52800diff
changeset | 24 | fun chunk ss = | 
| 
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
 wenzelm parents: 
52800diff
changeset | 25 | string_of_int (fold (Integer.add o size) ss 0) :: "\n" :: ss; | 
| 52800 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 26 | |
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 27 | fun message name raw_props body = | 
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 28 | let | 
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58857diff
changeset | 29 | val robust_props = map (apply2 YXML.embed_controls) raw_props; | 
| 52800 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 30 | val header = YXML.string_of (XML.Elem ((name, robust_props), [])); | 
| 56333 
38f1422ef473
support bulk messages consisting of small string segments, which are more healthy to the Poly/ML RTS and might prevent spurious GC crashes such as MTGCProcessMarkPointers::ScanAddressesInObject;
 wenzelm parents: 
52800diff
changeset | 31 | in Message (chunk [header] @ chunk body) end; | 
| 52800 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 32 | |
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 33 | fun output_message channel (Message ss) = | 
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 34 | List.app (System_Channel.output channel) ss; | 
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 35 | |
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 36 | |
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 37 | (* channel *) | 
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 38 | |
| 
1baa5d19ac44
less aggressive flushing: cope with massive amounts of protocol messages, e.g. from threads_trace;
 wenzelm parents: 
52584diff
changeset | 39 | datatype T = Message_Channel of {send: message -> unit, shutdown: unit -> unit};
 | 
| 52584 | 40 | |
| 41 | fun send (Message_Channel {send, ...}) = send;
 | |
| 42 | fun shutdown (Message_Channel {shutdown, ...}) = shutdown ();
 | |
| 43 | ||
| 56733 
f7700146678d
manager is direct receiver of prover output -- discontinued old performance tuning (329320fc88df, 1baa5d19ac44);
 wenzelm parents: 
56333diff
changeset | 44 | fun flush channel = ignore (try System_Channel.flush channel); | 
| 57417 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 45 | val flush_timeout = SOME (seconds 0.02); | 
| 56733 
f7700146678d
manager is direct receiver of prover output -- discontinued old performance tuning (329320fc88df, 1baa5d19ac44);
 wenzelm parents: 
56333diff
changeset | 46 | |
| 52584 | 47 | fun message_output mbox channel = | 
| 48 | let | |
| 57417 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 49 | fun continue timeout = | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 50 | (case Mailbox.receive timeout mbox of | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 51 | [] => (flush channel; continue NONE) | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 52 | | msgs => received timeout msgs) | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 53 | and received _ (NONE :: _) = flush channel | 
| 58857 | 54 | | received _ (SOME msg :: rest) = (output_message channel msg; received flush_timeout rest) | 
| 57417 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 55 | | received timeout [] = continue timeout; | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 56 | in fn () => continue NONE end; | 
| 52584 | 57 | |
| 58 | fun make channel = | |
| 62359 | 59 | let | 
| 60 | val mbox = Mailbox.create (); | |
| 61 | val thread = | |
| 62 |       Standard_Thread.fork {name = "channel", stack_limit = NONE, interrupts = false}
 | |
| 63 | (message_output mbox channel); | |
| 64 | fun send msg = Mailbox.send mbox (SOME msg); | |
| 65 | fun shutdown () = | |
| 66 | (Mailbox.send mbox NONE; Mailbox.await_empty mbox; Standard_Thread.join thread); | |
| 67 |   in Message_Channel {send = send, shutdown = shutdown} end;
 | |
| 52584 | 68 | |
| 69 | end; |