summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2010-05-04 02:22:19 +0200
committerMichael Bien <[email protected]>2010-05-04 02:22:19 +0200
commit9125a275449cb533798357914945de1f742a91f9 (patch)
treec25d5357ac99ec24bee4e7f2c95775362877db0b
parentea95ca1b96300fc9b2ec937759663eb0ed1406bf (diff)
finished main functionality of ErrorHandler impl.
- using event listener add/remove pattern instead add on context creation - context -> error handler object global reference mapping(TM) using LongLongMap in CLImpl - global ref is deleted on context release
-rw-r--r--resources/cl-if.cfg4
-rw-r--r--resources/cl-impl.cfg1
-rw-r--r--resources/clImplCustomCode.c66
-rw-r--r--resources/clImplCustomCode.java49
-rw-r--r--src/com/jogamp/opencl/CLContext.java92
-rw-r--r--src/com/jogamp/opencl/CLErrorHandler.java5
-rw-r--r--src/com/jogamp/opencl/gl/CLGLContext.java14
7 files changed, 187 insertions, 44 deletions
diff --git a/resources/cl-if.cfg b/resources/cl-if.cfg
index d0413d97..6f19e64f 100644
--- a/resources/cl-if.cfg
+++ b/resources/cl-if.cfg
@@ -21,12 +21,12 @@ Ignore CL_GL_.*|cl.*GL.*
Ignore clCreateContext
CustomJavaCode CL
CustomJavaCode CL /** Interface to C language function: <br> <code> cl_context {@native clCreateContext}(intptr_t * , uint32_t, cl_device_id * , void (*pfn_notify)(const char *, const void *, size_t, void *), void *, int32_t * ); </code> */
-CustomJavaCode CL public long clCreateContext(PointerBuffer properties, PointerBuffer devices, CreateContextCallback pfn_notify, IntBuffer errcode_ret);
+CustomJavaCode CL public long clCreateContext(PointerBuffer properties, PointerBuffer devices, CLErrorHandler pfn_notify, IntBuffer errcode_ret);
Ignore clCreateContextFromType
CustomJavaCode CL
CustomJavaCode CL /** Interface to C language function: <br> <code> cl_context {@native clCreateContextFromType}(cl_context_properties *properties, cl_device_type device_type, void (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data), void *user_data, cl_int *errcode_ret) ; </code> */
-CustomJavaCode CL public long clCreateContextFromType(PointerBuffer properties, long device_type, CreateContextCallback pfn_notify, IntBuffer errcode_ret);
+CustomJavaCode CL public long clCreateContextFromType(PointerBuffer properties, long device_type, CLErrorHandler pfn_notify, IntBuffer errcode_ret);
Ignore clBuildProgram
CustomJavaCode CL
diff --git a/resources/cl-impl.cfg b/resources/cl-impl.cfg
index 34753eb7..fc04d2b0 100644
--- a/resources/cl-impl.cfg
+++ b/resources/cl-impl.cfg
@@ -46,6 +46,7 @@ Ignore clCreateContext
Ignore clCreateContextFromType
Ignore clBuildProgram
Ignore clEnqueueNativeKernel
+Ignore clReleaseContext
#take buffer capacity from input param 5
ReturnValueCapacity clEnqueueMapBuffer {5}
diff --git a/resources/clImplCustomCode.c b/resources/clImplCustomCode.c
index b491eb7f..1314e7b8 100644
--- a/resources/clImplCustomCode.c
+++ b/resources/clImplCustomCode.c
@@ -25,7 +25,7 @@ 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/CreateContextCallback");
+ jclass errorHandlerClassID = (*env)->FindClass(env, "com/jogamp/opencl/CLErrorHandler");
// throws even more reflection Exceptions
// IDs are unique and do not change
@@ -35,7 +35,7 @@ JNI_OnLoad(JavaVM * _jvm, void *reserved) {
if (errorHandlerClassID != NULL) {
cccb_mid = (*env)->GetMethodID(env, errorHandlerClassID, "onError", "(Ljava/lang/String;Ljava/nio/ByteBuffer;J)V");
}
-
+
return JNI_VERSION_1_2;
}
@@ -47,8 +47,10 @@ void buildProgramCallback(cl_program id, void * object) {
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
- (*env)->CallVoidMethod(env, obj, bcb_mid, (jlong)id);
- (*env)->DeleteGlobalRef(env, obj);
+ (*env)->CallVoidMethod(env, obj, bcb_mid, (jlong)id);
+ (*env)->DeleteGlobalRef(env, obj);
+
+ (*jvm)->DetachCurrentThread(jvm);
}
@@ -59,11 +61,12 @@ void createContextCallback(const char * errinfo, const void * private_info, size
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
- jstring errorString = (*env)->NewStringUTF(env, errinfo);
+ jstring errorString = (*env)->NewStringUTF(env, errinfo);
- //TODO private_info
- (*env)->CallVoidMethod(env, obj, cccb_mid, errorString, NULL, 0);
- //(*env)->DeleteGlobalRef(env, obj);
+ //TODO private_info
+ (*env)->CallVoidMethod(env, obj, cccb_mid, errorString, NULL, 0);
+
+ (*jvm)->DetachCurrentThread(jvm);
}
@@ -80,7 +83,7 @@ void createContextCallback(const char * errinfo, const void * private_info, size
*/
JNIEXPORT jlong JNICALL
Java_com_jogamp_opencl_impl_CLImpl_clCreateContextFromType0(JNIEnv *env, jobject _unused,
- jobject props, jint props_byte_offset, jobject device_type, jobject cb, jobject errcode, jint errcode_byte_offset) {
+ jobject props, jint props_byte_offset, jobject device_type, jobject cb, jobject global, jobject errcode, jint errcode_byte_offset) {
cl_context_properties* _props_ptr = NULL;
int32_t * _errcode_ptr = NULL;
@@ -103,9 +106,16 @@ Java_com_jogamp_opencl_impl_CLImpl_clCreateContextFromType0(JNIEnv *env, jobject
_ctx = clCreateContextFromType(_props_ptr, (uint64_t) device_type, pfn_notify, globalCB, (int32_t *) _errcode_ptr);
- // if something went wrong
- if (_ctx == NULL && globalCB != NULL) {
- (*env)->DeleteGlobalRef(env, globalCB);
+ if(globalCB != NULL) {
+ jlong *g = (*env)->GetPrimitiveArrayCritical(env, global, NULL);
+ // if something went wrong
+ if(_ctx == NULL) {
+ g[0] = 0;
+ (*env)->DeleteGlobalRef(env, globalCB);
+ }else{
+ g[0] = (jlong)globalCB;
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, global, g, 0);
}
return (jlong) (intptr_t)_ctx;
@@ -123,7 +133,7 @@ Java_com_jogamp_opencl_impl_CLImpl_clCreateContextFromType0(JNIEnv *env, jobject
*/
JNIEXPORT jlong JNICALL
Java_com_jogamp_opencl_impl_CLImpl_clCreateContext0(JNIEnv *env, jobject _unused,
- jobject props, jint props_byte_offset, jint numDevices, jobject deviceList, jint device_type_offset, jobject cb, jobject errcode, jint errcode_byte_offset) {
+ jobject props, jint props_byte_offset, jint numDevices, jobject deviceList, jint device_type_offset, jobject cb, jobject global, jobject errcode, jint errcode_byte_offset) {
cl_context_properties* _props_ptr = NULL;
int32_t * _errcode_ptr = NULL;
@@ -149,14 +159,38 @@ Java_com_jogamp_opencl_impl_CLImpl_clCreateContext0(JNIEnv *env, jobject _unused
_ctx = clCreateContext(_props_ptr, numDevices, (cl_device_id *)_deviceListPtr, pfn_notify, globalCB, (int32_t *) _errcode_ptr);
- // if something went wrong
- if (_ctx == NULL && globalCB != NULL) {
- (*env)->DeleteGlobalRef(env, globalCB);
+ if(globalCB != NULL) {
+ jlong *g = (*env)->GetPrimitiveArrayCritical(env, global, NULL);
+ // if something went wrong
+ if(_ctx == NULL) {
+ g[0] = 0;
+ (*env)->DeleteGlobalRef(env, globalCB);
+ }else{
+ g[0] = (jlong)globalCB;
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, global, g, 0);
}
return (jlong) (intptr_t)_ctx;
}
+/* Java->C glue code:
+ * Java package: com.jogamp.opencl.impl.CLImpl
+ * Java method: int clReleaseContextImpl(long context)
+ * C function: int32_t clReleaseContextImpl(cl_context context);
+ */
+JNIEXPORT jint JNICALL
+Java_com_jogamp_opencl_impl_CLImpl_clReleaseContextImpl(JNIEnv *env, jobject _unused, jlong context, jlong global) {
+ int32_t _res;
+ _res = clReleaseContext((cl_context) (intptr_t) context);
+ // TODO deal with retains
+ if (global != 0) {
+ (*env)->DeleteGlobalRef(env, (jobject) global);
+ }
+ return _res;
+}
+
+
/**
* Entry point to C language function:
* extern CL_API_ENTRY cl_int CL_API_CALL
diff --git a/resources/clImplCustomCode.java b/resources/clImplCustomCode.java
index f3daddf0..d2993f96 100644
--- a/resources/clImplCustomCode.java
+++ b/resources/clImplCustomCode.java
@@ -1,33 +1,66 @@
private final CLProcAddressTable addressTable;
+ //maps the context id to its error handler's global object pointer
+ private final com.jogamp.common.util.LongLongHashMap contextCallbackMap;
+
public CLImpl(CLProcAddressTable addressTable) {
this.addressTable = addressTable;
+ this.contextCallbackMap = new com.jogamp.common.util.LongLongHashMap();
+ this.contextCallbackMap.setKeyNotFoundValue(0);
}
- public long clCreateContext(PointerBuffer properties, PointerBuffer devices, CreateContextCallback pfn_notify, IntBuffer errcode_ret) {
+ public long clCreateContext(PointerBuffer properties, PointerBuffer devices, CLErrorHandler pfn_notify, IntBuffer errcode_ret) {
if(properties!=null && !properties.isDirect())
throw new RuntimeException("Argument \"properties\" was not a direct buffer");
- return this.clCreateContext0(
+ long[] global = new long[1];
+ long ctx = this.clCreateContext0(
properties!=null?properties.getBuffer():null, Buffers.getDirectBufferByteOffset(properties),
devices!=null?devices.remaining():0, devices!=null?devices.getBuffer():null, Buffers.getDirectBufferByteOffset(devices),
- null, errcode_ret, Buffers.getDirectBufferByteOffset(errcode_ret) );
+ pfn_notify, global, errcode_ret, Buffers.getDirectBufferByteOffset(errcode_ret) );
+
+ if(pfn_notify != null && global[0] != 0) {
+ synchronized(contextCallbackMap) {
+ contextCallbackMap.put(ctx, global[0]);
+ }
+ }
+ return ctx;
}
- private native long clCreateContext0(Object cl_context_properties, int props_offset, int numDevices, Object devices, int devices_offset, CreateContextCallback pfn_notify, Object errcode_ret, int err_offset);
+ private native long clCreateContext0(Object cl_context_properties, int props_offset, int numDevices, Object devices, int devices_offset, CLErrorHandler pfn_notify, long[] global, Object errcode_ret, int err_offset);
- public long clCreateContextFromType(PointerBuffer properties, long device_type, CreateContextCallback pfn_notify, IntBuffer errcode_ret) {
+ public long clCreateContextFromType(PointerBuffer properties, long device_type, CLErrorHandler pfn_notify, IntBuffer errcode_ret) {
if(properties!=null && !properties.isDirect())
throw new RuntimeException("Argument \"properties\" was not a direct buffer");
- return this.clCreateContextFromType0(
+ long[] global = new long[1];
+ long ctx = this.clCreateContextFromType0(
properties!=null?properties.getBuffer():null, Buffers.getDirectBufferByteOffset(properties),
- device_type, pfn_notify, errcode_ret, Buffers.getDirectBufferByteOffset(errcode_ret) );
+ device_type, pfn_notify, global, errcode_ret, Buffers.getDirectBufferByteOffset(errcode_ret) );
+
+ if(pfn_notify != null && global[0] != 0) {
+ synchronized(contextCallbackMap) {
+ contextCallbackMap.put(ctx, global[0]);
+ }
+ }
+ return ctx;
}
- private native long clCreateContextFromType0(Object properties, int props_offset, long device_type, CreateContextCallback pfn_notify, Object errcode_ret, int err_offset);
+ private native long clCreateContextFromType0(Object properties, int props_offset, long device_type, CLErrorHandler pfn_notify, long[] global, Object errcode_ret, int err_offset);
+
+
+ public int clReleaseContext(long context) {
+ long global = 0;
+ synchronized(contextCallbackMap) {
+ global = contextCallbackMap.remove(context);
+ }
+ return clReleaseContextImpl(context, global);
+ }
+
+ /** Interface to C language function: <br> <code> int32_t {@native clReleaseContext}(cl_context context); </code> */
+ public native int clReleaseContextImpl(long context, long global);
/** Interface to C language function: <br> <code> int32_t clBuildProgram(cl_program, uint32_t, cl_device_id * , const char * , void * ); </code> */
diff --git a/src/com/jogamp/opencl/CLContext.java b/src/com/jogamp/opencl/CLContext.java
index e9e0a8a8..c904a37c 100644
--- a/src/com/jogamp/opencl/CLContext.java
+++ b/src/com/jogamp/opencl/CLContext.java
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static java.lang.System.*;
import static com.jogamp.opencl.CLException.*;
import static com.jogamp.common.nio.Buffers.*;
import static com.jogamp.common.os.Platform.*;
@@ -45,15 +46,26 @@ public class CLContext extends CLObject implements CLResource {
protected final Map<CLDevice, List<CLCommandQueue>> queuesMap;
protected final CLPlatform platform;
+
+ private final ErrorDispatcher errorHandler;
-
- protected CLContext(CLPlatform platform, long contextID) {
+ protected CLContext(CLPlatform platform, long contextID, ErrorDispatcher dispatcher) {
super(CLPlatform.getLowLevelCLInterface(), contextID);
this.platform = platform;
this.programs = new ArrayList<CLProgram>();
this.samplers = new ArrayList<CLSampler>();
this.memoryObjects = new ArrayList<CLMemory<? extends Buffer>>();
this.queuesMap = new HashMap<CLDevice, List<CLCommandQueue>>();
+ this.errorHandler = dispatcher;
+
+ /*
+ addCLErrorHandler(new CLErrorHandler() {
+ public void onError(String errinfo, ByteBuffer private_info, long cb) {
+ java.util.logging.Logger.getLogger(getClass().getName()).warning(errinfo);
+ }
+ });
+ */
+
}
private void initDevices() {
@@ -88,7 +100,7 @@ public class CLContext extends CLObject implements CLResource {
* Creates a context on the specified device types.
* The platform to be used is implementation dependent.
*/
- public static CLContext create(CLDevice.Type... deviceTypes) {
+ public static CLContext create(Type... deviceTypes) {
return create(null, deviceTypes);
}
@@ -104,14 +116,14 @@ public class CLContext extends CLObject implements CLResource {
* Creates a context on the specified platform on all available devices (CL_DEVICE_TYPE_ALL).
*/
public static CLContext create(CLPlatform platform) {
- return create(platform, CLDevice.Type.ALL);
+ return create(platform, Type.ALL);
}
/**
* Creates a context on the specified platform and with the specified
* device types.
*/
- public static CLContext create(CLPlatform platform, CLDevice.Type... deviceTypes) {
+ public static CLContext create(CLPlatform platform, Type... deviceTypes) {
if(platform == null) {
platform = CLPlatform.getDefault();
@@ -120,7 +132,8 @@ public class CLContext extends CLObject implements CLResource {
long type = toDeviceBitmap(deviceTypes);
PointerBuffer properties = setupContextProperties(platform);
- return new CLContext(platform, createContextFromType(properties, type));
+ ErrorDispatcher dispatcher = new ErrorDispatcher();
+ return new CLContext(platform, createContextFromType(dispatcher, properties, type), dispatcher);
}
/**
@@ -134,7 +147,8 @@ public class CLContext extends CLObject implements CLResource {
}
PointerBuffer properties = setupContextProperties(platform);
- CLContext context = new CLContext(platform, createContext(properties, devices));
+ ErrorDispatcher dispatcher = new ErrorDispatcher();
+ CLContext context = new CLContext(platform, createContext(dispatcher, properties, devices), dispatcher);
if(devices != null) {
for (int i = 0; i < devices.length; i++) {
devices[i].setContext(context);
@@ -143,17 +157,17 @@ public class CLContext extends CLObject implements CLResource {
return context;
}
- protected static long createContextFromType(PointerBuffer properties, long deviceType) {
+ protected static long createContextFromType(CLErrorHandler handler, PointerBuffer properties, long deviceType) {
IntBuffer status = IntBuffer.allocate(1);
- long context = CLPlatform.getLowLevelCLInterface().clCreateContextFromType(properties, deviceType, null, status);
+ long context = CLPlatform.getLowLevelCLInterface().clCreateContextFromType(properties, deviceType, handler, status);
checkForError(status.get(), "can not create CL context");
return context;
}
- protected static long createContext(PointerBuffer properties, CLDevice... devices) {
+ protected static long createContext(CLErrorHandler handler, PointerBuffer properties, CLDevice... devices) {
IntBuffer status = newDirectIntBuffer(1);
PointerBuffer pb = null;
@@ -167,7 +181,7 @@ public class CLContext extends CLObject implements CLResource {
pb.put(i, device.ID);
}
}
- long context = CLPlatform.getLowLevelCLInterface().clCreateContext(properties, pb, null, status);
+ long context = CLPlatform.getLowLevelCLInterface().clCreateContext(properties, pb, handler, status);
checkForError(status.get(), "can not create CL context");
@@ -353,6 +367,14 @@ public class CLContext extends CLObject implements CLResource {
samplers.remove(sampler);
}
+ public void addCLErrorHandler(CLErrorHandler handler) {
+ errorHandler.addHandler(handler);
+ }
+
+ public void removeCLErrorHandler(CLErrorHandler handler) {
+ errorHandler.removeHandler(handler);
+ }
+
/**
* Releases the context and all resources.
*/
@@ -513,4 +535,52 @@ public class CLContext extends CLObject implements CLResource {
return hash;
}
+ protected static ErrorDispatcher createErrorHandler() {
+ return new ErrorDispatcher();
+ }
+
+ protected static class ErrorDispatcher implements CLErrorHandler {
+
+ private volatile CLErrorHandler[] clientHandlers = new CLErrorHandler[0];
+
+ public void onError(String errinfo, ByteBuffer private_info, long cb) {
+ CLErrorHandler[] handlers = this.clientHandlers;
+ for (int i = 0; i < handlers.length; i++) {
+ handlers[i].onError(errinfo, private_info, cb);
+ }
+ }
+
+ private void addHandler(CLErrorHandler handler) {
+
+ if(handler == null) {
+ throw new IllegalArgumentException("handler was null.");
+ }
+
+ CLErrorHandler[] handlers = new CLErrorHandler[clientHandlers.length+1];
+ arraycopy(clientHandlers, 0, handlers, 0, clientHandlers.length);
+ handlers[handlers.length-1] = handler;
+ clientHandlers = handlers;
+ }
+
+ private void removeHandler(CLErrorHandler handler) {
+
+ if(handler == null) {
+ throw new IllegalArgumentException("handler was null.");
+ }
+
+ for (int i = 0; i < clientHandlers.length; i++) {
+ if(handler.equals(clientHandlers[i])) {
+ CLErrorHandler[] handlers = new CLErrorHandler[clientHandlers.length-1];
+ arraycopy(clientHandlers, 0, handlers, 0, i);
+ arraycopy(clientHandlers, i, handlers, 0, handlers.length-i);
+ clientHandlers = handlers;
+ return;
+ }
+ }
+ }
+
+
+ }
+
+
}
diff --git a/src/com/jogamp/opencl/CLErrorHandler.java b/src/com/jogamp/opencl/CLErrorHandler.java
index 74d49363..6a1cfb89 100644
--- a/src/com/jogamp/opencl/CLErrorHandler.java
+++ b/src/com/jogamp/opencl/CLErrorHandler.java
@@ -3,8 +3,11 @@ package com.jogamp.opencl;
import java.nio.ByteBuffer;
/**
- *
+ * Experimental: the api may change in future, feedback appreciated.<br/>
+ * Note: the thread which calls {@link #onError onError} is unspecified. The Application must ensure propper synchronization.
* @author Michael Bien
+ * @see CLContext#addCLErrorHandler(com.jogamp.opencl.CLErrorHandler)
+ * @see CLContext#removeCLErrorHandler(com.jogamp.opencl.CLErrorHandler)
*/
public interface CLErrorHandler {
diff --git a/src/com/jogamp/opencl/gl/CLGLContext.java b/src/com/jogamp/opencl/gl/CLGLContext.java
index 7b574664..dde05e75 100644
--- a/src/com/jogamp/opencl/gl/CLGLContext.java
+++ b/src/com/jogamp/opencl/gl/CLGLContext.java
@@ -23,8 +23,8 @@ public final class CLGLContext extends CLContext {
final long glID;
private final GLContext glContext;
- private CLGLContext(CLPlatform platform, GLContext glContext, long clContextID, long glContextID) {
- super(platform, clContextID);
+ private CLGLContext(CLPlatform platform, GLContext glContext, long clContextID, long glContextID, ErrorDispatcher dispatcher) {
+ super(platform, clContextID, dispatcher);
this.glID = glContextID;
this.glContext = glContext;
}
@@ -81,9 +81,10 @@ public final class CLGLContext extends CLContext {
long[] glID = new long[1];
PointerBuffer properties = setupContextProperties(platform, glContext, glID);
- long clID = createContextFromType(properties, toDeviceBitmap(deviceTypes));
+ ErrorDispatcher dispatcher = createErrorHandler();
+ long clID = createContextFromType(dispatcher, properties, toDeviceBitmap(deviceTypes));
- return new CLGLContext(platform, glContext, clID, glID[0]);
+ return new CLGLContext(platform, glContext, clID, glID[0], dispatcher);
}
@@ -101,9 +102,10 @@ public final class CLGLContext extends CLContext {
long[] glID = new long[1];
PointerBuffer properties = setupContextProperties(platform, glContext, glID);
- long clID = createContext(properties, devices);
+ ErrorDispatcher dispatcher = createErrorHandler();
+ long clID = createContext(dispatcher, properties, devices);
- CLGLContext context = new CLGLContext(platform, glContext, clID, glID[0]);
+ CLGLContext context = new CLGLContext(platform, glContext, clID, glID[0], dispatcher);
if(devices != null) {
for (int i = 0; i < devices.length; i++) {
context.overrideContext(devices[i]);