diff options
author | Michael Bien <[email protected]> | 2010-03-15 17:03:58 +0100 |
---|---|---|
committer | Michael Bien <[email protected]> | 2010-03-15 17:03:58 +0100 |
commit | 68b70f68f42a0fce94aea9c47981edc8de5dd1d1 (patch) | |
tree | 12d5aa9541b4b2e03fea009851660e3cddf40597 /src | |
parent | 49fdecee2ce2c43aca0e444330b9c605d209fcfb (diff) |
MultiQueueBarrier is now reusable.
Diffstat (limited to 'src')
-rw-r--r-- | src/com/mbien/opencl/util/MultiQueueBarrier.java | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/src/com/mbien/opencl/util/MultiQueueBarrier.java b/src/com/mbien/opencl/util/MultiQueueBarrier.java index a23ca9ad..7ac45f6a 100644 --- a/src/com/mbien/opencl/util/MultiQueueBarrier.java +++ b/src/com/mbien/opencl/util/MultiQueueBarrier.java @@ -10,12 +10,14 @@ import java.util.concurrent.TimeUnit; /** * An utility for synchronizing multiple concurrent {@link CLCommandQueue}s. + * This Barrier can be reused after it has been broken. * @author Michael Bien */ public class MultiQueueBarrier { private CountDownLatch latch; private final Set<CLCommandQueue> queues; + private final int count; /** * Creates a new MultiQueueBarrier with the given queueCount. @@ -23,15 +25,23 @@ public class MultiQueueBarrier { * which restricts the set of allowed queues for the barrier. */ public MultiQueueBarrier(int queueCount) { + if(queueCount == 0) { + throw new IllegalArgumentException("queueCount was 0"); + } this.latch = new CountDownLatch(queueCount); this.queues = null; + this.count = queueCount; } /** * Creates a new MultiQueueBarrier for the given queues. */ public MultiQueueBarrier(CLCommandQueue... allowedQueues) { + if(allowedQueues.length == 0) { + throw new IllegalArgumentException("allowedQueues was empty"); + } this.latch = new CountDownLatch(allowedQueues.length); + this.count = allowedQueues.length; HashSet<CLCommandQueue> set = new HashSet<CLCommandQueue>(allowedQueues.length); for (CLCommandQueue queue : allowedQueues) { @@ -49,7 +59,9 @@ public class MultiQueueBarrier { checkQueue(queue); queue.putBarrier(); - latch.countDown(); + synchronized(this) { + latch.countDown(); + } return this; } @@ -62,7 +74,9 @@ public class MultiQueueBarrier { checkQueue(queue); queue.putWaitForEvents(events, true); - latch.countDown(); + synchronized(this) { + latch.countDown(); + } return this; } @@ -73,6 +87,7 @@ public class MultiQueueBarrier { */ public MultiQueueBarrier await() throws InterruptedException { latch.await(); + rebuildBarrierIfBroken(); return this; } @@ -83,15 +98,30 @@ public class MultiQueueBarrier { */ public MultiQueueBarrier await(long timeout, TimeUnit unit) throws InterruptedException { latch.await(timeout, unit); + rebuildBarrierIfBroken(); return this; } /** - * Cancels this barrier and unblocks all waiting threads. + * Resets this barrier and unblocks all waiting threads. */ - public void cancelBarrier() { - while(latch.getCount() > 0) - latch.countDown(); + public void resetBarrier() { + synchronized(this) { + while(latch.getCount() > 0) { + latch.countDown(); + } + // thats OK. Another Thread can not rebuild the barrier since we have the lock. + // we have to rebuid it here in case there was no thread waiting. + latch = new CountDownLatch(count); + } + } + + private void rebuildBarrierIfBroken() { + synchronized (this) { + if (latch.getCount() == 0) { + latch = new CountDownLatch(count); + } + } } /** |