[m-rev.] for review: thread-local streams
Peter Wang
wangp at students.csse.unimelb.edu.au
Mon Jan 15 14:08:53 AEDT 2007
Branches: main
library/io.m:
Make the current input/output streams thread-local in C grades. This
uses the same underlying mechanisms as thread-local mutables, but not
the mutable language feature.
Index: library/io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.367
diff -u -r1.367 io.m
--- library/io.m 15 Jan 2007 02:23:59 -0000 1.367
+++ library/io.m 15 Jan 2007 03:03:24 -0000
@@ -22,6 +22,11 @@
% Attempting any operation on a stream which has already been closed results
% in undefined behaviour.
%
+% In multithreaded programs, each thread in the program has its own set of
+% "current" input and output streams. At the time it is created, a child
+% thread inherits the current streams from its parent. Predicates which
+% change which stream is current affect only the calling thread.
+%
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -4594,6 +4599,17 @@
:- pragma foreign_export("C", io.init_state(di, uo), "ML_io_init_state").
io.init_state(!IO) :-
+ %
+ % In C grades the "current" streams are thread-local values, so can only be
+ % set after the MR_Context has been initialised for the initial thread.
+ %
+ io.set_input_stream(io.stdin_stream, _, !IO),
+ io.set_output_stream(io.stdout_stream, _, !IO),
+ io.stdin_binary_stream(StdinBinary, !IO),
+ io.stdout_binary_stream(StdoutBinary, !IO),
+ io.set_binary_input_stream(StdinBinary, _, !IO),
+ io.set_binary_output_stream(StdoutBinary, _, !IO),
+
io.gc_init(type_of(StreamDb), type_of(Globals), !IO),
map.init(StreamDb),
type_to_univ("<globals>", Globals),
@@ -4739,10 +4755,10 @@
extern MercuryFile mercury_stderr;
extern MercuryFile mercury_stdin_binary;
extern MercuryFile mercury_stdout_binary;
-extern MercuryFile *mercury_current_text_input;
-extern MercuryFile *mercury_current_text_output;
-extern MercuryFile *mercury_current_binary_input;
-extern MercuryFile *mercury_current_binary_output;
+extern MR_Unsigned mercury_current_text_input_index;
+extern MR_Unsigned mercury_current_text_output_index;
+extern MR_Unsigned mercury_current_binary_input_index;
+extern MR_Unsigned mercury_current_binary_output_index;
#define MR_initial_io_state() 0 /* some random number */
#define MR_final_io_state(r) ((void)0)
@@ -4750,6 +4766,10 @@
#define MR_update_io(r_src, r_dest) ((r_dest) = (r_src))
void mercury_init_io(void);
+MercuryFilePtr mercury_current_text_input(void);
+MercuryFilePtr mercury_current_text_output(void);
+MercuryFilePtr mercury_current_binary_input(void);
+MercuryFilePtr mercury_current_binary_output(void);
MercuryFilePtr mercury_open(const char *filename, const char *openmode);
void mercury_io_error(MercuryFilePtr mf, const char *format, ...);
void mercury_output_error(MercuryFilePtr mf);
@@ -5382,10 +5402,10 @@
MercuryFile mercury_stdin_binary;
MercuryFile mercury_stdout_binary;
-MercuryFilePtr mercury_current_text_input = &mercury_stdin;
-MercuryFilePtr mercury_current_text_output = &mercury_stdout;
-MercuryFilePtr mercury_current_binary_input = &mercury_stdin_binary;
-MercuryFilePtr mercury_current_binary_output = &mercury_stdout_binary;
+MR_Unsigned mercury_current_text_input_index;
+MR_Unsigned mercury_current_text_output_index;
+MR_Unsigned mercury_current_binary_input_index;
+MR_Unsigned mercury_current_binary_output_index;
void
mercury_init_io(void)
@@ -5397,6 +5417,11 @@
MR_mercuryfile_init(NULL, 1, &mercury_stdin_binary);
MR_mercuryfile_init(NULL, 1, &mercury_stdout_binary);
+ mercury_current_text_input_index = MR_new_thread_local_mutable_index();
+ mercury_current_text_output_index = MR_new_thread_local_mutable_index();
+ mercury_current_binary_input_index = MR_new_thread_local_mutable_index();
+ mercury_current_binary_output_index = MR_new_thread_local_mutable_index();
+
#if defined(MR_HAVE_FDOPEN) && (defined(MR_HAVE_FILENO) || defined(fileno)) && \
defined(MR_HAVE_DUP)
MR_file(mercury_stdin_binary) = fdopen(dup(fileno(stdin)), ""rb"");
@@ -5425,6 +5450,42 @@
#endif
}
+MercuryFilePtr
+mercury_current_text_input(void)
+{
+ MercuryFilePtr stream;
+ MR_get_thread_local_mutable(MercuryFilePtr, stream,
+ mercury_current_text_input_index);
+ return stream;
+}
+
+MercuryFilePtr
+mercury_current_text_output(void)
+{
+ MercuryFilePtr stream;
+ MR_get_thread_local_mutable(MercuryFilePtr, stream,
+ mercury_current_text_output_index);
+ return stream;
+}
+
+MercuryFilePtr
+mercury_current_binary_input(void)
+{
+ MercuryFilePtr stream;
+ MR_get_thread_local_mutable(MercuryFilePtr, stream,
+ mercury_current_binary_input_index);
+ return stream;
+}
+
+MercuryFilePtr
+mercury_current_binary_output(void)
+{
+ MercuryFilePtr stream;
+ MR_get_thread_local_mutable(MercuryFilePtr, stream,
+ mercury_current_binary_output_index);
+ return stream;
+}
+
").
:- pragma foreign_code("C#", "
@@ -5468,6 +5529,7 @@
mercury_file_init(System.Console.OpenStandardOutput(),
null, System.Console.Out, ML_file_encoding_kind.ML_raw_binary);
+// Note: these are set again in io.init_state.
static MR_MercuryFileStruct mercury_current_text_input =
mercury_stdin;
static MR_MercuryFileStruct mercury_current_text_output =
@@ -5495,6 +5557,7 @@
static MR_MercuryFileStruct mercury_stdout_binary =
new MR_MercuryFileStruct(java.lang.System.out, true);
+// Note: these are set again in io.init_state.
static MR_MercuryFileStruct mercury_current_text_input =
mercury_stdin;
static MR_MercuryFileStruct mercury_current_text_output =
@@ -6228,7 +6291,7 @@
[may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
does_not_affect_liveness],
"
- mercury_print_string(mercury_current_text_output, Message);
+ mercury_print_string(mercury_current_text_output(), Message);
MR_update_io(IO0, IO);
").
@@ -6237,11 +6300,12 @@
[may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
does_not_affect_liveness],
"
- if (MR_PUTCH(*mercury_current_text_output, Character) < 0) {
- mercury_output_error(mercury_current_text_output);
+ MercuryFilePtr out = mercury_current_text_output();
+ if (MR_PUTCH(*out, Character) < 0) {
+ mercury_output_error(out);
}
if (Character == '\\n') {
- MR_line_number(*mercury_current_text_output)++;
+ MR_line_number(*out)++;
}
MR_update_io(IO0, IO);
").
@@ -6251,8 +6315,9 @@
[may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
does_not_affect_liveness],
"
- if (ML_fprintf(mercury_current_text_output, ""%ld"", (long) Val) < 0) {
- mercury_output_error(mercury_current_text_output);
+ MercuryFilePtr out = mercury_current_text_output();
+ if (ML_fprintf(out, ""%ld"", (long) Val) < 0) {
+ mercury_output_error(out);
}
MR_update_io(IO0, IO);
").
@@ -6263,9 +6328,12 @@
does_not_affect_liveness],
"
char buf[MR_SPRINTF_FLOAT_BUF_SIZE];
+ MercuryFilePtr out;
+
MR_sprintf_float(buf, Val);
- if (ML_fprintf(mercury_current_text_output, ""%s"", buf) < 0) {
- mercury_output_error(mercury_current_text_output);
+ out = mercury_current_text_output();
+ if (ML_fprintf(out, ""%s"", buf) < 0) {
+ mercury_output_error(out);
}
MR_update_io(IO0, IO);
").
@@ -6276,10 +6344,10 @@
does_not_affect_liveness],
"
/* call putc with a strictly non-negative byte-sized integer */
- if (MR_PUTCH(*mercury_current_binary_output,
+ if (MR_PUTCH(*mercury_current_binary_output(),
(int) ((unsigned char) Byte)) < 0)
{
- mercury_output_error(mercury_current_text_output);
+ mercury_output_error(mercury_current_text_output());
}
MR_update_io(IO0, IO);
").
@@ -6289,7 +6357,7 @@
[may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
does_not_affect_liveness],
"{
- mercury_print_binary_string(mercury_current_binary_output, Message);
+ mercury_print_binary_string(mercury_current_binary_output(), Message);
MR_update_io(IO0, IO);
}").
@@ -6298,8 +6366,9 @@
[may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
does_not_affect_liveness],
"
- if (MR_FLUSH(*mercury_current_text_output) < 0) {
- mercury_output_error(mercury_current_text_output);
+ MercuryFilePtr out = mercury_current_text_output();
+ if (MR_FLUSH(*out) < 0) {
+ mercury_output_error(out);
}
MR_update_io(IO0, IO);
").
@@ -6309,8 +6378,9 @@
[may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
does_not_affect_liveness],
"
- if (MR_FLUSH(*mercury_current_binary_output) < 0) {
- mercury_output_error(mercury_current_binary_output);
+ MercuryFilePtr out = mercury_current_binary_output();
+ if (MR_FLUSH(*out) < 0) {
+ mercury_output_error(out);
}
MR_update_io(IO0, IO);
").
@@ -6911,7 +6981,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- Stream = mercury_current_text_input;
+ Stream = mercury_current_text_input();
MR_update_io(IO0, IO);
").
@@ -6924,7 +6994,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- Stream = mercury_current_text_output;
+ Stream = mercury_current_text_output();
MR_update_io(IO0, IO);
").
@@ -6937,7 +7007,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- Stream = mercury_current_binary_input;
+ Stream = mercury_current_binary_input();
MR_update_io(IO0, IO);
").
@@ -6950,7 +7020,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- Stream = mercury_current_binary_output;
+ Stream = mercury_current_binary_output();
MR_update_io(IO0, IO);
").
@@ -6959,7 +7029,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- LineNum = MR_line_number(*mercury_current_text_input);
+ LineNum = MR_line_number(*mercury_current_text_input());
MR_update_io(IO0, IO);
").
@@ -6982,7 +7052,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- MR_line_number(*mercury_current_text_input) = LineNum;
+ MR_line_number(*mercury_current_text_input()) = LineNum;
MR_update_io(IO0, IO);
").
@@ -7006,7 +7076,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- LineNum = MR_line_number(*mercury_current_text_output);
+ LineNum = MR_line_number(*mercury_current_text_output());
MR_update_io(IO0, IO);
").
@@ -7030,7 +7100,7 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- MR_line_number(*mercury_current_text_output) = LineNum;
+ MR_line_number(*mercury_current_text_output()) = LineNum;
MR_update_io(IO0, IO);
").
@@ -7058,8 +7128,9 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- OutStream = mercury_current_text_input;
- mercury_current_text_input = NewStream;
+ OutStream = mercury_current_text_input();
+ MR_set_thread_local_mutable(MercuryFilePtr, NewStream,
+ mercury_current_text_input_index);
MR_update_io(IO0, IO);
").
@@ -7075,8 +7146,9 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- OutStream = mercury_current_text_output;
- mercury_current_text_output = NewStream;
+ OutStream = mercury_current_text_output();
+ MR_set_thread_local_mutable(MercuryFilePtr, NewStream,
+ mercury_current_text_output_index);
MR_update_io(IO0, IO);
").
@@ -7092,8 +7164,9 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- OutStream = mercury_current_binary_input;
- mercury_current_binary_input = NewStream;
+ OutStream = mercury_current_binary_input();
+ MR_set_thread_local_mutable(MercuryFilePtr, NewStream,
+ mercury_current_binary_input_index);
MR_update_io(IO0, IO);
").
@@ -7109,8 +7182,9 @@
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- OutStream = mercury_current_binary_output;
- mercury_current_binary_output = NewStream;
+ OutStream = mercury_current_binary_output();
+ MR_set_thread_local_mutable(MercuryFilePtr, NewStream,
+ mercury_current_binary_output_index);
MR_update_io(IO0, IO);
").
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list