[m-rev.] for review: [PATCH 1/4] Add thread_safe attribute to store procedures.
Peter Wang
novalazy at gmail.com
Tue Jul 22 15:00:23 AEST 2014
The mutvar procedures are not truly thread-safe but neither does
obtaining a global lock make them become thread-safe in a useful way,
except perhaps avoiding data races. On the other hand, the global lock
inhibits parallelism in programs that do use mutvars in a thread-safe
manner.
library/store.m:
As above.
---
library/store.m | 94 ++++++++++++++++++++++++++++-----------------------------
1 file changed, 47 insertions(+), 47 deletions(-)
diff --git a/library/store.m b/library/store.m
index a25e65a..bd93905 100644
--- a/library/store.m
+++ b/library/store.m
@@ -281,25 +281,25 @@ store.init(S) :-
:- pragma foreign_proc("C",
store.do_init(_S0::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
TypeInfo_for_S = 0;
").
:- pragma foreign_proc("C#",
store.do_init(_S0::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
TypeInfo_for_S = null;
").
:- pragma foreign_proc("Java",
store.do_init(_S0::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
TypeInfo_for_S = null;
").
:- pragma foreign_proc("Erlang",
store.do_init(_S0::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
TypeInfo_for_S = 'XXX'
").
@@ -321,7 +321,7 @@ store.init(S) :-
:- pragma foreign_proc("C",
new_mutvar(Val::in, Mutvar::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
MR_offset_incr_hp_msg(Mutvar, MR_SIZE_SLOT_SIZE, MR_SIZE_SLOT_SIZE + 1,
MR_ALLOC_ID, ""store.mutvar/2"");
@@ -332,7 +332,7 @@ store.init(S) :-
:- pragma foreign_proc("C",
get_mutvar(Mutvar::in, Val::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
Val = * (MR_Word *) Mutvar;
S = S0;
@@ -340,7 +340,7 @@ store.init(S) :-
:- pragma foreign_proc("C",
set_mutvar(Mutvar::in, Val::in, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
* (MR_Word *) Mutvar = Val;
S = S0;
@@ -350,21 +350,21 @@ store.init(S) :-
:- pragma foreign_proc("C#",
new_mutvar(Val::in, Mutvar::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar = new object[] { Val };
").
:- pragma foreign_proc("C#",
get_mutvar(Mutvar::in, Val::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = Mutvar[0];
").
:- pragma foreign_proc("C#",
set_mutvar(Mutvar::in, Val::in, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar[0] = Val;
").
@@ -373,21 +373,21 @@ store.init(S) :-
:- pragma foreign_proc("Java",
new_mutvar(Val::in, Mutvar::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar = new mutvar.Mutvar(Val);
").
:- pragma foreign_proc("Java",
get_mutvar(Mutvar::in, Val::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = Mutvar.object;
").
:- pragma foreign_proc("Java",
set_mutvar(Mutvar::in, Val::in, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar.object = Val;
").
@@ -399,7 +399,7 @@ store.init(S) :-
:- pragma foreign_proc("Erlang",
new_mutvar(Val::in, Mutvar::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar = ets:new(mutvar, [set, public]),
ets:insert(Mutvar, {value, Val}),
@@ -408,7 +408,7 @@ store.init(S) :-
:- pragma foreign_proc("Erlang",
get_mutvar(Mutvar::in, Val::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
[{value, Val}] = ets:lookup(Mutvar, value),
S = S0
@@ -416,7 +416,7 @@ store.init(S) :-
:- pragma foreign_proc("Erlang",
set_mutvar(Mutvar::in, Val::in, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
ets:insert(Mutvar, {value, Val}),
S = S0
@@ -431,7 +431,7 @@ copy_mutvar(Mutvar, Copy, !S) :-
:- pragma foreign_proc("C",
unsafe_new_uninitialized_mutvar(Mutvar::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
MR_offset_incr_hp_msg(Mutvar, MR_SIZE_SLOT_SIZE, MR_SIZE_SLOT_SIZE + 1,
MR_ALLOC_ID, ""store.mutvar/2"");
@@ -441,14 +441,14 @@ copy_mutvar(Mutvar, Copy, !S) :-
:- pragma foreign_proc("C#",
unsafe_new_uninitialized_mutvar(Mutvar::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar = new object[1];
").
:- pragma foreign_proc("Java",
unsafe_new_uninitialized_mutvar(Mutvar::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Mutvar = new mutvar.Mutvar();
").
@@ -588,7 +588,7 @@ store.new_cyclic_mutvar(Func, MutVar, !Store) :-
:- pragma foreign_proc("C",
new_ref(Val::di, Ref::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
MR_offset_incr_hp_msg(Ref, MR_SIZE_SLOT_SIZE, MR_SIZE_SLOT_SIZE + 1,
MR_ALLOC_ID, ""store.ref/2"");
@@ -599,21 +599,21 @@ store.new_cyclic_mutvar(Func, MutVar, !Store) :-
:- pragma foreign_proc("C#",
new_ref(Val::di, Ref::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Ref = new store.Ref(Val);
").
:- pragma foreign_proc("Java",
new_ref(Val::di, Ref::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Ref = new store.Ref(Val);
").
:- pragma foreign_proc("Erlang",
new_ref(Val::di, Ref::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Ref = ets:new(mutvar, [set, public]),
ets:insert(Ref, {value, Val}),
@@ -633,7 +633,7 @@ copy_ref_value(Ref, Val) -->
:- pragma foreign_proc("C",
unsafe_ref_value(Ref::in, Val::uo, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, will_not_modify_trail],
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
"
Val = * (MR_Word *) Ref;
S = S0;
@@ -641,21 +641,21 @@ copy_ref_value(Ref, Val) -->
:- pragma foreign_proc("C#",
unsafe_ref_value(Ref::in, Val::uo, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = Ref.getValue();
").
:- pragma foreign_proc("Java",
unsafe_ref_value(Ref::in, Val::uo, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = Ref.getValue();
").
:- pragma foreign_proc("Erlang",
unsafe_ref_value(Ref::in, Val::uo, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
[{value, Val}] = ets:lookup(Ref, value),
S = S0
@@ -675,7 +675,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C",
arg_ref(Ref::in, ArgNum::in, ArgRef::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, may_not_duplicate],
+ [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
"{
MR_TypeInfo type_info;
MR_TypeInfo arg_type_info;
@@ -715,7 +715,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C#",
arg_ref(Ref::in, ArgNum::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
/*
** XXX Some dynamic type-checking should be done here to check that
@@ -728,7 +728,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("Java",
arg_ref(Ref::in, ArgNum::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
/*
** XXX Some dynamic type-checking should be done here to check that
@@ -741,7 +741,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C",
new_arg_ref(Val::di, ArgNum::in, ArgRef::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure, may_not_duplicate],
+ [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
"{
MR_TypeInfo type_info;
MR_TypeInfo arg_type_info;
@@ -793,7 +793,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C#",
new_arg_ref(Val::di, ArgNum::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
/*
** XXX Some dynamic type-checking should be done here to check that
@@ -806,7 +806,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("Java",
new_arg_ref(Val::di, ArgNum::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
/*
** XXX Some dynamic type-checking should be done here to check that
@@ -819,7 +819,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C",
set_ref(Ref::in, ValRef::in, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
* (MR_Word *) Ref = * (MR_Word *) ValRef;
S = S0;
@@ -827,21 +827,21 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C#",
set_ref(Ref::in, ValRef::in, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Ref.setValue(ValRef.getValue());
").
:- pragma foreign_proc("Java",
set_ref(Ref::in, ValRef::in, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Ref.setValue(ValRef.getValue());
").
:- pragma foreign_proc("C",
set_ref_value(Ref::in, Val::di, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
* (MR_Word *) Ref = Val;
S = S0;
@@ -849,28 +849,28 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("Java",
set_ref_value(Ref::in, Val::di, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Ref.setValue(Val);
").
:- pragma foreign_proc("C",
extract_ref_value(_S::di, Ref::in, Val::out),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = * (MR_Word *) Ref;
").
:- pragma foreign_proc("C#",
extract_ref_value(_S::di, Ref::in, Val::out),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = Ref.getValue();
").
:- pragma foreign_proc("Java",
extract_ref_value(_S::di, Ref::in, Val::out),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
Val = Ref.getValue();
").
@@ -879,7 +879,7 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C",
unsafe_arg_ref(Ref::in, Arg::in, ArgRef::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"{
/* unsafe - does not check type & arity, won't handle no_tag types */
MR_Word *Ptr;
@@ -891,21 +891,21 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C#",
unsafe_arg_ref(Ref::in, Arg::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
ArgRef = new store.Ref(Ref.getValue(), Arg);
").
:- pragma foreign_proc("Java",
unsafe_arg_ref(Ref::in, Arg::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
ArgRef = new store.Ref(Ref.getValue(), Arg);
").
:- pragma foreign_proc("C",
unsafe_new_arg_ref(Val::di, Arg::in, ArgRef::out, S0::di, S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"{
/* unsafe - does not check type & arity, won't handle no_tag types */
MR_Word *Ptr;
@@ -917,14 +917,14 @@ ref_functor(Ref, Functor, Arity, !Store) :-
:- pragma foreign_proc("C#",
unsafe_new_arg_ref(Val::di, Arg::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
ArgRef = new store.Ref(Val, Arg);
").
:- pragma foreign_proc("Java",
unsafe_new_arg_ref(Val::di, Arg::in, ArgRef::out, _S0::di, _S::uo),
- [will_not_call_mercury, promise_pure],
+ [will_not_call_mercury, promise_pure, thread_safe],
"
ArgRef = new store.Ref(Val, Arg);
").
--
1.8.4
More information about the reviews
mailing list