From c8afa2e38a7d7174ceed0be2069856ed548192b4 Mon Sep 17 00:00:00 2001
From: Michael Bien
Date: Tue, 8 Feb 2011 23:30:18 +0100
Subject: CLContext and CLPlatform are now threadsafe. Updated javadocs.
---
src/com/jogamp/opencl/CLContext.java | 112 +++++++++++++++++++++-------------
src/com/jogamp/opencl/CLPlatform.java | 4 +-
2 files changed, 72 insertions(+), 44 deletions(-)
(limited to 'src/com/jogamp')
diff --git a/src/com/jogamp/opencl/CLContext.java b/src/com/jogamp/opencl/CLContext.java
index 8f5c411b..b7ddb813 100644
--- a/src/com/jogamp/opencl/CLContext.java
+++ b/src/com/jogamp/opencl/CLContext.java
@@ -47,30 +47,45 @@ import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static java.lang.System.*;
import static com.jogamp.opencl.CLException.*;
import static com.jogamp.common.nio.Buffers.*;
import static com.jogamp.common.os.Platform.*;
import static com.jogamp.opencl.CL.*;
import static com.jogamp.opencl.CLBuffer.*;
+import static java.util.Collections.*;
/**
* CLContext is responsible for managing objects such as command-queues, memory,
* program and kernel objects and for executing kernels on one or more devices
* specified in the context.
+ *
+ * Must be released if no longer used to free native resources. {@link #release()} will
+ * also free all associated {@link CLResource} like programs, samplers, command queues and memory
+ * objects.
+ *
+ *
+ * For a code example see {@link CLPlatform}.
+ *
+ *
+ * concurrency:
+ * CLContext is threadsafe.
+ *
* @author Michael Bien
*/
public class CLContext extends CLObject implements CLResource {
protected CLDevice[] devices;
- protected final List programs;
- protected final List samplers;
- protected final List> memoryObjects;
+ protected final Set programs;
+ protected final Set samplers;
+ protected final Set> memoryObjects;
protected final Map> queuesMap;
@@ -81,10 +96,13 @@ public class CLContext extends CLObject implements CLResource {
protected CLContext(CLPlatform platform, long contextID, ErrorDispatcher dispatcher) {
super(CLPlatform.getLowLevelCLInterface(), contextID);
this.platform = platform;
- this.programs = new ArrayList();
- this.samplers = new ArrayList();
- this.memoryObjects = new ArrayList>();
+
+ this.programs = synchronizedSet(new HashSet());
+ this.samplers = synchronizedSet(new HashSet());
+ this.memoryObjects = synchronizedSet(new HashSet>());
+
this.queuesMap = new HashMap>();
+
this.errorHandler = dispatcher;
/*
@@ -97,7 +115,7 @@ public class CLContext extends CLObject implements CLResource {
}
- private void initDevices() {
+ private synchronized void initDevices() {
if (devices == null) {
@@ -415,12 +433,14 @@ public class CLContext extends CLObject implements CLResource {
CLCommandQueue queue = CLCommandQueue.create(this, device, properties);
- List list = queuesMap.get(device);
- if(list == null) {
- list = new ArrayList();
- queuesMap.put(device, list);
+ synchronized(queuesMap) {
+ List list = queuesMap.get(device);
+ if(list == null) {
+ list = new ArrayList();
+ queuesMap.put(device, list);
+ }
+ list.add(queue);
}
- list.add(queue);
return queue;
}
@@ -440,11 +460,13 @@ public class CLContext extends CLObject implements CLResource {
}
void onCommandQueueReleased(CLDevice device, CLCommandQueue queue) {
- List list = queuesMap.get(device);
- list.remove(queue);
- // remove empty lists from map
- if(list.isEmpty())
- queuesMap.remove(device);
+ synchronized(queuesMap) {
+ List list = queuesMap.get(device);
+ list.remove(queue);
+ // remove empty lists from map
+ if(list.isEmpty())
+ queuesMap.remove(device);
+ }
}
void onSamplerReleased(CLSampler sampler) {
@@ -458,30 +480,28 @@ public class CLContext extends CLObject implements CLResource {
public void removeCLErrorHandler(CLErrorHandler handler) {
errorHandler.removeHandler(handler);
}
+
+ private void release(Collection extends CLResource> resources) {
+ // resources remove themselves when released, see above
+ CLResource[] array = resources.toArray(new CLResource[resources.size()]);
+ for (CLResource resource : array) {
+ resource.release();
+ }
+ }
/**
- * Releases the context and all resources.
+ * Releases this context and all resources.
*/
- public void release() {
+ public synchronized void release() {
try{
//release all resources
- while(!programs.isEmpty())
- programs.get(0).release();
-
- while(!memoryObjects.isEmpty())
- memoryObjects.get(0).release();
-
- while(!samplers.isEmpty())
- samplers.get(0).release();
+ release(programs);
+ release(memoryObjects);
+ release(samplers);
for (CLDevice device : getDevices()) {
- List list = queuesMap.get(device);
- if(list != null) {
- while(!list.isEmpty()) {
- list.get(0).release();
- }
- }
+ release(queuesMap.get(device));
}
}finally{
@@ -553,24 +573,30 @@ public class CLContext extends CLObject implements CLResource {
}
/**
- * Returns a read only view of all programs associated with this context.
+ * Returns a read only shapshot of all programs associated with this context.
*/
public List getPrograms() {
- return Collections.unmodifiableList(programs);
+ synchronized(programs) {
+ return unmodifiableList(new ArrayList(programs));
+ }
}
/**
- * Returns a read only view of all allocated memory objects associated with this context.
+ * Returns a read only shapshot of all allocated memory objects associated with this context.
*/
public List> getMemoryObjects() {
- return Collections.unmodifiableList(memoryObjects);
+ synchronized(memoryObjects) {
+ return unmodifiableList(new ArrayList>(memoryObjects));
+ }
}
/**
- * Returns a read only view of all samplers associated with this context.
+ * Returns a read only shapshot of all samplers associated with this context.
*/
public List getSamplers() {
- return Collections.unmodifiableList(samplers);
+ synchronized(samplers) {
+ return unmodifiableList(new ArrayList(samplers));
+ }
}
/**
@@ -667,7 +693,7 @@ public class CLContext extends CLObject implements CLResource {
protected static class ErrorDispatcher implements CLErrorHandler {
- private volatile CLErrorHandler[] clientHandlers = new CLErrorHandler[0];
+ private CLErrorHandler[] clientHandlers = new CLErrorHandler[0];
public void onError(String errinfo, ByteBuffer private_info, long cb) {
CLErrorHandler[] handlers = this.clientHandlers;
@@ -676,7 +702,7 @@ public class CLContext extends CLObject implements CLResource {
}
}
- private void addHandler(CLErrorHandler handler) {
+ private synchronized void addHandler(CLErrorHandler handler) {
if(handler == null) {
throw new IllegalArgumentException("handler was null.");
@@ -688,7 +714,7 @@ public class CLContext extends CLObject implements CLResource {
clientHandlers = handlers;
}
- private void removeHandler(CLErrorHandler handler) {
+ private synchronized void removeHandler(CLErrorHandler handler) {
if(handler == null) {
throw new IllegalArgumentException("handler was null.");
diff --git a/src/com/jogamp/opencl/CLPlatform.java b/src/com/jogamp/opencl/CLPlatform.java
index 1db3dcf2..218efed3 100644
--- a/src/com/jogamp/opencl/CLPlatform.java
+++ b/src/com/jogamp/opencl/CLPlatform.java
@@ -82,6 +82,8 @@ import static com.jogamp.opencl.CL.*;
* context.release();
* }
*
+ * concurrency:
+ * CLPlatform is threadsafe.
*
* @author Michael Bien
* @see #initialize()
@@ -441,7 +443,7 @@ public final class CLPlatform {
* Returns all platform extension names as unmodifiable Set.
*/
@CLProperty("CL_PLATFORM_EXTENSIONS")
- public Set getExtensions() {
+ public synchronized Set getExtensions() {
if(extensions == null) {
extensions = new HashSet();
--
cgit v1.2.3