[m-rev.] for review: Add barriers (for concurrency) to the standard library

Paul Bone paul at bone.id.au
Thu Apr 3 17:10:04 AEDT 2014


For review by anyone

Branches: master

---

Add barriers (for concurrency) to the standard library

Mission Critical IT has maintained a library of code for concurrent
programming.  We're happy to contribute this upstream to the Mercury
project starting with this module implementing barriers.

library/thread.barrier.m:
    Add the new module implementing barriers.

library/thread.m:
library/library.m:
    Add new module.

NEWS:
    Announce the new module.
---
 NEWS                     |   8 +++-
 library/library.m        |   3 +-
 library/thread.barrier.m | 122 +++++++++++++++++++++++++++++++++++++++++++++++
 library/thread.m         |   8 ++--
 4 files changed, 135 insertions(+), 6 deletions(-)
 create mode 100644 library/thread.barrier.m

diff --git a/NEWS b/NEWS
index 5c79e34..45c8c50 100644
--- a/NEWS
+++ b/NEWS
@@ -15,8 +15,12 @@ Changes to the Mercury standard library:
 * io.print and string_writer.print now print arbitrary precision integers
   in their decimal form instead of printing their underlying representation.
 
-* We have added a module for discrete interval encoding trees,
-  which are a highly efficient set implementation for fat sets.
+* We have added a module for discrete interval encoding trees, which are a
+  highly efficient set implementation for fat sets.  This module is a
+  contribution from Yes Logic Pty. Ltd.
+
+* We have added a module that implements barriers for concurrent
+  programming.  This module is a contribution from Mission Critical IT.
 
 Changes to the extras distribution:
 
diff --git a/library/library.m b/library/library.m
index 59daa61..e490443 100644
--- a/library/library.m
+++ b/library/library.m
@@ -1,7 +1,7 @@
 %---------------------------------------------------------------------------%
 % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
 %---------------------------------------------------------------------------%
-% Copyright (C) 1993-2007, 2009-2012 The University of Melbourne.
+% Copyright (C) 1993-2007, 2009-2014 The University of Melbourne.
 % 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.
 %---------------------------------------------------------------------------%
@@ -299,6 +299,7 @@ mercury_std_library_module("term_to_xml").
 mercury_std_library_module("test_bitset").
 mercury_std_library_module("time").
 mercury_std_library_module("thread").
+mercury_std_library_module("thread.barrier").
 mercury_std_library_module("thread.channel").
 mercury_std_library_module("thread.mvar").
 mercury_std_library_module("thread.semaphore").
diff --git a/library/thread.barrier.m b/library/thread.barrier.m
new file mode 100644
index 0000000..430872d
--- /dev/null
+++ b/library/thread.barrier.m
@@ -0,0 +1,122 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2005, 2014 Mission Critical IT.
+% Copyright (C) 2014 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.
+%-----------------------------------------------------------------------------%
+%
+% File: thread.barrier.m
+% Original author: Peter Ross
+% Stability: new
+%
+% This module provides a barrier implementation.
+%
+% A barrier is a position in a program that any thread (of N threads) must
+% be suspended at until all the other threads (of N) reach the same
+% position.
+%
+% Barriers are represented by calls to barrier/3 (defined below).  Different
+% code locations can belong to the same conceptual barrier using values of
+% type barrier.  The same code location can also be used by multiple
+% barriers by supplying different values.
+%
+% TODO:
+%
+%   In some grades it may be possible to improve performance by writing
+%   this natively rather than using mvar.
+%
+%   A semaphore may be better for the "go" signal than an mvar.
+%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- module thread.barrier.
+
+:- interface.
+
+:- import_module io.
+
+:- type barrier.
+
+    % init(N, Barrier, !IO)
+    %
+    % Create a barrier for N threads.
+    %
+:- pred init(int::in, barrier::out, io::di, io::uo) is det.
+
+    % barrier(Barrier, !IO)
+    %
+    % Indicate that the current thread has reached the barrier.
+    %
+:- pred barrier(barrier::in, io::di, io::uo) is det.
+
+    % release_barrier(Barrier, !IO)
+    %
+    % Release all the threads waiting at the barrier regardless
+    % of whether or not N threads have arrived at the barrier.
+    %
+:- pred release_barrier(barrier::in, io::di, io::uo) is det.
+
+%------------------------------------------------------------------------------%
+%------------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int.
+:- import_module require.
+:- import_module string.
+:- import_module thread.mvar.
+:- import_module unit.
+
+%------------------------------------------------------------------------------%
+
+:- type barrier
+    --->    barrier(
+                % How many threads we are still waiting on?
+                b_waiting_for   :: mvar(int),
+
+                % Can we go yet?
+                b_go            :: mvar(unit)
+            ).
+
+%------------------------------------------------------------------------------%
+
+init(N, barrier(WaitingOn, Go), !IO) :-
+    init(WaitingOn, !IO),
+    init(Go, !IO),
+    put(WaitingOn, N, !IO).
+
+%------------------------------------------------------------------------------%
+
+barrier(barrier(WaitingOn, Go), !IO) :-
+    take(WaitingOn, N, !IO),
+    StillWaitingFor = N - 1,
+
+    ( StillWaitingFor > 0 ->
+        % There are still outstanding threads.
+        
+        % Unlock the counter
+        put(WaitingOn, StillWaitingFor, !IO),
+
+        % Wait on the barrier then unlock another thread.
+        take(Go, _, !IO),
+        put(Go, unit, !IO)
+    ; StillWaitingFor = 0 ->
+        % The last thread at the barrier, so signal that we can go.
+        put(Go, unit, !IO),
+        put(WaitingOn, StillWaitingFor, !IO)
+    ;
+        unexpected($pred,
+            "Too many threads called barrier/3 on this barrier.")
+    ).
+
+release_barrier(barrier(WaitingOn, Go), !IO) :-
+    % Allow all the threads at the barrier to go.
+    put(Go, unit, !IO),
+    take(WaitingOn, N, !IO),
+    put(WaitingOn, N - 1, !IO).
+
+%------------------------------------------------------------------------------%
+%------------------------------------------------------------------------------%
diff --git a/library/thread.m b/library/thread.m
index 30ff338..9d282f3 100644
--- a/library/thread.m
+++ b/library/thread.m
@@ -1,7 +1,8 @@
 %-----------------------------------------------------------------------------%
 % vim: ft=mercury ts=4 sw=4 et
 %-----------------------------------------------------------------------------%
-% Copyright (C) 2000-2001,2003-2004, 2006-2008, 2010-2011 The University of Melbourne.
+% Copyright (C) 2000-2001, 2003-2004, 2006-2008, 2010-2011, 2014 The
+% University of Melbourne.
 % 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.
 %-----------------------------------------------------------------------------%
@@ -12,9 +13,9 @@
 %
 % This module defines the Mercury concurrency interface.
 %
-% The term `concurrency' here refers to threads, not necessarily to parallel
+% The term `concurrency' refers to threads, not necessarily to parallel
 % execution.  (The latter is also possible if you are using one of the .par
-% grades and the lowlevel C backend, e.g. grade asm_fast.par.gc).
+% grades or the java or csharp backends.)
 %
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -24,6 +25,7 @@
 
 :- import_module io.
 
+:- include_module barrier.
 :- include_module channel.
 :- include_module mvar.
 :- include_module semaphore.
-- 
1.9.1




More information about the reviews mailing list