mirror of
https://review.haiku-os.org/buildtools
synced 2025-02-14 09:47:56 +01:00
Updated dependencies: * GMP 6.2.1 * ISL 0.24 * MPL 1.2.1 * MPFR 4.1.0 The dependencies were pulled in by running the ./contrib/download_prerequisites script and then manually removing the symbolic links and archives, and renaming the directories (i.e mv isl-0.24 to isl)
141 lines
3.2 KiB
D
141 lines
3.2 KiB
D
/**
|
|
* The barrier module provides a primitive for synchronizing the progress of
|
|
* a group of threads.
|
|
*
|
|
* Copyright: Copyright Sean Kelly 2005 - 2009.
|
|
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
|
|
* Authors: Sean Kelly
|
|
* Source: $(DRUNTIMESRC core/sync/_barrier.d)
|
|
*/
|
|
|
|
/* Copyright Sean Kelly 2005 - 2009.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE or copy at
|
|
* http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
module core.sync.barrier;
|
|
|
|
|
|
public import core.sync.exception;
|
|
import core.sync.condition;
|
|
import core.sync.mutex;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Barrier
|
|
//
|
|
// void wait();
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/**
|
|
* This class represents a barrier across which threads may only travel in
|
|
* groups of a specific size.
|
|
*/
|
|
class Barrier
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Initialization
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/**
|
|
* Initializes a barrier object which releases threads in groups of limit
|
|
* in size.
|
|
*
|
|
* Params:
|
|
* limit = The number of waiting threads to release in unison.
|
|
*
|
|
* Throws:
|
|
* SyncError on error.
|
|
*/
|
|
this( uint limit )
|
|
in
|
|
{
|
|
assert( limit > 0 );
|
|
}
|
|
do
|
|
{
|
|
m_lock = new Mutex;
|
|
m_cond = new Condition( m_lock );
|
|
m_group = 0;
|
|
m_limit = limit;
|
|
m_count = limit;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// General Actions
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/**
|
|
* Wait for the pre-determined number of threads and then proceed.
|
|
*
|
|
* Throws:
|
|
* SyncError on error.
|
|
*/
|
|
void wait()
|
|
{
|
|
synchronized( m_lock )
|
|
{
|
|
uint group = m_group;
|
|
|
|
if ( --m_count == 0 )
|
|
{
|
|
m_group++;
|
|
m_count = m_limit;
|
|
m_cond.notifyAll();
|
|
}
|
|
while ( group == m_group )
|
|
m_cond.wait();
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
Mutex m_lock;
|
|
Condition m_cond;
|
|
uint m_group;
|
|
uint m_limit;
|
|
uint m_count;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Unit Tests
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
unittest
|
|
{
|
|
import core.thread;
|
|
|
|
int numThreads = 10;
|
|
auto barrier = new Barrier( numThreads );
|
|
auto synInfo = new Object;
|
|
int numReady = 0;
|
|
int numPassed = 0;
|
|
|
|
void threadFn()
|
|
{
|
|
synchronized( synInfo )
|
|
{
|
|
++numReady;
|
|
}
|
|
barrier.wait();
|
|
synchronized( synInfo )
|
|
{
|
|
++numPassed;
|
|
}
|
|
}
|
|
|
|
auto group = new ThreadGroup;
|
|
|
|
for ( int i = 0; i < numThreads; ++i )
|
|
{
|
|
group.create( &threadFn );
|
|
}
|
|
group.joinAll();
|
|
assert( numReady == numThreads && numPassed == numThreads );
|
|
}
|