harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Ellison <t.p.elli...@gmail.com>
Subject Re: [jira] Created: (HARMONY-6328) [classlib][nio] optimize SocketChannel.write(ByteBuffer[], int, int) by writev
Date Thu, 03 Sep 2009 12:08:09 GMT
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

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.

>> + if (!buffer.isDirect()) {
>> + src[i] = ByteBuffer.allocateDirect(buffer.remaining());
>> + int oldPosition = buffer.position();
>> + src[i].put(buffer);
>> some VMs will pin the java heap memory accessed in JNI
>> (GetByteArrayElements), so if you can get hold of the ByteBuffer#array()
>> you can pass a set of pointers to the backing arrays and maybe send the
>> data directly.
>> Looking forward to seeing the readv impl too ;-)
> Sure, it's on my TODO list :)



View raw message