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...

--
Best Regards,
Regis.

Reply via email to