comparison druntime/src/common/core/sync/barrier.d @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
comparison
equal deleted inserted replaced
1456:7b218ec1044f 1458:e0b2d67cfe7c
1 /**
2 * The barrier module provides a primitive for synchronizing the progress of
3 * a group of threads.
4 *
5 * Copyright: Copyright Sean Kelly 2005 - 2009.
6 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
7 * Authors: Sean Kelly
8 *
9 * Copyright Sean Kelly 2005 - 2009.
10 * Distributed under the Boost Software License, Version 1.0.
11 * (See accompanying file LICENSE_1_0.txt or copy at
12 * http://www.boost.org/LICENSE_1_0.txt)
13 */
14 module core.sync.barrier;
15
16
17 public import core.sync.exception;
18 private import core.sync.condition;
19 private import core.sync.mutex;
20
21 version( Win32 )
22 {
23 private import core.sys.windows.windows;
24 }
25 else version( Posix )
26 {
27 private import core.stdc.errno;
28 private import core.sys.posix.pthread;
29 }
30
31
32 ////////////////////////////////////////////////////////////////////////////////
33 // Barrier
34 //
35 // void wait();
36 ////////////////////////////////////////////////////////////////////////////////
37
38
39 /**
40 * This class represents a barrier across which threads may only travel in
41 * groups of a specific size.
42 */
43 class Barrier
44 {
45 ////////////////////////////////////////////////////////////////////////////
46 // Initialization
47 ////////////////////////////////////////////////////////////////////////////
48
49
50 /**
51 * Initializes a barrier object which releases threads in groups of limit
52 * in size.
53 *
54 * Params:
55 * limit = The number of waiting threads to release in unison.
56 *
57 * Throws:
58 * SyncException on error.
59 */
60 this( uint limit )
61 in
62 {
63 assert( limit > 0 );
64 }
65 body
66 {
67 m_lock = new Mutex;
68 m_cond = new Condition( m_lock );
69 m_group = 0;
70 m_limit = limit;
71 m_count = limit;
72 }
73
74
75 ////////////////////////////////////////////////////////////////////////////
76 // General Actions
77 ////////////////////////////////////////////////////////////////////////////
78
79
80 /**
81 * Wait for the pre-determined number of threads and then proceed.
82 *
83 * Throws:
84 * SyncException on error.
85 */
86 void wait()
87 {
88 synchronized( m_lock )
89 {
90 uint group = m_group;
91
92 if( --m_count == 0 )
93 {
94 m_group++;
95 m_count = m_limit;
96 m_cond.notifyAll();
97 }
98 while( group == m_group )
99 m_cond.wait();
100 }
101 }
102
103
104 private:
105 Mutex m_lock;
106 Condition m_cond;
107 uint m_group;
108 uint m_limit;
109 uint m_count;
110 }
111
112
113 ////////////////////////////////////////////////////////////////////////////////
114 // Unit Tests
115 ////////////////////////////////////////////////////////////////////////////////
116
117
118 version( unittest )
119 {
120 private import core.thread;
121
122
123 unittest
124 {
125 int numThreads = 10;
126 auto barrier = new Barrier( numThreads );
127 auto synInfo = new Object;
128 int numReady = 0;
129 int numPassed = 0;
130
131 void threadFn()
132 {
133 synchronized( synInfo )
134 {
135 ++numReady;
136 }
137 barrier.wait();
138 synchronized( synInfo )
139 {
140 ++numPassed;
141 }
142 }
143
144 auto group = new ThreadGroup;
145
146 for( int i = 0; i < numThreads; ++i )
147 {
148 group.create( &threadFn );
149 }
150 group.joinAll();
151 assert( numReady == numThreads && numPassed == numThreads );
152 }
153 }