summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2011-07-11 19:20:21 +0200
committerMichael Bien <[email protected]>2011-07-11 19:20:21 +0200
commit29deee58472b1c475955718db7b1246fbb1df9d6 (patch)
treed5850055efc4714bfa7587aa7fd22b5db1149163
parent519cfb8a41e28e4d10e40496893a9aacf0bce6b1 (diff)
changed resource release synchronization in a way that we can allow concurrent releases of the root and children of the resource hierarchy without a global lock (and a "already released" exception).
-rw-r--r--src/com/jogamp/opencl/CLBuffer.java2
-rw-r--r--src/com/jogamp/opencl/CLCommandQueue.java2
-rw-r--r--src/com/jogamp/opencl/CLContext.java20
-rw-r--r--src/com/jogamp/opencl/CLKernel.java2
-rw-r--r--src/com/jogamp/opencl/CLMemory.java2
-rw-r--r--src/com/jogamp/opencl/CLObjectResource.java2
-rw-r--r--src/com/jogamp/opencl/CLProgram.java20
-rw-r--r--src/com/jogamp/opencl/CLSampler.java2
-rw-r--r--src/com/jogamp/opencl/CLSubBuffer.java2
9 files changed, 35 insertions, 19 deletions
diff --git a/src/com/jogamp/opencl/CLBuffer.java b/src/com/jogamp/opencl/CLBuffer.java
index 03e07477..d4e0d003 100644
--- a/src/com/jogamp/opencl/CLBuffer.java
+++ b/src/com/jogamp/opencl/CLBuffer.java
@@ -127,7 +127,7 @@ public class CLBuffer<B extends Buffer> extends CLMemory<B> {
}
@Override
- public void release() {
+ public synchronized void release() {
if(childs != null) {
while(!childs.isEmpty()) {
childs.get(0).release();
diff --git a/src/com/jogamp/opencl/CLCommandQueue.java b/src/com/jogamp/opencl/CLCommandQueue.java
index b1644cf2..016192c3 100644
--- a/src/com/jogamp/opencl/CLCommandQueue.java
+++ b/src/com/jogamp/opencl/CLCommandQueue.java
@@ -1796,7 +1796,7 @@ public class CLCommandQueue extends CLObjectResource {
}
@Override
- public void release() {
+ public synchronized void release() {
super.release();
int ret = cl.clReleaseCommandQueue(ID);
context.onCommandQueueReleased(device, this);
diff --git a/src/com/jogamp/opencl/CLContext.java b/src/com/jogamp/opencl/CLContext.java
index 54f95728..928adabb 100644
--- a/src/com/jogamp/opencl/CLContext.java
+++ b/src/com/jogamp/opencl/CLContext.java
@@ -510,13 +510,27 @@ public class CLContext extends CLObjectResource {
public void removeCLErrorHandler(CLErrorHandler handler) {
errorHandler.removeHandler(handler);
}
-
+
+ /*
+ * We have a hierarchy of resources and we don't want any
+ * global lock in the create or release methods. context.release() releases the whole hierarchy
+ * but in the meantime a other thread could have already release a child resource.
+ */
private void release(Collection<? extends CLResource> resources) {
// resources remove themselves when released, see above
if(!resources.isEmpty()) {
- CLResource[] array = resources.toArray(new CLResource[resources.size()]);
+ // copy to workaround concurrent modification exceptions
+ CLResource[] array = null;
+ synchronized(resources) {
+ array = resources.toArray(new CLResource[resources.size()]);
+ }
for (CLResource resource : array) {
- resource.release();
+ synchronized(resource) {
+ // released==true can only happen if an other thread released the resource while we where iterating
+ if(!resource.isReleased()) {
+ resource.release();
+ }
+ }
}
}
}
diff --git a/src/com/jogamp/opencl/CLKernel.java b/src/com/jogamp/opencl/CLKernel.java
index 7d5751fd..4d06d8b9 100644
--- a/src/com/jogamp/opencl/CLKernel.java
+++ b/src/com/jogamp/opencl/CLKernel.java
@@ -632,7 +632,7 @@ public class CLKernel extends CLObjectResource implements Cloneable {
* Releases all resources of this kernel from its context.
*/
@Override
- public void release() {
+ public synchronized void release() {
super.release();
int ret = binding.clReleaseKernel(ID);
program.onKernelReleased(this);
diff --git a/src/com/jogamp/opencl/CLMemory.java b/src/com/jogamp/opencl/CLMemory.java
index 0edfb7e2..eee025e6 100644
--- a/src/com/jogamp/opencl/CLMemory.java
+++ b/src/com/jogamp/opencl/CLMemory.java
@@ -221,7 +221,7 @@ public abstract class CLMemory <B extends Buffer> extends CLObjectResource {
}
@Override
- public void release() {
+ public synchronized void release() {
super.release();
int ret = binding.clReleaseMemObject(ID);
context.onMemoryReleased(this);
diff --git a/src/com/jogamp/opencl/CLObjectResource.java b/src/com/jogamp/opencl/CLObjectResource.java
index 3a8fe500..f11e4f97 100644
--- a/src/com/jogamp/opencl/CLObjectResource.java
+++ b/src/com/jogamp/opencl/CLObjectResource.java
@@ -11,7 +11,7 @@ import com.jogamp.common.AutoCloseable;
*/
abstract class CLObjectResource extends CLObject implements CLResource, AutoCloseable {
- private boolean released;
+ protected volatile boolean released;
public CLObjectResource(long ID) {
super(ID);
diff --git a/src/com/jogamp/opencl/CLProgram.java b/src/com/jogamp/opencl/CLProgram.java
index 3fcee4a7..f8c83def 100644
--- a/src/com/jogamp/opencl/CLProgram.java
+++ b/src/com/jogamp/opencl/CLProgram.java
@@ -70,11 +70,10 @@ public class CLProgram extends CLObjectResource {
private Map<CLDevice, Status> buildStatusMap;
private boolean executable;
- private boolean released;
private CLProgram(CLContext context, long id) {
super(context, id);
- this.kernels = new HashSet<CLKernel>();
+ this.kernels = Collections.synchronizedSet(new HashSet<CLKernel>());
this.binding = context.getPlatform().getProgramBinding();
}
@@ -486,13 +485,12 @@ public class CLProgram extends CLObjectResource {
* Releases this program with its kernels.
*/
@Override
- public void release() {
+ public synchronized void release() {
super.release();
releaseKernels();
executable = false;
- released = true;
buildStatusMap = null;
int ret = binding.clReleaseProgram(ID);
@@ -503,11 +501,15 @@ public class CLProgram extends CLObjectResource {
}
private void releaseKernels() {
- if(!kernels.isEmpty()) {
- // copy to array to prevent concurrent modification exception
- CLKernel[] array = kernels.toArray(new CLKernel[kernels.size()]);
- for (CLKernel kernel : array) {
- kernel.release();
+ synchronized(kernels) {
+ if(!kernels.isEmpty()) {
+ // copy to array to prevent concurrent modification exception
+ CLKernel[] array = kernels.toArray(new CLKernel[kernels.size()]);
+ for (CLKernel kernel : array) {
+ if(!kernel.isReleased()) {
+ kernel.release();
+ }
+ }
}
}
}
diff --git a/src/com/jogamp/opencl/CLSampler.java b/src/com/jogamp/opencl/CLSampler.java
index 3f145b3b..c5b01c8b 100644
--- a/src/com/jogamp/opencl/CLSampler.java
+++ b/src/com/jogamp/opencl/CLSampler.java
@@ -79,7 +79,7 @@ public class CLSampler extends CLObjectResource {
}
@Override
- public void release() {
+ public synchronized void release() {
super.release();
int ret = binding.clReleaseSampler(ID);
context.onSamplerReleased(this);
diff --git a/src/com/jogamp/opencl/CLSubBuffer.java b/src/com/jogamp/opencl/CLSubBuffer.java
index d8831783..758ccf66 100644
--- a/src/com/jogamp/opencl/CLSubBuffer.java
+++ b/src/com/jogamp/opencl/CLSubBuffer.java
@@ -57,7 +57,7 @@ public class CLSubBuffer<B extends Buffer> extends CLBuffer<B> {
}
@Override
- public void release() {
+ public synchronized void release() {
parent.onReleaseSubBuffer(this);
super.release();
}