diff options
author | Michael Bien <[email protected]> | 2011-07-11 19:20:21 +0200 |
---|---|---|
committer | Michael Bien <[email protected]> | 2011-07-11 19:20:21 +0200 |
commit | 29deee58472b1c475955718db7b1246fbb1df9d6 (patch) | |
tree | d5850055efc4714bfa7587aa7fd22b5db1149163 | |
parent | 519cfb8a41e28e4d10e40496893a9aacf0bce6b1 (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.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLCommandQueue.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLContext.java | 20 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLKernel.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLMemory.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLObjectResource.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLProgram.java | 20 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLSampler.java | 2 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLSubBuffer.java | 2 |
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(); } |