[m-rev.] [PATCH 3/4] Add thread_safe and not_thread_safe attributes.

Peter Wang novalazy at gmail.com
Tue Jul 22 15:00:25 AEST 2014


library/benchmarking.m:
library/bit_buffer.m:
library/exception.m:
library/gc.m:
library/io.m:
library/library.m:
library/thread.m:
library/time.m:
	Add `thread_safe' or `not_thread_safe' to foreign procs
	where it is clear.
---
 library/benchmarking.m |  8 ++++----
 library/bit_buffer.m   | 28 ++++++++++++++--------------
 library/exception.m    |  2 +-
 library/gc.m           |  2 +-
 library/io.m           | 29 +++++++++++++++--------------
 library/library.m      |  6 +++---
 library/thread.m       |  6 +++---
 library/time.m         |  9 ++++++---
 8 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/library/benchmarking.m b/library/benchmarking.m
index 5bc9e6f..b3aeb77 100644
--- a/library/benchmarking.m
+++ b/library/benchmarking.m
@@ -997,14 +997,14 @@ repeat(N) :-
 
 :- pragma foreign_proc("C",
     get_user_cpu_milliseconds(Time::out),
-    [will_not_call_mercury],
+    [will_not_call_mercury, thread_safe],
 "
     Time = MR_get_user_cpu_milliseconds();
 ").
 
 :- pragma foreign_proc("C#",
     get_user_cpu_milliseconds(Time::out),
-    [will_not_call_mercury],
+    [will_not_call_mercury, thread_safe],
 "
     // This won't return the elapsed time since program start,
     // as it begins timing after the first call.
@@ -1015,7 +1015,7 @@ repeat(N) :-
 
 :- pragma foreign_proc("Java",
     get_user_cpu_milliseconds(Time::out),
-    [will_not_call_mercury, may_not_duplicate],
+    [will_not_call_mercury, thread_safe, may_not_duplicate],
 "
     try {
         java.lang.management.ThreadMXBean bean =
@@ -1033,7 +1033,7 @@ repeat(N) :-
 
 :- pragma foreign_proc("Erlang",
     get_user_cpu_milliseconds(Time::out),
-    [will_not_call_mercury],
+    [will_not_call_mercury, thread_safe],
 "
     {Time, _TimeSinceLastCall} = statistics(runtime)
 ").
diff --git a/library/bit_buffer.m b/library/bit_buffer.m
index c15bbcf..85a6f21 100644
--- a/library/bit_buffer.m
+++ b/library/bit_buffer.m
@@ -171,7 +171,7 @@ new_buffer_2(BM, Pos, Size, UseStream, Stream, State, ReadStatus) =
 :- pragma foreign_proc("C",
     new_buffer_2(BM::in, Pos::in, Size::in, UseStream::in,
         Stream::in, State::in, ReadStatus::in) = (Buffer::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "{
     MR_incr_hp_type_msg(Buffer, ML_BitBuffer, MR_ALLOC_ID,
         ""bit_buffer.bit_buffer/3"");
@@ -209,56 +209,56 @@ Buffer ^ read_status = Buffer ^ mer_read_status.
 
 :- pragma foreign_proc("C",
     bitmap(Buffer::bit_buffer_ui) = (BM::bitmap_uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     BM = Buffer->ML_bit_buffer_bitmap;
 ").
 
 :- pragma foreign_proc("C",
     pos(Buffer::bit_buffer_ui) = (Pos::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Pos = Buffer->ML_bit_buffer_pos;
 ").
 
 :- pragma foreign_proc("C",
     size(Buffer::bit_buffer_ui) = (Size::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Size = Buffer->ML_bit_buffer_size;
 ").
 
 :- pragma foreign_proc("C",
     use_stream(Buffer::bit_buffer_ui) = (UseStream::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     UseStream = Buffer->ML_bit_buffer_use_stream;
 ").
 
 :- pragma foreign_proc("C",
     stream(Buffer::bit_buffer_ui) = (Stream::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Stream = Buffer->ML_bit_buffer_stream;
 ").
 
 :- pragma foreign_proc("C",
     state(Buffer::bit_buffer_ui) = (State::uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     State = Buffer->ML_bit_buffer_state;
 ").
 
 :- pragma foreign_proc("C",
     filled_bitmaps(Buffer::bit_buffer_ui) = (FilledBMs::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     FilledBMs = Buffer->ML_bit_buffer_filled_bitmaps;
 ").
 
 :- pragma foreign_proc("C",
     read_status(Buffer::bit_buffer_ui) = (ReadStatus::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     ReadStatus = Buffer->ML_bit_buffer_read_status;
 ").
@@ -277,7 +277,7 @@ set_all(BM, Pos, Size, State, FilledBMs, !Buffer) :-
 :- pragma foreign_proc("C",
     set_all(BM::bitmap_di, Pos::in, Size::in, State::di, FilledBMs::in,
         Buffer0::bit_buffer_di, Buffer::bit_buffer_uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Buffer = Buffer0;
     Buffer->ML_bit_buffer_bitmap = BM;
@@ -298,7 +298,7 @@ set_bitmap(BM, Pos, !Buffer) :-
 :- pragma foreign_proc("C",
     set_bitmap(BM::bitmap_di, Pos::in,
         Buffer0::bit_buffer_di, Buffer::bit_buffer_uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Buffer = Buffer0;
     Buffer->ML_bit_buffer_bitmap = BM;
@@ -314,7 +314,7 @@ set_state(State, !Buffer) :-
 
 :- pragma foreign_proc("C",
     set_state(State::di, Buffer0::bit_buffer_di, Buffer::bit_buffer_uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Buffer = Buffer0;
     Buffer->ML_bit_buffer_state = State;
@@ -330,7 +330,7 @@ set_use_stream(UseStream, !Buffer) :-
 :- pragma foreign_proc("C",
     set_use_stream(UseStream::in,
         Buffer0::bit_buffer_di, Buffer::bit_buffer_uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Buffer = Buffer0;
     Buffer->ML_bit_buffer_use_stream = UseStream;
@@ -346,7 +346,7 @@ set_read_status(ReadStatus, !Buffer) :-
 :- pragma foreign_proc("C",
     set_read_status(ReadStatus::in,
         Buffer0::bit_buffer_di, Buffer::bit_buffer_uo),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Buffer = Buffer0;
     Buffer->ML_bit_buffer_read_status = ReadStatus;
diff --git a/library/exception.m b/library/exception.m
index 272344c..39b5db7 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -2892,7 +2892,7 @@ throw_if_near_stack_limits :-
 
 :- pragma foreign_proc("C",
     now_near_stack_limits,
-    [will_not_call_mercury, no_sharing],
+    [will_not_call_mercury, thread_safe, no_sharing],
 "
 #ifdef  MR_HIGHLEVEL_CODE
     /*
diff --git a/library/gc.m b/library/gc.m
index d2312f7..bd3234b 100644
--- a/library/gc.m
+++ b/library/gc.m
@@ -51,7 +51,7 @@ garbage_collect(!IO) :-
 
 :- pragma foreign_proc("C",
 	garbage_collect,
-	[may_call_mercury, terminates],
+	[may_call_mercury, thread_safe, terminates],
 "
 #ifdef MR_CONSERVATIVE_GC
   #ifndef MR_HIGHLEVEL_CODE
diff --git a/library/io.m b/library/io.m
index 7ebf6ad..d9646f9 100644
--- a/library/io.m
+++ b/library/io.m
@@ -4499,7 +4499,8 @@ should_reduce_stack_usage(yes).
 
 :- pragma foreign_proc("C",
     should_reduce_stack_usage(ShouldReduce::out),
-    [will_not_call_mercury, promise_pure, does_not_affect_liveness],
+    [will_not_call_mercury, promise_pure, thread_safe,
+        does_not_affect_liveness],
 "
 #ifdef  MR_EXEC_TRACE
     ShouldReduce = MR_TRUE;
@@ -5366,8 +5367,8 @@ io.progname_base(DefaultName, PrognameBase, !IO) :-
 
 :- pragma foreign_proc("C",
     io.get_stream_id(Stream::in) = (Id::out),
-    [will_not_call_mercury, promise_pure, does_not_affect_liveness,
-        no_sharing],
+    [will_not_call_mercury, promise_pure, thread_safe,
+        does_not_affect_liveness, no_sharing],
 "
 #ifndef MR_NATIVE_GC
     /*
@@ -5551,7 +5552,7 @@ io.finalize_state(!IO).
 
 :- pragma foreign_proc("C",
     io.gc_init(StreamDbType::in, UserGlobalsType::in, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, not_thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
 "
     /* for Windows DLLs, we need to call GC_INIT() from each DLL */
@@ -8629,7 +8630,7 @@ io.input_stream(input_stream(Stream), !IO) :-
 :- pred io.input_stream_2(io.stream::out, io::di, io::uo) is det.
 :- pragma foreign_proc("C",
     io.input_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8642,7 +8643,7 @@ io.output_stream(output_stream(Stream), !IO) :-
 :- pred io.output_stream_2(io.stream::out, io::di, io::uo) is det.
 :- pragma foreign_proc("C",
     io.output_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8655,7 +8656,7 @@ io.binary_input_stream(binary_input_stream(Stream), !IO) :-
 :- pred io.binary_input_stream_2(io.stream::out, io::di, io::uo) is det.
 :- pragma foreign_proc("C",
     io.binary_input_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8668,7 +8669,7 @@ io.binary_output_stream(binary_output_stream(Stream), !IO) :-
 :- pred io.binary_output_stream_2(io.stream::out, io::di, io::uo) is det.
 :- pragma foreign_proc("C",
     io.binary_output_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8767,7 +8768,7 @@ io.set_input_stream(input_stream(NewStream), input_stream(OutStream), !IO) :-
     io::di, io::uo) is det.
 :- pragma foreign_proc("C",
     io.set_input_stream_2(NewStream::in, OutStream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8785,7 +8786,7 @@ io.set_output_stream(output_stream(NewStream), output_stream(OutStream),
 
 :- pragma foreign_proc("C",
     io.set_output_stream_2(NewStream::in, OutStream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8803,7 +8804,7 @@ io.set_binary_input_stream(binary_input_stream(NewStream),
 :- pragma foreign_proc("C",
     io.set_binary_input_stream_2(NewStream::in, OutStream::out,
         _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -8821,7 +8822,7 @@ io.set_binary_output_stream(binary_output_stream(NewStream),
 :- pragma foreign_proc("C",
     io.set_binary_output_stream_2(NewStream::in, OutStream::out,
         _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io,
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
         does_not_affect_liveness, no_sharing],
     % no_sharing is okay as io.stream is a foreign type so can't be reused.
 "
@@ -10126,8 +10127,8 @@ io.setenv(Var, Value) :-
 
 :- pragma foreign_proc("C",
     io.putenv(VarAndValue::in),
-    [will_not_call_mercury, tabled_for_io, does_not_affect_liveness,
-        no_sharing],
+    [will_not_call_mercury, not_thread_safe, tabled_for_io,
+        does_not_affect_liveness, no_sharing],
 "
 #ifdef MR_WIN32
     SUCCESS_INDICATOR = (_wputenv(ML_utf8_to_wide(VarAndValue)) == 0);
diff --git a/library/library.m b/library/library.m
index 7e1f0ab..85804f2 100644
--- a/library/library.m
+++ b/library/library.m
@@ -166,7 +166,7 @@
 
 :- pragma foreign_proc("C",
     library.version(Version::out),
-    [will_not_call_mercury, promise_pure, will_not_modify_trail],
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
 "
     MR_ConstString version_string =
         MR_VERSION "", configured for "" MR_FULLARCH;
@@ -179,7 +179,7 @@
 
 :- pragma foreign_proc("C#",
     library.version(Version::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Version = runtime.Constants.MR_VERSION + "" configured for ""
         + runtime.Constants.MR_FULLARCH;
@@ -187,7 +187,7 @@
 
 :- pragma foreign_proc("Java",
     library.version(Version::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     Version = jmercury.runtime.Constants.MR_VERSION + "" configured for ""
         + jmercury.runtime.Constants.MR_FULLARCH;
diff --git a/library/thread.m b/library/thread.m
index 30ff338..a113283 100644
--- a/library/thread.m
+++ b/library/thread.m
@@ -82,7 +82,7 @@
 
 :- pragma foreign_proc("C",
     can_spawn,
-    [will_not_call_mercury, promise_pure, may_not_duplicate],
+    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
 #if !defined(MR_HIGHLEVEL_CODE)
     SUCCESS_INDICATOR = MR_TRUE;
@@ -97,14 +97,14 @@
 
 :- pragma foreign_proc("C#",
     can_spawn,
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     SUCCESS_INDICATOR = true;
 ").
 
 :- pragma foreign_proc("Java",
     can_spawn,
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
     SUCCESS_INDICATOR = true;
 ").
diff --git a/library/time.m b/library/time.m
index e050668..22eaabb 100644
--- a/library/time.m
+++ b/library/time.m
@@ -591,7 +591,7 @@ time.localtime(time_t(Time)) = TM :-
 :- pragma foreign_proc("C",
     time.c_localtime(Time::in, Yr::out, Mnt::out, MD::out, Hrs::out,
         Min::out, Sec::out, YD::out, WD::out, N::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, not_thread_safe],
 "
     struct tm   *p;
     time_t      t;
@@ -701,7 +701,7 @@ time.gmtime(time_t(Time)) = TM :-
 :- pragma foreign_proc("C",
     time.c_gmtime(Time::in, Yr::out, Mnt::out, MD::out, Hrs::out,
         Min::out, Sec::out, YD::out, WD::out, N::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, not_thread_safe],
 "{
     struct tm   *p;
     time_t      t;
@@ -826,13 +826,16 @@ time.mktime(TM) = time_t(Time) :-
     time.c_mktime(Yr, Mnt, MD, Hrs, Min, Sec, YD, WD,
         maybe_dst_to_int(DST), Time).
 
+    % NOTE: mktime() modifies tzname so is strictly impure.
+    % We do not expose tzname through a Mercury interface, though.
+    %
 :- pred time.c_mktime(int::in, int::in, int::in, int::in, int::in, int::in,
     int::in, int::in, int::in, time_t_rep::out) is det.
 
 :- pragma foreign_proc("C",
     time.c_mktime(Yr::in, Mnt::in, MD::in, Hrs::in, Min::in, Sec::in,
         YD::in, WD::in, N::in, Time::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, not_thread_safe],
  "{
     struct tm t;
 
-- 
1.8.4




More information about the reviews mailing list