Thanks for doing this Paul. Looks good ( with Alan and Doug’s comments ).
-Chris. On 2 Dec 2014, at 10:02, Paul Sandoz <paul.san...@oracle.com> wrote: > Hi, > > Please find below a patch to remove the networking code computing a seed in > ThreadLocal/SplittableRandom. > > We thought it a good idea at the time :-) but subsequently on certain > platforms this results in very high initalization costs that can propagate to > other classes such as ConcurrentSkipList*. > > The short-term solution is to remove this code and fallback just using > current system time. This needs to be back-ported to 8u40. > > A longer term solution is to provide a simple public API to get access to > some seed bytes that is optimal for the underlying platform, for example, > based on Peter's investigations. For linux /dev/urandom is sufficient as a > source of bytes. The main problem seems to be Windows. It would also be nice > to back-port to say 8u60 using a private API and update TLR/SR. > > Paul. > > [1] https://bugs.openjdk.java.net/browse/JDK-8060435 > > diff -r 1b599b4755bd > src/java.base/share/classes/java/util/SplittableRandom.java > --- a/src/java.base/share/classes/java/util/SplittableRandom.java Mon Dec > 01 17:59:39 2014 -0800 > +++ b/src/java.base/share/classes/java/util/SplittableRandom.java Tue Dec > 02 10:53:47 2014 +0100 > @@ -237,34 +237,7 @@ > s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); > return s; > } > - long h = 0L; > - try { > - Enumeration<NetworkInterface> ifcs = > - NetworkInterface.getNetworkInterfaces(); > - boolean retry = false; // retry once if getHardwareAddress is > null > - while (ifcs.hasMoreElements()) { > - NetworkInterface ifc = ifcs.nextElement(); > - if (!ifc.isVirtual()) { // skip fake addresses > - byte[] bs = ifc.getHardwareAddress(); > - if (bs != null) { > - int n = bs.length; > - int m = Math.min(n >>> 1, 4); > - for (int i = 0; i < m; ++i) > - h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i]; > - if (m < 4) > - h = (h << 8) ^ bs[n-1-m]; > - h = mix64(h); > - break; > - } > - else if (!retry) > - retry = true; > - else > - break; > - } > - } > - } catch (Exception ignore) { > - } > - return (h ^ mix64(System.currentTimeMillis()) ^ > + return (mix64(System.currentTimeMillis()) ^ > mix64(System.nanoTime())); > } > > diff -r 1b599b4755bd > src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java > --- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java > Mon Dec 01 17:59:39 2014 -0800 > +++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java > Tue Dec 02 10:53:47 2014 +0100 > @@ -147,34 +147,7 @@ > s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); > return s; > } > - long h = 0L; > - try { > - Enumeration<NetworkInterface> ifcs = > - NetworkInterface.getNetworkInterfaces(); > - boolean retry = false; // retry once if getHardwareAddress is > null > - while (ifcs.hasMoreElements()) { > - NetworkInterface ifc = ifcs.nextElement(); > - if (!ifc.isVirtual()) { // skip fake addresses > - byte[] bs = ifc.getHardwareAddress(); > - if (bs != null) { > - int n = bs.length; > - int m = Math.min(n >>> 1, 4); > - for (int i = 0; i < m; ++i) > - h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i]; > - if (m < 4) > - h = (h << 8) ^ bs[n-1-m]; > - h = mix64(h); > - break; > - } > - else if (!retry) > - retry = true; > - else > - break; > - } > - } > - } catch (Exception ignore) { > - } > - return (h ^ mix64(System.currentTimeMillis()) ^ > + return (mix64(System.currentTimeMillis()) ^ > mix64(System.nanoTime())); > }