[m-rev.] for review: Add some mvar predicates.
Peter Wang
novalazy at gmail.com
Wed Sep 7 12:12:28 AEST 2016
library/thread.mvar.m:
Add mvar.init/1, mvar.impure_init/1, mvar.try_read/4.
Improve some documentation.
NEWS:
Announce additions.
---
NEWS | 7 +++++++
library/thread.mvar.m | 58 +++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/NEWS b/NEWS
index 105d3dc..10c4b89 100644
--- a/NEWS
+++ b/NEWS
@@ -177,6 +177,13 @@ Changes to the Mercury standard library:
* We have added thread.num_processors/3 which returns the number of
processors available for parallel work.
+* The following predicates and functions have been added to the thread.mvar
+ module:
+
+ - mvar.init/1
+ - mvar.impure_init/1
+ - mvar.try_read/4
+
+ We have deprecated the impure init/1 function in thread.semaphore.
* In C grades, the math module now provides the fused multiply-add operation
diff --git a/library/thread.mvar.m b/library/thread.mvar.m
index 47f8c30..6a287d7 100644
--- a/library/thread.mvar.m
+++ b/library/thread.mvar.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2000-2003, 2006-2007, 2011 The University of Melbourne.
-% Copyright (C) 2014 The Mercury Team.
+% Copyright (C) 2014, 2016 The Mercury Team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -36,10 +36,18 @@
%
:- pred init(mvar(T)::out, io::di, io::uo) is det.
+ % Create an mvar with the given initial value.
+ %
+:- pred init(T::in, mvar(T)::out, io::di, io::uo) is det.
+
% Create an empty mvar.
%
:- impure func impure_init = (mvar(T)::uo) is det.
+ % Create an mvar with the given initial value.
+ %
+:- impure func impure_init(T) = mvar(T).
+
% Create an empty mvar.
%
% This has been renamed to impure_init.
@@ -47,33 +55,39 @@
:- impure func init = (mvar(T)::uo) is det.
:- pragma obsolete(init/0).
- % Take the contents of the mvar out leaving the mvar empty.
+ % Take the contents of the mvar out, leaving the mvar empty.
% If the mvar is empty, block until some thread fills the mvar.
%
:- pred take(mvar(T)::in, T::out, io::di, io::uo) is det.
- % Take the contents of the mvar out leaving the mvar empty.
+ % Take the contents of the mvar out, leaving the mvar empty.
% Returns immediately with no if the mvar was empty, or yes(X) if
% the mvar contained X.
%
:- pred try_take(mvar(T)::in, maybe(T)::out, io::di, io::uo) is det.
% Place the value of type T into an empty mvar.
- % If the mvar is full block until it becomes empty.
+ % If the mvar is full then block until it becomes empty.
%
:- pred put(mvar(T)::in, T::in, io::di, io::uo) is det.
% Place the value of type T into an empty mvar, returning yes on success.
- % If the mvar is full, return no immediately without blocking.
+ % If the mvar is full then return no immediately without blocking.
%
:- pred try_put(mvar(T)::in, T::in, bool::out, io::di, io::uo) is det.
- % Read the contents of mvar, without taking it out.
- % If the mvar is empty, block until it is full.
- % This is equivalent to mvar.take followed by mvar.put.
+ % Read the contents of mvar without taking it out.
+ % If the mvar is empty then block until it is full.
+ % This is similar to mvar.take followed by mvar.put, but atomic.
%
:- pred read(mvar(T)::in, T::out, io::di, io::uo) is det.
+ % Try to read the contents of mvar without taking it out.
+ % Returns immediately with no if the mvar was empty, or yes(X) if
+ % the mvar contained X.
+ %
+:- pred try_read(mvar(T)::in, maybe(T)::out, io::di, io::uo) is det.
+
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
@@ -98,11 +112,21 @@ init(Mvar, !IO) :-
impure Mvar = impure_init
).
+init(Value, Mvar, !IO) :-
+ promise_pure (
+ impure Mvar = impure_init(Value)
+ ).
+
impure_init = mvar(Full, Empty, Ref) :-
impure semaphore.impure_init(0, Full),
- impure semaphore.impure_init(1, Empty), % Initially a mvar starts empty.
+ impure semaphore.impure_init(1, Empty), % initially empty
impure new_mutvar0(Ref).
+impure_init(Value) = mvar(Full, Empty, Ref) :-
+ impure semaphore.impure_init(1, Full), % initially full
+ impure semaphore.impure_init(0, Empty),
+ impure new_mutvar(Value, Ref).
+
init = Mvar :-
impure Mvar = impure_init.
@@ -168,4 +192,20 @@ read(mvar(Full, _Empty, Ref), Data, !IO) :-
).
%---------------------------------------------------------------------------%
+
+try_read(mvar(Full, _Empty, Ref), MaybeData, !IO) :-
+ promise_pure (
+ semaphore.try_wait(Full, Success, !IO),
+ (
+ Success = yes,
+ impure get_mutvar(Ref, Data),
+ semaphore.signal(Full, !IO),
+ MaybeData = yes(Data)
+ ;
+ Success = no,
+ MaybeData = no
+ )
+ ).
+
+%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
--
2.9.0
More information about the reviews
mailing list