From bc4e1521cc2ccc91a033998847dc35e1a8c8687b Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Thu, 2 Sep 2010 23:45:05 +0200 Subject: CLMemObjectDestructorCallback for HLB and LLB. --- resources/cl-common.cfg | 3 -- resources/cl-if.cfg | 9 ++++- resources/cl-impl.cfg | 3 ++ resources/clImplCustomCode.c | 26 +++++++++++-- src/com/jogamp/opencl/CLMemObjectListener.java | 19 ++++++++++ src/com/jogamp/opencl/CLMemory.java | 13 +++++++ src/com/jogamp/opencl/impl/CLImpl.java | 12 ++++++ .../opencl/impl/CLMemObjectDestructorCallback.java | 19 ++++++++++ test/com/jogamp/opencl/CLBufferTest.java | 44 +++++++++++++++++++++- 9 files changed, 139 insertions(+), 9 deletions(-) create mode 100644 src/com/jogamp/opencl/CLMemObjectListener.java create mode 100644 src/com/jogamp/opencl/impl/CLMemObjectDestructorCallback.java diff --git a/resources/cl-common.cfg b/resources/cl-common.cfg index f9c32c84..fab403b5 100644 --- a/resources/cl-common.cfg +++ b/resources/cl-common.cfg @@ -106,6 +106,3 @@ TagNativeBinding true # platform dependent extensions Ignore .*APPLE.* - -# TODO implement custom callbacks if this makes sense -Ignore clSetMemObjectDestructorCallback diff --git a/resources/cl-if.cfg b/resources/cl-if.cfg index b8deb126..f65a417b 100644 --- a/resources/cl-if.cfg +++ b/resources/cl-if.cfg @@ -8,6 +8,7 @@ Import java.nio.LongBuffer Import com.jogamp.opencl.impl.CLImageFormatImpl import com.jogamp.opencl.impl.BuildProgramCallback import com.jogamp.opencl.impl.CLEventCallback +import com.jogamp.opencl.impl.CLMemObjectDestructorCallback ClassJavadoc CL /** ClassJavadoc CL * Java bindings to OpenCL, the Open Computing Language. @@ -36,7 +37,13 @@ CustomJavaCode CL public int clBuildProgram(long program, int deviceCount, Poin Ignore clSetEventCallback CustomJavaCode CL -CustomJavaCode CL public int clSetEventCallback(long event, int type, CLEventCallback listener); +CustomJavaCode CL /** Interface to C language function:
int32_t {@native clSetEventCallback}(cl_event event, cl_int command_exec_callback_type, void (CL_CALLBACK *pfn_event_notify) (cl_event event, cl_int event_command_exec_status, void *user_data), void *user_data); */ +CustomJavaCode CL public int clSetEventCallback(long event, int type, CLEventCallback cb); + +Ignore clSetMemObjectDestructorCallback +CustomJavaCode CL +CustomJavaCode CL /** Interface to C language function:
int32_t {@native clSetMemObjectDestructorCallback}(cl_mem memobj, void (CL_CALLBACK *pfn_notify) (cl_mem memobj, void *user_data), void *user_data); */ +CustomJavaCode CL public int clSetMemObjectDestructorCallback(long memObjID, CLMemObjectDestructorCallback cb); Ignore clEnqueueNativeKernel #TODO.. diff --git a/resources/cl-impl.cfg b/resources/cl-impl.cfg index f3367eac..856c85cd 100644 --- a/resources/cl-impl.cfg +++ b/resources/cl-impl.cfg @@ -75,6 +75,9 @@ ForceProcAddressGen clReleaseContext Ignore clSetEventCallback ForceProcAddressGen clSetEventCallback +Ignore clSetMemObjectDestructorCallback +ForceProcAddressGen clSetMemObjectDestructorCallback + #take buffer capacity from input param 5 ReturnValueCapacity clEnqueueMapBuffer {5} diff --git a/resources/clImplCustomCode.c b/resources/clImplCustomCode.c index bf4cf1c9..f0ff3651 100644 --- a/resources/clImplCustomCode.c +++ b/resources/clImplCustomCode.c @@ -29,7 +29,7 @@ JNI_OnLoad(JavaVM * _jvm, void *reserved) { 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"); + jclass memObjCBClassID = (*env)->FindClass(env, "com/jogamp/opencl/impl/CLMemObjectDestructorCallback"); // throws even more reflection Exceptions // IDs are unique and do not change @@ -43,7 +43,7 @@ JNI_OnLoad(JavaVM * _jvm, void *reserved) { eventCB_mid = (*env)->GetMethodID(env, eventCBClassID, "eventStateChanged", "(JI)V"); } if (memObjCBClassID != NULL) { - memObjCB_mid = (*env)->GetMethodID(env, memObjCBClassID, "memoryDeallocated", "(Lcom/jogamp/opencl/CLMemory;)V"); + memObjCB_mid = (*env)->GetMethodID(env, memObjCBClassID, "memoryDeallocated", "(J)V"); } return JNI_VERSION_1_2; @@ -98,7 +98,7 @@ CL_CALLBACK void eventCallback(cl_event event, cl_int status, void * object) { (*jvm)->DetachCurrentThread(jvm); } -/* + CL_CALLBACK void memObjDestructorCallback(cl_mem mem, void * object) { JNIEnv *env; @@ -106,9 +106,12 @@ CL_CALLBACK void memObjDestructorCallback(cl_mem mem, void * object) { (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); + (*env)->CallVoidMethod(env, obj, memObjCB_mid, mem); + (*env)->DeleteGlobalRef(env, obj); + (*jvm)->DetachCurrentThread(jvm); } -*/ + /* Java->C glue code: * Java package: com.jogamp.opencl.impl.CLImpl @@ -391,3 +394,18 @@ Java_com_jogamp_opencl_impl_CLImpl_clSetEventCallback0(JNIEnv *env, jobject _unu return _res; } + +JNIEXPORT jint JNICALL +Java_com_jogamp_opencl_impl_CLImpl_clSetMemObjectDestructorCallback0(JNIEnv *env, jobject _unused, + jlong mem, jobject listener, jlong procAddress) { + + cl_mem _mem = mem; + cl_int _res; + typedef int32_t (*function)(cl_mem, void (*pfn_event_notify) (cl_mem, void *), void *); + function clSetMemObjectDestructorCallback = (function)(intptr_t) procAddress; + + jobject cb = (*env)->NewGlobalRef(env, listener); + _res = (*clSetMemObjectDestructorCallback)(_mem, &memObjDestructorCallback, cb); + + return _res; +} diff --git a/src/com/jogamp/opencl/CLMemObjectListener.java b/src/com/jogamp/opencl/CLMemObjectListener.java new file mode 100644 index 00000000..4ee32b9f --- /dev/null +++ b/src/com/jogamp/opencl/CLMemObjectListener.java @@ -0,0 +1,19 @@ +/* + * Created on Tuesday, July 06 2010 00:46 + */ + +package com.jogamp.opencl; + +/** + * A callback which is invoked by the OpenCL implementation when the memory + * object is deleted and its resources freed. + * @author Michael Bien + */ +public interface CLMemObjectListener { + + /** + * + */ + public void memoryDeallocated(CLMemory mem); + +} diff --git a/src/com/jogamp/opencl/CLMemory.java b/src/com/jogamp/opencl/CLMemory.java index d66db3c8..416b8019 100644 --- a/src/com/jogamp/opencl/CLMemory.java +++ b/src/com/jogamp/opencl/CLMemory.java @@ -3,6 +3,7 @@ package com.jogamp.opencl; import com.jogamp.opencl.gl.CLGLI; import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.opencl.impl.CLMemObjectDestructorCallback; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.DoubleBuffer; @@ -72,6 +73,18 @@ public abstract class CLMemory extends CLObject implements CL return context.cl; } + /** + * Registers a callback which will be called by the OpenCL implementation + * when the memory object is released. + */ + public void registerDestructorCallback(final CLMemObjectListener listener) { + cl.clSetMemObjectDestructorCallback(ID, new CLMemObjectDestructorCallback() { + public void memoryDeallocated(long memObjID) { + listener.memoryDeallocated(CLMemory.this); + } + }); + } + /** * Returns a new instance of CLMemory pointing to the same CLResource but using a different Buffer. */ diff --git a/src/com/jogamp/opencl/impl/CLImpl.java b/src/com/jogamp/opencl/impl/CLImpl.java index b9dd9835..98db94ea 100644 --- a/src/com/jogamp/opencl/impl/CLImpl.java +++ b/src/com/jogamp/opencl/impl/CLImpl.java @@ -134,6 +134,18 @@ public class CLImpl extends CLAbstractImpl { private native int clSetEventCallback0(long event, int type, CLEventCallback cb, long address); + + public int clSetMemObjectDestructorCallback(long memObjID, CLMemObjectDestructorCallback cb) { + final long address = addressTable._addressof_clSetMemObjectDestructorCallback; + if (address == 0) { + throw new UnsupportedOperationException("Method not available"); + } + return clSetMemObjectDestructorCallback0(memObjID, cb, address); + } + + private native int clSetMemObjectDestructorCallback0(long memObjID, CLMemObjectDestructorCallback cb, long address); + + /** Interface to C language function:
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); @param origin a direct {@link com.jogamp.common.nio.PointerBuffer} @param range a direct {@link com.jogamp.common.nio.PointerBuffer} diff --git a/src/com/jogamp/opencl/impl/CLMemObjectDestructorCallback.java b/src/com/jogamp/opencl/impl/CLMemObjectDestructorCallback.java new file mode 100644 index 00000000..df6f18f6 --- /dev/null +++ b/src/com/jogamp/opencl/impl/CLMemObjectDestructorCallback.java @@ -0,0 +1,19 @@ +/* + * Created on Thursday, September 02 2010 23:09 + */ + +package com.jogamp.opencl.impl; + +/** + * A callback which is invoked by the OpenCL implementation when the memory + * object is deleted and its resources freed. + * @author Michael Bien + */ +public interface CLMemObjectDestructorCallback { + + /** + * + */ + public void memoryDeallocated(long memObjID); + +} diff --git a/test/com/jogamp/opencl/CLBufferTest.java b/test/com/jogamp/opencl/CLBufferTest.java index f2d2d609..92f94831 100644 --- a/test/com/jogamp/opencl/CLBufferTest.java +++ b/test/com/jogamp/opencl/CLBufferTest.java @@ -5,6 +5,8 @@ import com.jogamp.opencl.CLMemory.Map; import com.jogamp.common.nio.Buffers; import java.nio.ByteBuffer; import java.nio.FloatBuffer; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import org.junit.Test; import static org.junit.Assert.*; @@ -150,6 +152,8 @@ public class CLBufferTest { @Test public void subBufferTest() { + out.println(" - - - subBufferTest - - - "); + CLPlatform[] platforms = CLPlatform.listCLPlatforms(); CLPlatform theChosenOne = null; for (CLPlatform platform : platforms) { @@ -215,5 +219,43 @@ public class CLBufferTest { } } - + + @Test + public void destructorCallbackTest() throws InterruptedException { + + out.println(" - - - destructorCallbackTest - - - "); + + CLPlatform platform = CLPlatform.getDefault(); + if(!platform.isAtLeast(CLVersion.CL_1_1)) { + out.println("aborting destructorCallbackTest"); + return; + } + + CLContext context = CLContext.create(platform); + + try{ + + final CLBuffer buffer = context.createBuffer(32); + final CountDownLatch countdown = new CountDownLatch(1); + + buffer.registerDestructorCallback(new CLMemObjectListener() { + public void memoryDeallocated(CLMemory mem) { + out.println("buffer released"); + assertEquals(mem, buffer); + countdown.countDown(); + } + }); + buffer.release(); + + countdown.await(2, TimeUnit.SECONDS); + assertEquals(countdown.getCount(), 0); + + }finally{ + context.release(); + } + + + } + + } -- cgit v1.2.3