| author | wenzelm | 
| Fri, 09 Aug 2019 20:33:05 +0200 | |
| changeset 70495 | aaafff824632 | 
| parent 69451 | 387894c2fb2c | 
| child 70995 | 2c17fa0f5187 | 
| 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 | 
| 69449 | 14 | val make: BinIO.outstream -> T | 
| 52584 | 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 | |
| 69449 | 33 | fun output_message stream (Message ss) = | 
| 34 | List.app (File.output stream) ss; | |
| 52800 
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 | ||
| 57417 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 44 | 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 | 45 | |
| 69449 | 46 | fun message_output mbox stream = | 
| 52584 | 47 | let | 
| 57417 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 48 | fun continue timeout = | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 49 | (case Mailbox.receive timeout mbox of | 
| 69451 | 50 | [] => (Byte_Message.flush stream; continue NONE) | 
| 57417 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 51 | | msgs => received timeout msgs) | 
| 69451 | 52 | and received _ (NONE :: _) = Byte_Message.flush stream | 
| 69449 | 53 | | received _ (SOME msg :: rest) = (output_message stream 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 | 54 | | received timeout [] = continue timeout; | 
| 
29fe9bac501b
more tight Mailbox: single list is sufficient for single receiver, reverse outside critical section;
 wenzelm parents: 
56733diff
changeset | 55 | in fn () => continue NONE end; | 
| 52584 | 56 | |
| 69449 | 57 | fun make stream = | 
| 62359 | 58 | let | 
| 59 | val mbox = Mailbox.create (); | |
| 60 | val thread = | |
| 61 |       Standard_Thread.fork {name = "channel", stack_limit = NONE, interrupts = false}
 | |
| 69449 | 62 | (message_output mbox stream); | 
| 62359 | 63 | fun send msg = Mailbox.send mbox (SOME msg); | 
| 64 | fun shutdown () = | |
| 65 | (Mailbox.send mbox NONE; Mailbox.await_empty mbox; Standard_Thread.join thread); | |
| 66 |   in Message_Channel {send = send, shutdown = shutdown} end;
 | |
| 52584 | 67 | |
| 68 | end; |