sendfile is broken on solaris with -d64?

Tigran Mkrtchyan tigran.mkrtchyan at desy.de
Fri Nov 26 07:07:40 PST 2010



Dear NIO gurus,

we observed some weird behavior with sendfile on a solaris box with 
1.6.0_22 and 1.7.0

we notice, that with -d64 FileChannel.transferTo() method uses memory 
mapped file instead of
using systems sendfile call.

according to jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c, 
my_sendfile_func  have initialized
in initIDs() function:

JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileChannelImpl_initIDs(JNIEnv *env, jclass clazz)
{
     jlong pageSize = sysconf(_SC_PAGESIZE);
     chan_fd = (*env)->GetFieldID(env, clazz, "fd", 
"Ljava/io/FileDescriptor;");

#ifdef __solaris__
     if (dlopen("/usr/lib/libsendfile.so.1", RTLD_GLOBAL | RTLD_LAZY) != 
NULL) {
         my_sendfile_func = (sendfile_func*) dlsym(RTLD_DEFAULT, 
"sendfilev64");
     }
#endif

#ifdef __linux__
     my_sendfile64_func = (sendfile64_func*) dlsym(RTLD_DEFAULT, 
"sendfile64");
#endif

     return pageSize;
}

when I run with -d32 I can see that with dtrace ( I puted the probe on 
sysconf call):

               sun/nio/ch/FileChannelImpl.initIDs()J
               sun/nio/ch/FileChannelImpl.<clinit>()V
               StubRoutines (1)
               
libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1c9
               
libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
               
libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
               
libjvm.so`__1cNinstanceKlassbBcall_class_initializer_impl6FnTinstanceKlassHandle_pnGThread__v_+0xce
               
libjvm.so`__1cNinstanceKlassWcall_class_initializer6MpnGThread__v_+0x4f
               
libjvm.so`__1cNinstanceKlassPinitialize_impl6FnTinstanceKlassHandle_pnGThread__v_+0x2cc
               libjvm.so`__1cNinstanceKlassKinitialize6MpnGThread__v_+0x6c
               
libjvm.so`__1cMLinkResolverTresolve_static_call6FrnICallInfo_rnLKlassHandle_nMsymbolHandle_53bbpnGThread__v_+0xd3
               
libjvm.so`__1cMLinkResolverUresolve_invokestatic6FrnICallInfo_nSconstantPoolHandle_ipnGThread__v_+0x67
               
libjvm.so`__1cMLinkResolverOresolve_invoke6FrnICallInfo_nGHandle_nSconstantPoolHandle_inJBytecodesECode_pnGThread__v_+0x71


But I dont see that with -d64. As a result, pointer to my_sendfile_func 
still NULL and sendfile method returns UNSUPPORTED:
#ifdef __solaris__
     if (my_sendfile_func == NULL) {
         return IOS_UNSUPPORTED;
     }
...


How this happens is a puzzle for me, as according to the code it called 
in a static block of jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java:

     static {
         Util.load();
         allocationGranularity = initIDs();
         nd = new FileDispatcher();
         isAMappedBufferField = 
Reflect.lookupField("java.nio.MappedByteBuffer",
                                           "isAMappedBuffer");
     }

here is my dtrace script:

#  dtrace -s s1.d -c "java -XX:+ExtendedDTraceProbes -d64 Send"

# trace only calls with SC_PAGESIZE as argument
pid$target::sysconf:entry
/ arg0 == 11 /
{
    self->pagesize = 1;
}

pid$target::sysconf:return
/self->pagesize/
{
    printf("sysconf: rc=%d", arg0);
    jstack(50, 500);

    self->pagesize = 0;
}


Regards,
    Tigran.


More information about the nio-dev mailing list