JOCL v2.6.0-rc-20250722
JOCL, OpenCL® API Binding for Java™ (public API).
MultiQueueBarrier.java
Go to the documentation of this file.
1/*
2 * Copyright 2009 - 2010 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opencl.util;
30
31import com.jogamp.opencl.CLCommandQueue;
32import com.jogamp.opencl.CLEventList;
33import java.util.Collections;
34import java.util.HashSet;
35import java.util.Set;
36import java.util.concurrent.CountDownLatch;
37import java.util.concurrent.TimeUnit;
38
39/**
40 * An utility for synchronizing multiple concurrent {@link CLCommandQueue}s.
41 * This Barrier can be reused after it has been broken.
42 * @author Michael Bien
43 */
44public class MultiQueueBarrier {
45
46 private CountDownLatch latch;
47 private final Set<CLCommandQueue> queues;
48 private final int count;
49
50 /**
51 * Creates a new MultiQueueBarrier with the given queueCount.
52 * It is recommented to use {@link #MultiQueueBarrier(CLCommandQueue... allowedQueues)} if possible
53 * which restricts the set of allowed queues for the barrier.
54 */
55 public MultiQueueBarrier(final int queueCount) {
56 if(queueCount == 0) {
57 throw new IllegalArgumentException("queueCount was 0");
58 }
59 this.latch = new CountDownLatch(queueCount);
60 this.queues = null;
61 this.count = queueCount;
62 }
63
64 /**
65 * Creates a new MultiQueueBarrier for the given queues.
66 */
67 public MultiQueueBarrier(final CLCommandQueue... allowedQueues) {
68 if(allowedQueues.length == 0) {
69 throw new IllegalArgumentException("allowedQueues was empty");
70 }
71 this.latch = new CountDownLatch(allowedQueues.length);
72 this.count = allowedQueues.length;
73
74 final HashSet<CLCommandQueue> set = new HashSet<CLCommandQueue>(allowedQueues.length);
75 for (final CLCommandQueue queue : allowedQueues) {
76 set.add(queue);
77 }
78 this.queues = Collections.unmodifiableSet(set);
79 }
80
81 /**
82 * Blocks the current Thread until all commands on the {@link CLCommandQueue} finished excecution.
83 * This method may be invoked concurrently without synchronization on the MultiQueueBarrier object
84 * as long each Thread passes a distinct CLCommandQueue as parameter to this method.
85 */
87 checkQueue(queue);
88
89 queue.putBarrier();
90 synchronized(this) {
91 latch.countDown();
92 }
93 return this;
94 }
95
96 /**
97 * Blocks the current Thread until the given events on the {@link CLCommandQueue} occurred.
98 * This method may be invoked concurrently without synchronization on the MultiQueueBarrier object
99 * as long each Thread passes a distinct CLCommandQueue as parameter to this method.
100 */
101 public MultiQueueBarrier waitFor(final CLCommandQueue queue, final CLEventList events) {
102 checkQueue(queue);
103
104 queue.putWaitForEvents(events, true);
105 synchronized(this) {
106 latch.countDown();
107 }
108 return this;
109 }
110
111 /**
112 * Blocks until all Threads which called {@link #waitFor}
113 * continue execution.
114 * This method blocks only once, all subsequent calls are ignored.
115 */
116 public MultiQueueBarrier await() throws InterruptedException {
117 latch.await();
118 rebuildBarrierIfBroken();
119 return this;
120 }
121
122 /**
123 * @see #await()
124 * @param timeout the maximum time to wait
125 * @param unit the time unit of the {@code timeout} argument
126 */
127 public boolean await(final long timeout, final TimeUnit unit) throws InterruptedException {
128 final boolean ret = latch.await(timeout, unit);
129 rebuildBarrierIfBroken();
130 return ret;
131 }
132
133 /**
134 * Resets this barrier and unblocks all waiting threads.
135 */
136 public void resetBarrier() {
137 synchronized(this) {
138 while(latch.getCount() > 0) {
139 latch.countDown();
140 }
141 // thats OK. Another Thread can not rebuild the barrier since we have the lock.
142 // we have to rebuid it here in case there was no thread waiting.
143 latch = new CountDownLatch(count);
144 }
145 }
146
147 private void rebuildBarrierIfBroken() {
148 synchronized (this) {
149 if (latch.getCount() == 0) {
150 latch = new CountDownLatch(count);
151 }
152 }
153 }
154
155 /**
156 * Returns the current number of events which must occure before this barrier unblocks the waiting threads.
157 * This method is typically used for debugging and testing purposes.
158 */
159 public long getCount() {
160 return latch.getCount();
161 }
162
163 private void checkQueue(final CLCommandQueue queue) throws IllegalArgumentException {
164 if (queues != null && !queues.contains(queue)) {
165 throw new IllegalArgumentException(queue + " is not in the allowedQueues Set: " + queues);
166 }
167 }
168
169}
The command queue is used to queue a set of operations for a specific CLDevice.
CLCommandQueue putBarrier()
Calls {@native clEnqueueBarrier}.
CLCommandQueue putWaitForEvents(final CLEventList list, final boolean blockingWait)
Calls {@native clWaitForEvents} if blockingWait equals true otherwise {@native clEnqueueWaitForEvents...
Fixed size list for storing CLEvents.
An utility for synchronizing multiple concurrent CLCommandQueues.
MultiQueueBarrier await()
Blocks until all Threads which called waitFor continue execution.
MultiQueueBarrier(final int queueCount)
Creates a new MultiQueueBarrier with the given queueCount.
boolean await(final long timeout, final TimeUnit unit)
MultiQueueBarrier waitFor(final CLCommandQueue queue, final CLEventList events)
Blocks the current Thread until the given events on the CLCommandQueue occurred.
MultiQueueBarrier waitFor(final CLCommandQueue queue)
Blocks the current Thread until all commands on the CLCommandQueue finished excecution.
long getCount()
Returns the current number of events which must occure before this barrier unblocks the waiting threa...
void resetBarrier()
Resets this barrier and unblocks all waiting threads.
MultiQueueBarrier(final CLCommandQueue... allowedQueues)
Creates a new MultiQueueBarrier for the given queues.