[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