Mercurial > projects > ldc
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 } |