On 07/Sep/2009 09:33, Regis wrote: > Tim Ellison wrote: >> On 03/Sep/2009 12:29, Regis wrote: >>> Tim Ellison wrote: >>>> A minor comment first :-) Please check return values for : >>>> >>>> + vect = (struct iovec*) hymem_allocate_memory(sizeof(struct iovec) * >>>> length); >>>> + >>>> + message = (*env)->GetPrimitiveArrayCritical(env, addrs, >>>> &isCopyMessage); >>>> + cts = (*env)->GetPrimitiveArrayCritical(env, counts, &isCopyCts); >>> Yes, will add it, thanks. >>> >>>> >>>> A further enhancement is to have two versions of primitives, one that >>>> deals with direct buffers and one that deals with java heap buffers, so >>>> that there is (potentially) no data copying required for the java-heap >>>> buffers version that you have got today: >>> One case stop me to do that is a buffer array contains direct and java >>> heap buffers both. In this case, either copying java heap buffres to >>> direct buffers or passing the whole array to native directly. >> >> Yes, good point. >> >>> If pass the array to native directly, it need to call isDirect and >>> AddressUtil.getDirectBufferAddress in native code, as I understand, call >>> java methods from native side is like reflection, even more expensive, >>> so I chose copying all java heap buffers to direct buffers, at least it >>> fast when most buffers are direct and size of java heap buffers are not >>> too big. >> >> No need to use call back into Java code to do this, there are already >> JNI functions you can use: >> >> jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz); >> void* GetDirectBufferAddress(JNIEnv* env, jobject buf); >> >> See the spec at >> http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html >> >> However, you cannot always get the backing array from a ByteBuffer, so >> you still have three cases to deal with: >> 1. the direct byte buffer (by address) >> 2. the heap byte buffer with backing array (may be pinned/copied) >> 3. the heap byte buffer without an array (must be copied) >> >> For case (3) likely it is best to copy into a direct byte buffer to >> ensure it does not get copied again, so you end up passing only types >> (1) and (2) into the native. >> >>> One possible solution I can think is adding a new native call >>> >>> writevDirect(JNIEnv *env, jobject thiz, jobject fd, jobject bufferArray, >>> jobject addrs, jobject counts, jint length) >>> >>> passing buffer array and native addresses of direct buffers together, if >>> element of addrs is 0, the corresponding buffer is not direct. Well, >>> this method is a little bit hard to understand, it has 7 parameters.... >> >> I agree. Maybe the best way is to pass them in as jobjects and let the >> native code sort out the direct / heap buffers -- using the address >> directly and getting access to the bytes respectively. >> > > I managed to implement in this way and submit a patch to JIRA. > > I tried to pass a object array, if it's direct buffer, fill the array > element with buffer directly (heap byte buffer without an array will be > copied to direct buffer first), otherwise, pass byte array. Because we > still need to know the offset of arrays, so I have to pass it to native > code. > > More test cases and documents are coming...
Wow, quick work! I'll take a look. Regards, Tim