diff options
author | Narayan Kamath <narayan@google.com> | 2014-11-14 11:14:37 +0000 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2014-11-17 13:51:11 +0000 |
commit | 7c22337691326a03386e42a32becbeb2c2dc7f06 (patch) | |
tree | 81b33f235d41c97f0db44256240271c5f58da3f8 | |
parent | 5dbbe8317afd79d21bdbe931fe476ccf9a4bf269 (diff) | |
download | libcore-7c22337691326a03386e42a32becbeb2c2dc7f06.zip libcore-7c22337691326a03386e42a32becbeb2c2dc7f06.tar.gz libcore-7c22337691326a03386e42a32becbeb2c2dc7f06.tar.bz2 |
Set random seeds post fork.
Gets rid of static Random objects from various classes and
makes them use Math.random instead. Also add hidden APIs to
set the random seed post fork (where we're single threaded).
This has the nice side effect of fixing a performance bug
related to linpack (11388705) where threads were serializing
on Math.class while calling Math.random.
bug: https://code.google.com/p/android/issues/detail?id=79143
bug: 11388705
Change-Id: Ide3a7d17fe855a8086601348be87a890e4c42ab4
-rw-r--r-- | dalvik/src/main/java/dalvik/system/ZygoteHooks.java | 4 | ||||
-rw-r--r-- | luni/src/main/java/java/io/File.java | 8 | ||||
-rw-r--r-- | luni/src/main/java/java/lang/Math.java | 26 | ||||
-rw-r--r-- | luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java | 20 | ||||
-rw-r--r-- | luni/src/main/java/libcore/io/IoUtils.java | 4 |
5 files changed, 39 insertions, 23 deletions
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java index 11ea286..59d8820 100644 --- a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java +++ b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java @@ -29,7 +29,7 @@ public final class ZygoteHooks { /** * Called by the zygote prior to every fork. Each call to {@code preFork} - * is followed by a matching call to {@link #postForkChild(int)} on the child + * is followed by a matching call to {@link #postForkChild(int, String)} on the child * process and {@link #postForkCommon()} on both the parent and the child * process. {@code postForkCommon} is called after {@code postForkChild} in * the child process. @@ -47,6 +47,8 @@ public final class ZygoteHooks { */ public void postForkChild(int debugFlags, String instructionSet) { nativePostForkChild(token, debugFlags, instructionSet); + + Math.setRandomSeedInternal(System.currentTimeMillis()); } /** diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java index d107c28..a07d34c 100644 --- a/luni/src/main/java/java/io/File.java +++ b/luni/src/main/java/java/io/File.java @@ -57,12 +57,6 @@ public class File implements Serializable, Comparable<File> { private static final long serialVersionUID = 301077366599181567L; /** - * Reusing a Random makes temporary filenames slightly harder to predict. - * (Random is thread-safe.) - */ - private static final Random tempFileRandom = new Random(); - - /** * The system-dependent character used to separate components in filenames ('/'). * Use of this (rather than hard-coding '/') helps portability to other operating systems. * @@ -1002,7 +996,7 @@ public class File implements Serializable, Comparable<File> { } File result; do { - result = new File(tmpDirFile, prefix + tempFileRandom.nextInt() + suffix); + result = new File(tmpDirFile, prefix + Math.randomIntInternal() + suffix); } while (!result.createNewFile()); return result; } diff --git a/luni/src/main/java/java/lang/Math.java b/luni/src/main/java/java/lang/Math.java index 86df784..a738511 100644 --- a/luni/src/main/java/java/lang/Math.java +++ b/luni/src/main/java/java/lang/Math.java @@ -35,7 +35,7 @@ public final class Math { */ public static final double PI = 3.141592653589793; - private static Random random; + private static final Random INSTANCE = new Random(); /** * Prevents this class from being instantiated. @@ -875,11 +875,25 @@ public final class Math { * * @return a pseudo-random number. */ - public static synchronized double random() { - if (random == null) { - random = new Random(); - } - return random.nextDouble(); + public static double random() { + return INSTANCE.nextDouble(); + } + + /** + * Set the seed for the pseudo random generator used by {@link #random()} + * and {@link #randomIntInternal()}. + * + * @hide for internal use only. + */ + public static void setRandomSeedInternal(long seed) { + INSTANCE.setSeed(seed); + } + + /** + * @hide for internal use only. + */ + public static int randomIntInternal() { + return INSTANCE.nextInt(); } /** diff --git a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java index 803cd49..4a76104 100644 --- a/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java +++ b/luni/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java @@ -293,11 +293,13 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> private static final long serialVersionUID = -8627078645895051609L; - /** - * Generates the initial random seed for the cheaper per-instance - * random number generators used in randomLevel. - */ - private static final Random seedGenerator = new Random(); +// BEGIN android-removed +// /** +// * Generates the initial random seed for the cheaper per-instance +// * random number generators used in randomLevel. +// */ +// private static final Random seedGenerator = new Random(); +// END android-removed /** * Special value used to identify base-level header @@ -341,7 +343,13 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> entrySet = null; values = null; descendingMap = null; - randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero + // BEGIN android-changed + // + // Most processes are forked from the zygote, so they'll end up + // with the same random seed unless we take additional post fork + // measures. + randomSeed = Math.randomIntInternal() | 0x0100; // ensure nonzero + // END android-changed head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null), null, null, 1); } diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java index 5a19f17..737ceeb 100644 --- a/luni/src/main/java/libcore/io/IoUtils.java +++ b/luni/src/main/java/libcore/io/IoUtils.java @@ -30,8 +30,6 @@ import java.util.Random; import static android.system.OsConstants.*; public final class IoUtils { - private static final Random TEMPORARY_DIRECTORY_PRNG = new Random(); - private IoUtils() { } @@ -142,7 +140,7 @@ public final class IoUtils { */ public static File createTemporaryDirectory(String prefix) { while (true) { - String candidateName = prefix + TEMPORARY_DIRECTORY_PRNG.nextInt(); + String candidateName = prefix + Math.randomIntInternal(); File result = new File(System.getProperty("java.io.tmpdir"), candidateName); if (result.mkdir()) { return result; |