summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resources/cl-common.cfg1
-rw-r--r--resources/cl-if.cfg7
-rw-r--r--resources/cl-impl.cfg3
-rw-r--r--resources/clImplCustomCode.c66
-rw-r--r--src/com/jogamp/opencl/CLEvent.java19
-rw-r--r--src/com/jogamp/opencl/CLEventListener.java15
-rw-r--r--src/com/jogamp/opencl/impl/CLEventCallback.java15
-rw-r--r--src/com/jogamp/opencl/impl/CLImpl.java11
-rw-r--r--test/com/jogamp/opencl/CLCommandQueueTest.java40
9 files changed, 167 insertions, 10 deletions
diff --git a/resources/cl-common.cfg b/resources/cl-common.cfg
index c5cf4f62..f9c32c84 100644
--- a/resources/cl-common.cfg
+++ b/resources/cl-common.cfg
@@ -108,5 +108,4 @@ TagNativeBinding true
Ignore .*APPLE.*
# TODO implement custom callbacks if this makes sense
-Ignore clSetEventCallback
Ignore clSetMemObjectDestructorCallback
diff --git a/resources/cl-if.cfg b/resources/cl-if.cfg
index 6f19e64f..b8deb126 100644
--- a/resources/cl-if.cfg
+++ b/resources/cl-if.cfg
@@ -6,7 +6,8 @@ Style InterfaceOnly
Import java.nio.IntBuffer
Import java.nio.LongBuffer
Import com.jogamp.opencl.impl.CLImageFormatImpl
-import com.jogamp.opencl.impl.BuildProgramCallback;
+import com.jogamp.opencl.impl.BuildProgramCallback
+import com.jogamp.opencl.impl.CLEventCallback
ClassJavadoc CL /**
ClassJavadoc CL * Java bindings to OpenCL, the Open Computing Language.
@@ -33,6 +34,10 @@ CustomJavaCode CL
CustomJavaCode CL /** Interface to C language function: <br> <code> int32_t {@native clBuildProgram}(cl_program, uint32_t, cl_device_id * , const char * , void (*pfn_notify)(cl_program, void *user_data), void * ); </code> */
CustomJavaCode CL public int clBuildProgram(long program, int deviceCount, PointerBuffer devices, String options, BuildProgramCallback cb);
+Ignore clSetEventCallback
+CustomJavaCode CL
+CustomJavaCode CL public int clSetEventCallback(long event, int type, CLEventCallback listener);
+
Ignore clEnqueueNativeKernel
#TODO..
diff --git a/resources/cl-impl.cfg b/resources/cl-impl.cfg
index f42b814c..f3367eac 100644
--- a/resources/cl-impl.cfg
+++ b/resources/cl-impl.cfg
@@ -72,6 +72,9 @@ ForceProcAddressGen clEnqueueNativeKernel
Ignore clReleaseContext
ForceProcAddressGen clReleaseContext
+Ignore clSetEventCallback
+ForceProcAddressGen clSetEventCallback
+
#take buffer capacity from input param 5
ReturnValueCapacity clEnqueueMapBuffer {5}
diff --git a/resources/clImplCustomCode.c b/resources/clImplCustomCode.c
index 89b350ec..bf4cf1c9 100644
--- a/resources/clImplCustomCode.c
+++ b/resources/clImplCustomCode.c
@@ -9,8 +9,10 @@ void checkStatus(const char* msg, int status) {
JavaVM * jvm;
-jmethodID bcb_mid;
-jmethodID cccb_mid;
+jmethodID buildCB_mid;
+jmethodID contextCB_mid;
+jmethodID eventCB_mid;
+jmethodID memObjCB_mid;
JNIEXPORT jint JNICALL
@@ -26,14 +28,22 @@ JNI_OnLoad(JavaVM * _jvm, void *reserved) {
// throws ClassNotFoundException (or other reflection stuff)
jclass buildCBClassID = (*env)->FindClass(env, "com/jogamp/opencl/impl/BuildProgramCallback");
jclass errorHandlerClassID = (*env)->FindClass(env, "com/jogamp/opencl/CLErrorHandler");
+ jclass eventCBClassID = (*env)->FindClass(env, "com/jogamp/opencl/impl/CLEventCallback");
+ jclass memObjCBClassID = (*env)->FindClass(env, "com/jogamp/opencl/CLMemObjectDestructorCallback");
// throws even more reflection Exceptions
// IDs are unique and do not change
if (buildCBClassID != NULL) {
- bcb_mid = (*env)->GetMethodID(env, buildCBClassID, "buildFinished", "(J)V");
+ buildCB_mid = (*env)->GetMethodID(env, buildCBClassID, "buildFinished", "(J)V");
}
if (errorHandlerClassID != NULL) {
- cccb_mid = (*env)->GetMethodID(env, errorHandlerClassID, "onError", "(Ljava/lang/String;Ljava/nio/ByteBuffer;J)V");
+ contextCB_mid = (*env)->GetMethodID(env, errorHandlerClassID, "onError", "(Ljava/lang/String;Ljava/nio/ByteBuffer;J)V");
+ }
+ if (eventCBClassID != NULL) {
+ eventCB_mid = (*env)->GetMethodID(env, eventCBClassID, "eventStateChanged", "(JI)V");
+ }
+ if (memObjCBClassID != NULL) {
+ memObjCB_mid = (*env)->GetMethodID(env, memObjCBClassID, "memoryDeallocated", "(Lcom/jogamp/opencl/CLMemory;)V");
}
return JNI_VERSION_1_2;
@@ -43,6 +53,8 @@ JNI_OnLoad(JavaVM * _jvm, void *reserved) {
// callbacks
typedef void (CL_CALLBACK * cccallback)(const char *, const void *, size_t, void *);
typedef void (CL_CALLBACK * bpcallback)(cl_program, void *);
+typedef void (CL_CALLBACK * evcallback)(cl_event, cl_int, void *);
+typedef void (CL_CALLBACK * mocallback)(cl_mem, void *);
CL_CALLBACK void buildProgramCallback(cl_program id, void * object) {
@@ -51,7 +63,7 @@ CL_CALLBACK void buildProgramCallback(cl_program id, void * object) {
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
- (*env)->CallVoidMethod(env, obj, bcb_mid, (jlong)(intptr_t)id);
+ (*env)->CallVoidMethod(env, obj, buildCB_mid, (jlong)(intptr_t)id);
(*env)->DeleteGlobalRef(env, obj);
(*jvm)->DetachCurrentThread(jvm);
@@ -68,12 +80,35 @@ CL_CALLBACK void createContextCallback(const char * errinfo, const void * privat
jstring errorString = (*env)->NewStringUTF(env, errinfo);
//TODO private_info
- (*env)->CallVoidMethod(env, obj, cccb_mid, errorString, NULL, 0);
+ (*env)->CallVoidMethod(env, obj, contextCB_mid, errorString, NULL, 0);
(*jvm)->DetachCurrentThread(jvm);
}
+CL_CALLBACK void eventCallback(cl_event event, cl_int status, void * object) {
+
+ JNIEnv *env;
+ jobject obj = (jobject)object;
+
+ (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
+
+ (*env)->CallVoidMethod(env, obj, eventCB_mid, event, status);
+ (*env)->DeleteGlobalRef(env, obj); // events can only fire once
+
+ (*jvm)->DetachCurrentThread(jvm);
+}
+/*
+CL_CALLBACK void memObjDestructorCallback(cl_mem mem, void * object) {
+
+ JNIEnv *env;
+ jobject obj = (jobject)object;
+
+ (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
+
+ (*jvm)->DetachCurrentThread(jvm);
+}
+*/
/* Java->C glue code:
* Java package: com.jogamp.opencl.impl.CLImpl
@@ -338,4 +373,21 @@ Java_com_jogamp_opencl_impl_CLImpl_clEnqueueMapImage0__JJIJLjava_lang_Object_2IL
}
return (*env)->NewDirectByteBuffer(env, _res, pixels * (*elements));
-} \ No newline at end of file
+
+}
+
+JNIEXPORT jint JNICALL
+Java_com_jogamp_opencl_impl_CLImpl_clSetEventCallback0(JNIEnv *env, jobject _unused,
+ jlong event, jint trigger, jobject listener, jlong procAddress) {
+
+ cl_event _event = event;
+ cl_int _trigger = trigger;
+ cl_int _res;
+ typedef int32_t (*function)(cl_event, cl_int, void (*pfn_event_notify) (cl_event, cl_int, void *), void *);
+ function clSetEventCallback = (function)(intptr_t) procAddress;
+
+ jobject cb = (*env)->NewGlobalRef(env, listener);
+ _res = (*clSetEventCallback)(_event, _trigger, &eventCallback, cb);
+
+ return _res;
+}
diff --git a/src/com/jogamp/opencl/CLEvent.java b/src/com/jogamp/opencl/CLEvent.java
index b7df1465..8423e7c6 100644
--- a/src/com/jogamp/opencl/CLEvent.java
+++ b/src/com/jogamp/opencl/CLEvent.java
@@ -1,7 +1,10 @@
package com.jogamp.opencl;
+import com.jogamp.opencl.impl.CLEventCallback;
+import java.util.List;
import com.jogamp.common.nio.PointerBuffer;
import java.nio.Buffer;
+import java.util.ArrayList;
import static com.jogamp.opencl.CL.*;
import static com.jogamp.opencl.CLException.*;
@@ -25,6 +28,22 @@ public class CLEvent extends CLObject implements CLResource {
this.eventProfilingInfo = new CLEventProfilingInfoAccessor();
}
+ /**
+ * Registers a callback which will be called when the event terminates (COMPLETE or ERROR).
+ */
+ public void registerCallback(final CLEventListener callback) {
+ this.registerCallback(callback, ExecutionStatus.COMPLETE);
+ }
+
+ // apparently only ExecutionStatus.COMPLETE is allowed -> private
+ private void registerCallback(final CLEventListener callback, ExecutionStatus trigger) {
+ cl.clSetEventCallback(ID, trigger.STATUS, new CLEventCallback() {
+ public void eventStateChanged(long event, int status) {
+ callback.eventStateChanged(CLEvent.this, status);
+ }
+ });
+ }
+
public void release() {
int ret = cl.clReleaseEvent(ID);
checkForError(ret, "can not release event");
diff --git a/src/com/jogamp/opencl/CLEventListener.java b/src/com/jogamp/opencl/CLEventListener.java
new file mode 100644
index 00000000..76911008
--- /dev/null
+++ b/src/com/jogamp/opencl/CLEventListener.java
@@ -0,0 +1,15 @@
+/*
+ * Created on Thursday, September 02 2010 22:01
+ */
+package com.jogamp.opencl;
+
+/**
+ * A callback for a specific command execution status.
+ * @author Michael Bien
+ * @see CLEvent#registerCallback(com.jogamp.opencl.CLEventListener)
+ */
+public interface CLEventListener {
+
+ public void eventStateChanged(CLEvent event, int status);
+
+} \ No newline at end of file
diff --git a/src/com/jogamp/opencl/impl/CLEventCallback.java b/src/com/jogamp/opencl/impl/CLEventCallback.java
new file mode 100644
index 00000000..db4d5b35
--- /dev/null
+++ b/src/com/jogamp/opencl/impl/CLEventCallback.java
@@ -0,0 +1,15 @@
+/*
+ * Created on Tuesday, July 06 2010 00:46
+ */
+
+package com.jogamp.opencl.impl;
+
+/**
+ * A callback for a specific command execution status.
+ * @author Michael Bien
+ */
+public interface CLEventCallback {
+
+ public void eventStateChanged(long event, int status);
+
+}
diff --git a/src/com/jogamp/opencl/impl/CLImpl.java b/src/com/jogamp/opencl/impl/CLImpl.java
index abec3597..b9dd9835 100644
--- a/src/com/jogamp/opencl/impl/CLImpl.java
+++ b/src/com/jogamp/opencl/impl/CLImpl.java
@@ -123,6 +123,17 @@ public class CLImpl extends CLAbstractImpl {
/** Entry point to C language function: <code> int32_t clBuildProgram(cl_program, uint32_t, cl_device_id * , const char * , void * ); </code> */
private native int clBuildProgram0(long program, int deviceCount, Object deviceList, int deviceListOffset, String options, BuildProgramCallback cb, long address);
+
+ public int clSetEventCallback(long event, int trigger, CLEventCallback callback) {
+ final long address = addressTable._addressof_clSetEventCallback;
+ if (address == 0) {
+ throw new UnsupportedOperationException("Method not available");
+ }
+ return clSetEventCallback0(event, trigger, callback, address);
+ }
+
+ private native int clSetEventCallback0(long event, int type, CLEventCallback cb, long address);
+
/** Interface to C language function: <br> <code> void * {@native clEnqueueMapImage}(cl_command_queue command_queue, cl_mem image, uint32_t blocking_map, uint64_t map_flags, const size_t * , const size_t * , size_t * image_row_pitch, size_t * image_slice_pitch, uint32_t num_events_in_wait_list, cl_event * event_wait_list, cl_event * event, int32_t * errcode_ret); </code>
@param origin a direct {@link com.jogamp.common.nio.PointerBuffer}
@param range a direct {@link com.jogamp.common.nio.PointerBuffer}
diff --git a/test/com/jogamp/opencl/CLCommandQueueTest.java b/test/com/jogamp/opencl/CLCommandQueueTest.java
index 9c4cc7a8..cafdbc18 100644
--- a/test/com/jogamp/opencl/CLCommandQueueTest.java
+++ b/test/com/jogamp/opencl/CLCommandQueueTest.java
@@ -1,11 +1,13 @@
package com.jogamp.opencl;
+import java.util.concurrent.CountDownLatch;
import com.jogamp.opencl.util.MultiQueueBarrier;
import com.jogamp.opencl.CLCommandQueue.Mode;
import com.jogamp.opencl.CLMemory.Mem;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.EnumSet;
+import java.util.concurrent.TimeUnit;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -172,7 +174,6 @@ public class CLCommandQueueTest {
final int elements = roundUp(groupSize, ONE_MB / SIZEOF_INT * 5); // 5MB per buffer
- // 5MB per buffer
CLPlatform[] platforms = CLPlatform.listCLPlatforms();
CLPlatform theChosenOne = platforms[0];
for (CLPlatform platform : platforms) {
@@ -247,6 +248,43 @@ public class CLCommandQueueTest {
}
@Test
+ public void eventCallbackTest() throws InterruptedException {
+
+ out.println(" - - - event callback test - - - ");
+
+ CLPlatform platform = CLPlatform.getDefault();
+
+ if(!platform.isAtLeast(CL_1_1)) {
+ out.println("test dissabled, required CLVersion: "+CL_1_1+" available: "+platform.getVersion());
+ return;
+ }
+
+ CLContext context = CLContext.create();
+
+ final CLUserEvent customEvent = CLUserEvent.create(context);
+
+ final CountDownLatch countdown = new CountDownLatch(1);
+ customEvent.registerCallback(new CLEventListener() {
+
+ public void eventStateChanged(CLEvent event, int status) {
+ out.println("event received: "+event);
+ assertEquals(event, customEvent);
+ countdown.countDown();
+ }
+
+ });
+
+ customEvent.setStatus(ExecutionStatus.COMPLETE);
+ countdown.await(2, TimeUnit.SECONDS);
+ assertEquals(countdown.getCount(), 0);
+
+ customEvent.release();
+
+ context.release();
+
+ }
+
+ @Test
public void concurrencyTest() throws IOException, InterruptedException {
out.println(" - - - QueueBarrier test - - - ");