harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Regis <xu.re...@gmail.com>
Subject Re: [jira] Created: (HARMONY-6328) [classlib][nio] optimize SocketChannel.write(ByteBuffer[], int, int) by writev
Date Mon, 07 Sep 2009 08:33:26 GMT
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,

View raw message