# HG changeset patch # User vtewari # Date 1494437809 -19800 # Node ID 74b09ee3cd556a84c35e980069a1afefa2339a90 # Parent adbeae0f677e762e98913d255205274601ba3d00 8179905: Remove the use of gettimeofday in Networking code Reviewed-by: chegar, rriggs, dfuchs, clanger diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/aix/native/libnet/aix_close.c --- a/jdk/src/java.base/aix/native/libnet/aix_close.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/aix/native/libnet/aix_close.c Wed May 10 23:06:49 2017 +0530 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, SAP SE and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, SAP SE and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,8 @@ #include #include #include +#include "jvm.h" +#include "net_util.h" /* * Stack allocated by thread when doing blocking operation @@ -507,9 +509,9 @@ * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout0(int s, long timeout, long currentTime) { - long prevtime = currentTime, newtime; - struct timeval t; +int NET_Timeout(JNIEnv *env, int s, long timeout, jlong nanoTimeStamp) { + jlong prevNanoTime = nanoTimeStamp; + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; fdEntry_t *fdEntry = getFdEntry(s); /* @@ -533,7 +535,7 @@ pfd.events = POLLIN | POLLERR; startOp(fdEntry, &self); - rv = poll(&pfd, 1, timeout); + rv = poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); endOp(fdEntry, &self); /* @@ -541,18 +543,14 @@ * has expired return 0 (indicating timeout expired). */ if (rv < 0 && errno == EINTR) { - if (timeout > 0) { - gettimeofday(&t, NULL); - newtime = t.tv_sec * 1000 + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - return 0; - } - prevtime = newtime; + jlong newNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= newNanoTime - prevNanoTime; + if (nanoTimeout < NET_NSEC_PER_MSEC) { + return 0; } + prevNanoTime = newNanoTime; } else { return rv; } - } } diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/linux/native/libnet/linux_close.c --- a/jdk/src/java.base/linux/native/libnet/linux_close.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/linux/native/libnet/linux_close.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ #include #include #include +#include "jvm.h" +#include "net_util.h" /* * Stack allocated by thread when doing blocking operation @@ -410,9 +412,9 @@ * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout0(int s, long timeout, long currentTime) { - long prevtime = currentTime, newtime; - struct timeval t; +int NET_Timeout(JNIEnv *env, int s, long timeout, jlong nanoTimeStamp) { + jlong prevNanoTime = nanoTimeStamp; + jlong nanoTimeout = (jlong)timeout * NET_NSEC_PER_MSEC; fdEntry_t *fdEntry = getFdEntry(s); /* @@ -436,26 +438,21 @@ pfd.events = POLLIN | POLLERR; startOp(fdEntry, &self); - rv = poll(&pfd, 1, timeout); + rv = poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); endOp(fdEntry, &self); - /* * If interrupted then adjust timeout. If timeout * has expired return 0 (indicating timeout expired). */ if (rv < 0 && errno == EINTR) { - if (timeout > 0) { - gettimeofday(&t, NULL); - newtime = t.tv_sec * 1000 + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - return 0; - } - prevtime = newtime; + jlong newNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= newNanoTime - prevNanoTime; + if (nanoTimeout < NET_NSEC_PER_MSEC) { + return 0; } + prevNanoTime = newNanoTime; } else { return rv; } - } } diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/macosx/native/libnet/bsd_close.c --- a/jdk/src/java.base/macosx/native/libnet/bsd_close.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/macosx/native/libnet/bsd_close.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ #include #include #include +#include "jvm.h" +#include "net_util.h" /* * Stack allocated by thread when doing blocking operation @@ -414,8 +416,7 @@ * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout0(int s, long timeout, long currentTime) { - long prevtime = currentTime, newtime; +int NET_Timeout(JNIEnv *env, int s, long timeout, jlong nanoTimeStamp) { struct timeval t, *tp = &t; fd_set fds; fd_set* fdsp = NULL; @@ -460,6 +461,8 @@ } FD_SET(s, fdsp); + jlong prevNanoTime = nanoTimeStamp; + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; for(;;) { int rv; @@ -477,25 +480,21 @@ * has expired return 0 (indicating timeout expired). */ if (rv < 0 && errno == EINTR) { - if (timeout > 0) { - struct timeval now; - gettimeofday(&now, NULL); - newtime = now.tv_sec * 1000 + now.tv_usec / 1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - if (allocated != 0) - free(fdsp); - return 0; - } - prevtime = newtime; - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; + jlong newNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= newNanoTime - prevNanoTime; + if (nanoTimeout < NET_NSEC_PER_MSEC) { + if (allocated != 0) + free(fdsp); + return 0; } + prevNanoTime = newNanoTime; + t.tv_sec = nanoTimeout / NET_NSEC_PER_SEC; + t.tv_usec = (nanoTimeout % NET_NSEC_PER_SEC) / NET_NSEC_PER_USEC; + } else { if (allocated != 0) free(fdsp); return rv; } - } } diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/solaris/native/libnet/solaris_close.c --- a/jdk/src/java.base/solaris/native/libnet/solaris_close.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/solaris/native/libnet/solaris_close.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ #include #include #include +#include "jvm.h" +#include "net_util.h" /* Support for restartable system calls on Solaris. */ @@ -90,25 +92,22 @@ RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout)); } -int NET_Timeout0(int s, long timeout, long currentTime) { +int NET_Timeout(JNIEnv *env, int s, long timeout, jlong nanoTimeStamp) { int result; - struct timeval t; - long prevtime = currentTime, newtime; + jlong prevNanoTime = nanoTimeStamp; + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; struct pollfd pfd; pfd.fd = s; pfd.events = POLLIN; for(;;) { - result = poll(&pfd, 1, timeout); + result = poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); if (result < 0 && errno == EINTR) { - if (timeout > 0) { - gettimeofday(&t, NULL); - newtime = (t.tv_sec * 1000) + t.tv_usec /1000; - timeout -= newtime - prevtime; - if (timeout <= 0) - return 0; - prevtime = newtime; - } + jlong newNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= newNanoTime - prevNanoTime; + if (nanoTimeout < NET_NSEC_PER_MSEC) + return 0; + prevNanoTime = newNanoTime; } else { return result; } diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c --- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -485,7 +485,7 @@ return -1; } if (timeout) { - int ret = NET_Timeout(fd, timeout); + int ret = NET_Timeout(env, fd, timeout, JVM_NanoTime(env, 0)); if (ret == 0) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "Peek timed out"); @@ -576,7 +576,7 @@ packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID); packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID); if (timeout) { - int ret = NET_Timeout(fd, timeout); + int ret = NET_Timeout(env, fd, timeout, JVM_NanoTime(env, 0)); if (ret == 0) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "Receive timed out"); @@ -789,7 +789,7 @@ retry = JNI_FALSE; if (timeout) { - int ret = NET_Timeout(fd, timeout); + int ret = NET_Timeout(env, fd, timeout, JVM_NanoTime(env, 0)); if (ret <= 0) { if (ret == 0) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c --- a/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ */ #include +#include "jvm.h" #include "net_util.h" #include "java_net_SocketOptions.h" @@ -231,7 +232,6 @@ { jint localport = (*env)->GetIntField(env, this, psi_localportID); int len = 0; - /* fdObj is the FileDescriptor field on this */ jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID); @@ -325,7 +325,8 @@ /* connection not established immediately */ if (connect_rv != 0) { socklen_t optlen; - jlong prevTime = JVM_CurrentTimeMillis(env, 0); + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; + jlong prevNanoTime = JVM_NanoTime(env, 0); if (errno != EINPROGRESS) { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException", @@ -341,13 +342,13 @@ * this thread. */ while (1) { - jlong newTime; + jlong newNanoTime; struct pollfd pfd; pfd.fd = fd; pfd.events = POLLOUT; errno = 0; - connect_rv = NET_Poll(&pfd, 1, timeout); + connect_rv = NET_Poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); if (connect_rv >= 0) { break; @@ -360,13 +361,13 @@ * The poll was interrupted so adjust timeout and * restart */ - newTime = JVM_CurrentTimeMillis(env, 0); - timeout -= (newTime - prevTime); - if (timeout <= 0) { + newNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= (newNanoTime - prevNanoTime); + if (nanoTimeout < NET_NSEC_PER_MSEC) { connect_rv = 0; break; } - prevTime = newTime; + prevNanoTime = newNanoTime; } /* while */ @@ -593,7 +594,8 @@ /* fields on this */ int port; jint timeout = (*env)->GetIntField(env, this, psi_timeoutID); - jlong prevTime = 0; + jlong prevNanoTime = 0; + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID); /* the FileDescriptor field on socket */ @@ -633,18 +635,19 @@ */ for (;;) { int ret; + jlong currNanoTime; /* first usage pick up current time */ - if (prevTime == 0 && timeout > 0) { - prevTime = JVM_CurrentTimeMillis(env, 0); + if (prevNanoTime == 0 && nanoTimeout > 0) { + prevNanoTime = JVM_NanoTime(env, 0); } /* passing a timeout of 0 to poll will return immediately, but in the case of ServerSocket 0 means infinite. */ if (timeout <= 0) { - ret = NET_Timeout(fd, -1); + ret = NET_Timeout(env, fd, -1, 0); } else { - ret = NET_Timeout(fd, timeout); + ret = NET_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC, prevNanoTime); } if (ret == 0) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", @@ -676,17 +679,14 @@ } /* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */ - if (timeout) { - jlong currTime = JVM_CurrentTimeMillis(env, 0); - timeout -= (currTime - prevTime); - - if (timeout <= 0) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", - "Accept timed out"); - return; - } - prevTime = currTime; + currNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= (currNanoTime - prevNanoTime); + if (nanoTimeout < NET_NSEC_PER_MSEC) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", + "Accept timed out"); + return; } + prevNanoTime = currNanoTime; } if (newfd < 0) { diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/unix/native/libnet/SocketInputStream.c --- a/jdk/src/java.base/unix/native/libnet/SocketInputStream.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/unix/native/libnet/SocketInputStream.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #include #include +#include "jvm.h" #include "net_util.h" #include "java_net_SocketInputStream.h" @@ -48,9 +49,10 @@ static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) { int result = 0; - long prevtime = NET_GetCurrentTime(), newtime; - while (timeout > 0) { - result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime); + jlong prevNanoTime = JVM_NanoTime(env, 0); + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; + while (nanoTimeout >= NET_NSEC_PER_MSEC) { + result = NET_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC, prevNanoTime); if (result <= 0) { if (result == 0) { JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out"); @@ -68,10 +70,10 @@ } result = NET_NonBlockingRead(fd, bufP, len); if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) { - newtime = NET_GetCurrentTime(); - timeout -= newtime - prevtime; - if (timeout > 0) { - prevtime = newtime; + jlong newtNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= newtNanoTime - prevNanoTime; + if (nanoTimeout >= NET_NSEC_PER_MSEC) { + prevNanoTime = newtNanoTime; } } else { break; diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/unix/native/libnet/net_util_md.c --- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ #include #endif +#include "jvm.h" #include "net_util.h" #include "java_net_SocketOptions.h" @@ -1543,11 +1544,12 @@ jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) { - jlong prevTime = JVM_CurrentTimeMillis(env, 0); + jlong prevNanoTime = JVM_NanoTime(env, 0); + jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; jint read_rv; while (1) { - jlong newTime; + jlong newNanoTime; struct pollfd pfd; pfd.fd = fd; pfd.events = 0; @@ -1559,36 +1561,18 @@ pfd.events |= POLLOUT; errno = 0; - read_rv = NET_Poll(&pfd, 1, timeout); + read_rv = NET_Poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); - newTime = JVM_CurrentTimeMillis(env, 0); - timeout -= (newTime - prevTime); - if (timeout <= 0) { + newNanoTime = JVM_NanoTime(env, 0); + nanoTimeout -= (newNanoTime - prevNanoTime); + if (nanoTimeout < NET_NSEC_PER_MSEC) { return read_rv > 0 ? 0 : -1; } - prevTime = newTime; + prevNanoTime = newNanoTime; if (read_rv > 0) { break; } - - } /* while */ - - return timeout; + return (nanoTimeout / NET_NSEC_PER_MSEC); } - -long NET_GetCurrentTime() { - struct timeval time; - gettimeofday(&time, NULL); - return (time.tv_sec * 1000 + time.tv_usec / 1000); -} - -int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) { - return NET_Timeout0(s, timeout, currentTime); -} - -int NET_Timeout(int s, long timeout) { - long currentTime = (timeout > 0) ? NET_GetCurrentTime() : 0; - return NET_Timeout0(s, timeout, currentTime); -} diff -r adbeae0f677e -r 74b09ee3cd55 jdk/src/java.base/unix/native/libnet/net_util_md.h --- a/jdk/src/java.base/unix/native/libnet/net_util_md.h Wed May 10 12:00:08 2017 +0530 +++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h Wed May 10 23:06:49 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,10 @@ * Macros and constants */ +#define NET_NSEC_PER_MSEC 1000000 +#define NET_NSEC_PER_SEC 1000000000 +#define NET_NSEC_PER_USEC 1000 + /* Defines SO_REUSEPORT */ #ifndef SO_REUSEPORT #ifdef __linux__ @@ -68,12 +72,9 @@ * Functions */ -int NET_Timeout(int s, long timeout); -int NET_Timeout0(int s, long timeout, long currentTime); +int NET_Timeout(JNIEnv *env, int s, long timeout, jlong nanoTimeStamp); int NET_Read(int s, void* buf, size_t len); int NET_NonBlockingRead(int s, void* buf, size_t len); -int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime); -long NET_GetCurrentTime(); int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen); int NET_ReadV(int s, const struct iovec * vector, int count);