[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