diff options
Diffstat (limited to 'src/com/jogamp/opencl/CLProgram.java')
-rw-r--r-- | src/com/jogamp/opencl/CLProgram.java | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/src/com/jogamp/opencl/CLProgram.java b/src/com/jogamp/opencl/CLProgram.java index 7e1ef6cf..3c68fa35 100644 --- a/src/com/jogamp/opencl/CLProgram.java +++ b/src/com/jogamp/opencl/CLProgram.java @@ -29,12 +29,11 @@ package com.jogamp.opencl; import com.jogamp.common.nio.CachedBufferFactory; -import com.jogamp.opencl.llb.CLProgramBinding; import com.jogamp.opencl.util.CLProgramConfiguration; import com.jogamp.opencl.util.CLUtil; import com.jogamp.common.os.Platform; import com.jogamp.common.nio.PointerBuffer; -import com.jogamp.opencl.llb.CLKernelBinding; +import com.jogamp.opencl.llb.CL; import com.jogamp.opencl.llb.impl.BuildProgramCallback; import com.jogamp.opencl.util.CLBuildListener; import java.nio.ByteBuffer; @@ -46,7 +45,7 @@ import java.util.LinkedHashMap; import java.util.Map.Entry; import java.util.Set; import java.util.Map; -import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.Semaphore; import static com.jogamp.opencl.CLException.*; import static com.jogamp.opencl.llb.CL.*; @@ -62,8 +61,10 @@ import static com.jogamp.common.nio.Buffers.*; */ public class CLProgram extends CLObjectResource { - private final static ReentrantLock buildLock = new ReentrantLock(); - private final CLProgramBinding binding; + // must use a semaphore instead of a reentrant lock because the CL implementation can call + // our notifier function from a different thread than the one that calls clBuildProgram + private final static Semaphore buildLock = new Semaphore(1, true); + private final CL binding; private final Set<CLKernel> kernels; private Map<CLDevice, Status> buildStatusMap; @@ -76,7 +77,7 @@ public class CLProgram extends CLObjectResource { private CLProgram(final CLContext context, final long id) { super(context, id); this.kernels = new HashSet<CLKernel>(); - this.binding = context.getPlatform().getProgramBinding(); + this.binding = context.getPlatform().getCLBinding(); } static CLProgram create(final CLContext context, final String src) { @@ -87,7 +88,7 @@ public class CLProgram extends CLObjectResource { final String[] srcArray = new String[] {src}; // Create the program - final CLProgramBinding binding = context.getPlatform().getProgramBinding(); + final CL binding = context.getPlatform().getCLBinding(); final long id = binding.clCreateProgramWithSource(context.ID, 1, srcArray, length, status); final int err = status.get(); @@ -133,7 +134,7 @@ public class CLProgram extends CLObjectResource { final IntBuffer errBuffer = bf.newDirectIntBuffer(1); // IntBuffer status = newDirectByteBuffer(binaries.size()*4).asIntBuffer(); - final CLProgramBinding binding = context.getPlatform().getProgramBinding(); + final CL binding = context.getPlatform().getCLBinding(); final long id = binding.clCreateProgramWithBinary(context.ID, devices.capacity(), devices, lengths, codeBuffers, /*status*/null, errBuffer); // while(status.remaining() != 0) { @@ -151,18 +152,16 @@ public class CLProgram extends CLObjectResource { private void initBuildStatus() { if(buildStatusMap == null) { -// synchronized(buildLock) { - final Map<CLDevice, Status> map = new HashMap<CLDevice, Status>(); - final CLDevice[] devices = getCLDevices(); - for (final CLDevice device : devices) { - final Status status = getBuildStatus(device); - if(status == Status.BUILD_SUCCESS) { - executable = true; - } - map.put(device, status); + final Map<CLDevice, Status> map = new HashMap<CLDevice, Status>(); + final CLDevice[] devices = getCLDevices(); + for (final CLDevice device : devices) { + final Status status = getBuildStatus(device); + if(status == Status.BUILD_SUCCESS) { + executable = true; } - this.buildStatusMap = Collections.unmodifiableMap(map); -// } + map.put(device, status); + } + this.buildStatusMap = Collections.unmodifiableMap(map); } } @@ -218,10 +217,6 @@ public class CLProgram extends CLObjectResource { return buffer.getInt(); } - private CLKernelBinding getKernelBinding() { - return getPlatform().getKernelBinding(); - } - /** * Builds this program for all devices associated with the context. * @return this @@ -364,7 +359,7 @@ public class CLProgram extends CLObjectResource { callback = new BuildProgramCallback() { @Override public void buildFinished(final long cl_program) { - buildLock.unlock(); + buildLock.release(); listener.buildFinished(CLProgram.this); } }; @@ -376,14 +371,19 @@ public class CLProgram extends CLObjectResource { // spec: building programs is not threadsafe, we are locking the API call to // make sure only one thread calls it at a time until it completes (asynchronous or synchronously). { - buildLock.lock(); + try { + buildLock.acquire(); + } catch(InterruptedException e) { + throw newException(ret, "\nInterrupted while waiting to get build lock"); + } + boolean exception = true; try{ ret = binding.clBuildProgram(ID, count, deviceIDs, options, callback); exception = false; }finally{ if(callback == null || exception) { - buildLock.unlock(); + buildLock.release(); } } } @@ -412,7 +412,7 @@ public class CLProgram extends CLObjectResource { } final int[] err = new int[1]; - final long id = getKernelBinding().clCreateKernel(ID, kernelName, err, 0); + final long id = binding.clCreateKernel(ID, kernelName, err, 0); if(err[0] != CL_SUCCESS) { throw newException(err[0], "unable to create Kernel with name: "+kernelName); } @@ -434,8 +434,7 @@ public class CLProgram extends CLObjectResource { final HashMap<String, CLKernel> newKernels = new HashMap<String, CLKernel>(); final IntBuffer numKernels = newDirectByteBuffer(4).asIntBuffer(); - final CLKernelBinding kernelBinding = getKernelBinding(); - int ret = kernelBinding.clCreateKernelsInProgram(ID, 0, null, numKernels); + int ret = binding.clCreateKernelsInProgram(ID, 0, null, numKernels); if(ret != CL_SUCCESS) { throw newException(ret, "can not create kernels for "+this); } @@ -443,7 +442,7 @@ public class CLProgram extends CLObjectResource { if(numKernels.get(0) > 0) { final PointerBuffer kernelIDs = PointerBuffer.allocateDirect(numKernels.get(0)); - ret = kernelBinding.clCreateKernelsInProgram(ID, kernelIDs.capacity(), kernelIDs, null); + ret = binding.clCreateKernelsInProgram(ID, kernelIDs.capacity(), kernelIDs, null); if(ret != CL_SUCCESS) { throw newException(ret, "can not create "+kernelIDs.capacity()+" kernels for "+this); } |