#parse("main/Header.vm") package com.nativelibs4java.opencl; import org.bridj.*; import static org.bridj.Pointer.*; abstract class CLAbstractEntity { private long entityPeer; private final boolean nullable; protected CLAbstractEntity(long entityPeer) { this(entityPeer, false); } protected CLAbstractEntity(long entityPeer, boolean nullable) { this.nullable = nullable; this.entityPeer = entityPeer; checkNullity(entityPeer); } private void checkNullity(long entityPeer) { if (!nullable && entityPeer == 0) { throw new IllegalArgumentException("Null OpenCL " + getClass().getSimpleName() + " !"); } } protected void setEntity(long entityPeer) { checkNullity(entityPeer); this.entityPeer = entityPeer; } static <T> Pointer<T> copyNonNullEntities(CLAbstractEntity[] entities, int[] countOut, ReusablePointer tmp) { if (entities == null) { countOut[0] = 0; return null; } int n = entities.length; Pointer<T> out = null; int count = 0; for (int i = 0; i < n; i++) { CLAbstractEntity entity = entities[i]; if (entity != null && entity != CLEvent.FIRE_AND_FORGET) { long pointer = entity.getEntity(); if (pointer != 0) { if (out == null) out = tmp.allocatedBytes(Pointer.SIZE * (n - i)); out.setSizeTAtOffset(Pointer.SIZE * count, pointer); count++; } } } countOut[0] = count; return out; } /** * Manual release of the OpenCL resources represented by this object.<br> * Note that resources are automatically released by the garbage collector, so in general there's no need to call this method.<br> * In an environment with fast allocation/deallocation of large objects, it might be safer to call release() manually, though.<br> * Note that release() does not necessarily free the object immediately : OpenCL maintains a reference count for all its objects, and an object released on the Java side might still be pointed to by running kernels or queued operations. */ public synchronized void release() { if (entityPeer == 0) { if (!nullable) throw new RuntimeException("This " + getClass().getSimpleName() + " has already been released ! Besides, keep in mind that manual release is not necessary, as it will automatically be done by the garbage collector."); else return; } doRelease(); } public static <E extends TypedPointer, A extends CLAbstractEntity> Pointer<E> getEntities(A[] objects, Pointer<E> out) { for (int i = 0, len = objects.length; i < len; i++) out.setSizeTAtOffset(i * Pointer.SIZE, objects[i].getEntity()); return out; } private void checkNullity() { if (entityPeer == 0 && !nullable) throw new RuntimeException("This " + getClass().getSimpleName() + " has been manually released and can't be used anymore !"); } synchronized long getEntity() { checkNullity(); return entityPeer; } synchronized void doRelease() { if (entityPeer != 0) { clear(); entityPeer = 0; } } @Override protected void finalize() throws Throwable { doRelease(); } protected abstract void clear(); /** * Underyling implementation pointer-based hashCode computation */ @Override public int hashCode() { return entityPeer == 0 ? 0 : Long.valueOf(entityPeer).hashCode(); } /** * Underyling implementation pointer-based equality test */ @Override public boolean equals(Object obj) { if (!getClass().isInstance(obj)) return false; CLAbstractEntity e = (CLAbstractEntity)obj; return getEntity() == e.getEntity(); } }