Use optimized write and read calls if memoryAddress is present. Part of [#2239]
This commit is contained in:
parent
b49490e239
commit
55d0f36a61
@ -461,14 +461,8 @@ JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_epollCtlDel(JNIEnv * e
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_write(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit) {
|
||||
// TODO: We could also maybe pass the address in directly and so eliminate this call
|
||||
// not sure if this would buy us much. So some testing is needed.
|
||||
void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
|
||||
if (buffer == NULL) {
|
||||
throwRuntimeException(env, "Unable to access address of buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jint write0(JNIEnv * env, jclass clazz, jint fd, void *buffer, jint pos, jint limit) {
|
||||
ssize_t res;
|
||||
int err;
|
||||
do {
|
||||
@ -488,14 +482,22 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_write(JNIEnv * env, jc
|
||||
throwIOException(env, exceptionMessage("Error while write(...): ", err));
|
||||
return -1;
|
||||
}
|
||||
if (posFieldId == NULL) {
|
||||
(*env)->CallObjectMethod(env, jbuffer, updatePosId, pos + res);
|
||||
} else {
|
||||
(*env)->SetIntField(env, jbuffer, posFieldId, pos + res);
|
||||
}
|
||||
return (jint) res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_write(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit) {
|
||||
void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
|
||||
if (buffer == NULL) {
|
||||
throwRuntimeException(env, "Unable to access address of buffer");
|
||||
return -1;
|
||||
}
|
||||
return write0(env, clazz, fd, buffer, pos, limit);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_writeAddress(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit) {
|
||||
return write0(env, clazz, fd, (void *) address, pos, limit);
|
||||
}
|
||||
|
||||
void incrementPosition(JNIEnv * env, jobject bufObj, int written) {
|
||||
// Get the current position using the (*env)->GetIntField if possible and fallback
|
||||
// to slower (*env)->CallIntMethod(...) if needed
|
||||
@ -578,14 +580,7 @@ JNIEXPORT jlong JNICALL Java_io_netty_channel_epoll_Native_writev(JNIEnv * env,
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_read(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit) {
|
||||
// TODO: We could also maybe pass the address in directly and so eliminate this call
|
||||
// not sure if this would buy us much. So some testing is needed.
|
||||
void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
|
||||
if (buffer == NULL) {
|
||||
throwRuntimeException(env, "Unable to access address of buffer");
|
||||
return -1;
|
||||
}
|
||||
jint read0(JNIEnv * env, jclass clazz, jint fd, void *buffer, jint pos, jint limit) {
|
||||
ssize_t res;
|
||||
int err;
|
||||
do {
|
||||
@ -613,6 +608,19 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_read(JNIEnv * env, jcl
|
||||
return (jint) res;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_read(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit) {
|
||||
void *buffer = (*env)->GetDirectBufferAddress(env, jbuffer);
|
||||
if (buffer == NULL) {
|
||||
throwRuntimeException(env, "Unable to access address of buffer");
|
||||
return -1;
|
||||
}
|
||||
return read0(env, clazz, fd, buffer, pos, limit);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_readAddress(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit) {
|
||||
return read0(env, clazz, fd, (void*) address, pos, limit);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_close(JNIEnv * env, jclass clazz, jint fd) {
|
||||
if (close(fd) < 0) {
|
||||
throwIOException(env, "Error closing file descriptor");
|
||||
|
@ -30,8 +30,10 @@ void Java_io_netty_channel_epoll_Native_epollCtlAdd(JNIEnv * env, jclass clazz,
|
||||
void Java_io_netty_channel_epoll_Native_epollCtlMod(JNIEnv * env, jclass clazz, jint efd, jint fd, jint flags, jint id);
|
||||
void Java_io_netty_channel_epoll_Native_epollCtlDel(JNIEnv * env, jclass clazz, jint efd, jint fd);
|
||||
jint Java_io_netty_channel_epoll_Native_write(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
|
||||
jint Java_io_netty_channel_epoll_Native_writeAddress(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
|
||||
jlong Java_io_netty_channel_epoll_Native_writev(JNIEnv * env, jclass clazz, jint fd, jobjectArray buffers, jint offset, jint length);
|
||||
jint Java_io_netty_channel_epoll_Native_read(JNIEnv * env, jclass clazz, jint fd, jobject jbuffer, jint pos, jint limit);
|
||||
jint Java_io_netty_channel_epoll_Native_readAddress(JNIEnv * env, jclass clazz, jint fd, jlong address, jint pos, jint limit);
|
||||
void JNICALL Java_io_netty_channel_epoll_Native_close(JNIEnv * env, jclass clazz, jint fd);
|
||||
void Java_io_netty_channel_epoll_Native_shutdown(JNIEnv * env, jclass clazz, jint fd, jboolean read, jboolean write);
|
||||
jint Java_io_netty_channel_epoll_Native_socket(JNIEnv * env, jclass clazz);
|
||||
|
@ -115,8 +115,12 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
|
||||
int readerIndex = buf.readerIndex();
|
||||
int localFlushedAmount;
|
||||
if (buf.nioBufferCount() == 1) {
|
||||
ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readable);
|
||||
localFlushedAmount = Native.write(fd, nioBuf, nioBuf.position(), nioBuf.limit());
|
||||
if (buf.hasMemoryAddress()) {
|
||||
localFlushedAmount = Native.writeAddress(fd, buf.memoryAddress(), readerIndex, buf.writerIndex());
|
||||
} else {
|
||||
ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readable);
|
||||
localFlushedAmount = Native.write(fd, nioBuf, nioBuf.position(), nioBuf.limit());
|
||||
}
|
||||
} else {
|
||||
// backed by more then one buffer, do a gathering write...
|
||||
ByteBuffer[] nioBufs = buf.nioBuffers();
|
||||
@ -509,8 +513,13 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
|
||||
*/
|
||||
private int doReadBytes(ByteBuf byteBuf) throws Exception {
|
||||
int writerIndex = byteBuf.writerIndex();
|
||||
ByteBuffer buf = byteBuf.internalNioBuffer(writerIndex, byteBuf.writableBytes());
|
||||
int localReadAmount = Native.read(fd, buf, buf.position(), buf.limit());
|
||||
int localReadAmount;
|
||||
if (byteBuf.hasMemoryAddress()) {
|
||||
localReadAmount = Native.readAddress(fd, byteBuf.memoryAddress(), writerIndex, byteBuf.capacity());
|
||||
} else {
|
||||
ByteBuffer buf = byteBuf.internalNioBuffer(writerIndex, byteBuf.writableBytes());
|
||||
localReadAmount = Native.read(fd, buf, buf.position(), buf.limit());
|
||||
}
|
||||
if (localReadAmount > 0) {
|
||||
byteBuf.writerIndex(writerIndex + localReadAmount);
|
||||
}
|
||||
|
@ -60,9 +60,14 @@ final class Native {
|
||||
|
||||
// File-descriptor operations
|
||||
public static native void close(int fd) throws IOException;
|
||||
|
||||
public static native int write(int fd, ByteBuffer buf, int pos, int limit) throws IOException;
|
||||
public static native int writeAddress(int fd, long address, int pos, int limit) throws IOException;
|
||||
|
||||
public static native long writev(int fd, ByteBuffer[] buffers, int offset, int length) throws IOException;
|
||||
public static native int read(int fd, ByteBuffer buf, int pos, int limit) throws IOException;
|
||||
public static native int readAddress(int fd, long address, int pos, int limit) throws IOException;
|
||||
|
||||
public static native long sendfile(int dest, DefaultFileRegion src, long offset, long length) throws IOException;
|
||||
|
||||
// socket operations
|
||||
|
Loading…
Reference in New Issue
Block a user