diff --git a/jdk/make/gendata/GendataBreakIterator.gmk b/jdk/make/gendata/GendataBreakIterator.gmk index 6c60ec26d6b..4407fa9b166 100644 --- a/jdk/make/gendata/GendataBreakIterator.gmk +++ b/jdk/make/gendata/GendataBreakIterator.gmk @@ -58,13 +58,13 @@ UNICODEDATA := $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt # output BASE_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/java.base/sun/text/resources -SL_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources +LD_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources BIFILES := $(BASE_DATA_PKG_DIR)/CharacterBreakIteratorData \ $(BASE_DATA_PKG_DIR)/WordBreakIteratorData \ $(BASE_DATA_PKG_DIR)/LineBreakIteratorData \ $(BASE_DATA_PKG_DIR)/SentenceBreakIteratorData -BIFILES_TH := $(SA_DATA_PKG_DIR)/th/WordBreakIteratorData_th \ - $(SA_DATA_PKG_DIR)/th/LineBreakIteratorData_th +BIFILES_TH := $(LD_DATA_PKG_DIR)/th/WordBreakIteratorData_th \ + $(LD_DATA_PKG_DIR)/th/LineBreakIteratorData_th $(BIFILES): $(BASE_DATA_PKG_DIR)/_the.bifiles $(BASE_DATA_PKG_DIR)/_the.bifiles: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES) @@ -77,9 +77,9 @@ $(BASE_DATA_PKG_DIR)/_the.bifiles: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKIT -spec $(UNICODEDATA) $(TOUCH) $@ -$(BIFILES_TH): $(SL_DATA_PKG_DIR)/_the.bifiles_th -$(SL_DATA_PKG_DIR)/_the.bifiles_th: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES) -$(SL_DATA_PKG_DIR)/_the.bifiles_th: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKITERATOR) +$(BIFILES_TH): $(LD_DATA_PKG_DIR)/_the.bifiles_th +$(LD_DATA_PKG_DIR)/_the.bifiles_th: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES) +$(LD_DATA_PKG_DIR)/_the.bifiles_th: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKITERATOR) $(ECHO) $(LOG_INFO) "Generating BreakIteratorData_th" $(MKDIR) -p $(@D)/th $(RM) $(BIFILES_TH) diff --git a/jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk b/jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk new file mode 100644 index 00000000000..11e54a6f635 --- /dev/null +++ b/jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk @@ -0,0 +1,55 @@ +# +# Copyright (c) 2015, 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 +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include GensrcCommon.gmk + +################################################################################ + +define merge-providers + $(MKDIR) -p $(@D) + $(CAT) $^ > $@ +endef + +PROVIDER_FILE := META-INF/services/sun.jvmstat.monitor.MonitoredHostService + +# Merge the local and remote sevice providers into jdk.jvmstat/META-INF/services +$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE): \ + $(JDK_TOPDIR)/src/jdk.jvmstat/share/classes/$(PROVIDER_FILE) \ + $(JDK_TOPDIR)/src/jdk.jvmstat.rmi/share/classes/$(PROVIDER_FILE) + $(merge-providers) + +# Copy the same service file into jdk.jvmstat.rmi so that they are kept the same. +$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE): \ + $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) + $(install-file) + +################################################################################ + +jdk.jvmstat: $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) \ + $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE) + +all: jdk.jvmstat + +.PHONY: all \ No newline at end of file diff --git a/jdk/make/gensrc/GensrcCommon.gmk b/jdk/make/gensrc/GensrcCommon.gmk index 09819e19d57..a3370639176 100644 --- a/jdk/make/gensrc/GensrcCommon.gmk +++ b/jdk/make/gensrc/GensrcCommon.gmk @@ -33,4 +33,3 @@ include TextFileProcessing.gmk include SetupJavaCompilers.gmk # We need the tools. include Tools.gmk - diff --git a/jdk/make/gensrc/GensrcMisc.gmk b/jdk/make/gensrc/GensrcMisc.gmk index 7762a284952..1587cbcadc5 100644 --- a/jdk/make/gensrc/GensrcMisc.gmk +++ b/jdk/make/gensrc/GensrcMisc.gmk @@ -100,7 +100,6 @@ ifneq ($(OPENJDK_TARGET_OS), windows) SRC := $(GENSRC_UC_SRC), \ INCLUDE_FILES := $(GENSRC_UC_SRC_FILE), \ TOOLCHAIN := TOOLCHAIN_BUILD, \ - CFLAGS := $(filter -D%, $(CFLAGS_JDKEXE)), \ OBJECT_DIR := $(GENSRC_UC_BIN), \ OUTPUT_DIR := $(GENSRC_UC_BIN), \ PROGRAM := genUnixConstants)) diff --git a/jdk/make/gensrc/GensrcProperties.gmk b/jdk/make/gensrc/GensrcProperties.gmk index 7293a19bbeb..2cc6231175e 100644 --- a/jdk/make/gensrc/GensrcProperties.gmk +++ b/jdk/make/gensrc/GensrcProperties.gmk @@ -75,7 +75,7 @@ define SetupCompilePropertiesBody # Convert .../src//share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties # to .../support/gensrc//com/sun/tools/javac/resources/javac_zh_CN.java - # Strip away prefix and suffix, leaving for example only: + # Strip away prefix and suffix, leaving for example only: # "/share/classes/com/sun/tools/javac/resources/javac_zh_CN" $1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \ $(SUPPORT_OUTPUTDIR)/gensrc/%, \ diff --git a/jdk/make/launcher/Launcher-jdk.jcmd.gmk b/jdk/make/launcher/Launcher-jdk.jcmd.gmk index 34d24418550..a742b1a2de3 100644 --- a/jdk/make/launcher/Launcher-jdk.jcmd.gmk +++ b/jdk/make/launcher/Launcher-jdk.jcmd.gmk @@ -30,7 +30,6 @@ $(eval $(call SetupBuildLauncher, jinfo, \ JAVA_ARGS := \ -Dsun.jvm.hotspot.debugger.useProcDebugger \ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ MACOSX_SIGNED := true, \ )) @@ -39,7 +38,6 @@ $(eval $(call SetupBuildLauncher, jmap, \ JAVA_ARGS := \ -Dsun.jvm.hotspot.debugger.useProcDebugger \ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ MACOSX_SIGNED := true, \ )) @@ -52,7 +50,6 @@ $(eval $(call SetupBuildLauncher, jstack, \ JAVA_ARGS := \ -Dsun.jvm.hotspot.debugger.useProcDebugger \ -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ MACOSX_SIGNED := true, \ )) diff --git a/jdk/make/launcher/Launcher-jdk.jconsole.gmk b/jdk/make/launcher/Launcher-jdk.jconsole.gmk index 7c5ada82382..aa07823c54a 100644 --- a/jdk/make/launcher/Launcher-jdk.jconsole.gmk +++ b/jdk/make/launcher/Launcher-jdk.jconsole.gmk @@ -28,7 +28,6 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jconsole, \ MAIN_CLASS := sun.tools.jconsole.JConsole, \ JAVA_ARGS := -Djconsole.showOutputViewer, \ - APP_CLASSPATH := /lib/jconsole.jar /lib/tools.jar /classes, \ CFLAGS_windows := -DJAVAW, \ LIBS_windows := user32.lib, \ )) diff --git a/jdk/make/launcher/Launcher-jdk.jdi.gmk b/jdk/make/launcher/Launcher-jdk.jdi.gmk index acb2a7125ba..fcce98cf430 100644 --- a/jdk/make/launcher/Launcher-jdk.jdi.gmk +++ b/jdk/make/launcher/Launcher-jdk.jdi.gmk @@ -27,5 +27,4 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jdb, \ MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \ - APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \ )) diff --git a/jdk/make/launcher/Launcher-jdk.jvmstat.gmk b/jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk similarity index 100% rename from jdk/make/launcher/Launcher-jdk.jvmstat.gmk rename to jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk diff --git a/jdk/make/launcher/LauncherCommon.gmk b/jdk/make/launcher/LauncherCommon.gmk index debc6337b60..b7d0ccf459e 100644 --- a/jdk/make/launcher/LauncherCommon.gmk +++ b/jdk/make/launcher/LauncherCommon.gmk @@ -64,7 +64,6 @@ JAVA_MANIFEST := $(JDK_TOPDIR)/src/java.base/windows/native/launcher/java.manife # Remaining parameters are named arguments. These include: # MAIN_CLASS The Java main class to launch # JAVA_ARGS Processed into a -DJAVA_ARGS C flag -# APP_CLASSPATH Processed into a -DAPP_CLASSPATH C flag # CFLAGS Additional CFLAGS # CFLAGS_windows Additional CFLAGS_windows # LIBS_unix Additional LIBS_unix @@ -103,15 +102,6 @@ define SetupBuildLauncherBody $1_CFLAGS += -DJAVA_ARGS=$$($1_JAVA_ARGS_STR) endif - ifneq ($$($1_APP_CLASSPATH), ) - $1_APP_CLASSPATH_STR := '{ $$(strip $$(foreach a, \ - $$($1_APP_CLASSPATH), "$$a"$(COMMA) )) }' - # Remove the trailing comma - $1_APP_CLASSPATH_STR := $$(strip $$(subst $$(COMMA) }', }', \ - $$($1_APP_CLASSPATH_STR))) - $1_CFLAGS += -DAPP_CLASSPATH=$$($1_APP_CLASSPATH_STR) - endif - $1_LIBS := ifeq ($(OPENJDK_TARGET_OS), macosx) ifeq ($$($1_MACOSX_SIGNED), true) diff --git a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk index 9f2ff08d7be..c71634166b2 100644 --- a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk +++ b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk @@ -43,7 +43,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris) LDFLAGS := $(LDFLAGS_JDKLIB), \ LIBS := $(LIBDL), \ LIBS_solaris := -lc, \ - OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2ucrypto, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2ucrypto, \ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) $(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA) diff --git a/jdk/make/src/classes/build/tools/module/ext.modules b/jdk/make/src/classes/build/tools/module/ext.modules index 15c2e9d6ae0..d266d40847f 100644 --- a/jdk/make/src/classes/build/tools/module/ext.modules +++ b/jdk/make/src/classes/build/tools/module/ext.modules @@ -9,6 +9,7 @@ jdk.crypto.ec jdk.crypto.mscapi jdk.crypto.pkcs11 jdk.crypto.ucrypto +jdk.dynalink jdk.localedata jdk.naming.dns jdk.scripting.nashorn diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java b/jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java similarity index 61% rename from jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java rename to jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java index e812e535165..3f23cc4fa3b 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java +++ b/jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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,8 +26,6 @@ package sun.nio.ch; import java.nio.channels.spi.SelectorProvider; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; /** * Creates this platform's default SelectorProvider @@ -40,32 +38,10 @@ public class DefaultSelectorProvider { */ private DefaultSelectorProvider() { } - @SuppressWarnings("unchecked") - private static SelectorProvider createProvider(String cn) { - Class c; - try { - c = (Class)Class.forName(cn); - } catch (ClassNotFoundException x) { - throw new AssertionError(x); - } - try { - return c.newInstance(); - } catch (IllegalAccessException | InstantiationException x) { - throw new AssertionError(x); - } - - } - /** * Returns the default SelectorProvider. */ public static SelectorProvider create() { - String osname = AccessController - .doPrivileged(new GetPropertyAction("os.name")); - if (osname.equals("SunOS")) - return createProvider("sun.nio.ch.DevPollSelectorProvider"); - if (osname.equals("Linux")) - return createProvider("sun.nio.ch.EPollSelectorProvider"); return new sun.nio.ch.PollSelectorProvider(); } diff --git a/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java b/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java new file mode 100644 index 00000000000..1278f1583ee --- /dev/null +++ b/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.nio.ch; + +import java.nio.channels.spi.SelectorProvider; + +/** + * Creates this platform's default SelectorProvider + */ + +public class DefaultSelectorProvider { + + /** + * Prevent instantiation. + */ + private DefaultSelectorProvider() { } + + /** + * Returns the default SelectorProvider. + */ + public static SelectorProvider create() { + return new sun.nio.ch.EPollSelectorProvider(); + } + +} diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java index 5e7da4bb6d4..203fde39335 100644 --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java @@ -272,22 +272,6 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { // (Done collecting options from props.) - boolean isClassFile(String name) { - if (!name.endsWith(".class")) return false; - for (String prefix = name; ; ) { - if (passFiles.contains(prefix)) return false; - int chop = prefix.lastIndexOf('/'); - if (chop < 0) break; - prefix = prefix.substring(0, chop); - } - return true; - } - - boolean isMetaInfFile(String name) { - return name.startsWith("/" + Utils.METAINF) || - name.startsWith(Utils.METAINF); - } - // Get a new package, based on the old one. private void makeNextPackage() { pkg.reset(); @@ -332,6 +316,29 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { InFile(JarEntry je) { this(null, je); } + boolean isClassFile() { + if (!name.endsWith(".class")) { + return false; + } + for (String prefix = name;;) { + if (passFiles.contains(prefix)) { + return false; + } + int chop = prefix.lastIndexOf('/'); + if (chop < 0) { + break; + } + prefix = prefix.substring(0, chop); + } + return true; + } + boolean isMetaInfFile() { + return name.startsWith("/" + Utils.METAINF) + || name.startsWith(Utils.METAINF); + } + boolean mustProcess() { + return !isMetaInfFile() && isClassFile(); + } long getInputLength() { long len = (je != null)? je.getSize(): f.length(); assert(len >= 0) : this+".len="+len; @@ -391,7 +398,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { Package.File file = null; // (5078608) : discount the resource files in META-INF // from segment computation. - long inflen = (isMetaInfFile(name)) + long inflen = (inFile.isMetaInfFile()) ? 0L : inFile.getInputLength(); @@ -406,7 +413,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { assert(je.isDirectory() == name.endsWith("/")); - if (isClassFile(name)) { + if (inFile.mustProcess()) { file = readClass(name, bits.getInputStream()); } if (file == null) { @@ -429,7 +436,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { for (InFile inFile : inFiles) { String name = inFile.name; // (5078608) : discount the resource files completely from segmenting - long inflen = (isMetaInfFile(name)) + long inflen = (inFile.isMetaInfFile()) ? 0L : inFile.getInputLength() ; if ((segmentSize += inflen) > segmentLimit) { @@ -447,7 +454,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { if (verbose > 1) Utils.log.fine("Reading " + name); Package.File file = null; - if (isClassFile(name)) { + if (inFile.mustProcess()) { file = readClass(name, strm); if (file == null) { strm.close(); diff --git a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index 3cd12eeac15..177bba66f61 100644 --- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -732,13 +732,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @return a reference to this object. */ public AbstractStringBuilder append(int i) { - if (i == Integer.MIN_VALUE) { - append("-2147483648"); - return this; - } - int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 - : Integer.stringSize(i); - int spaceNeeded = count + appendedLength; + int spaceNeeded = count + Integer.stringSize(i); ensureCapacityInternal(spaceNeeded); if (isLatin1()) { Integer.getChars(i, spaceNeeded, value); @@ -764,13 +758,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @return a reference to this object. */ public AbstractStringBuilder append(long l) { - if (l == Long.MIN_VALUE) { - append("-9223372036854775808"); - return this; - } - int appendedLength = (l < 0) ? Long.stringSize(-l) + 1 - : Long.stringSize(l); - int spaceNeeded = count + appendedLength; + int spaceNeeded = count + Long.stringSize(l); ensureCapacityInternal(spaceNeeded); if (isLatin1()) { Long.getChars(l, spaceNeeded, value); diff --git a/jdk/src/java.base/share/classes/java/lang/Integer.java b/jdk/src/java.base/share/classes/java/lang/Integer.java index e956c3571ff..e34ae9d9395 100644 --- a/jdk/src/java.base/share/classes/java/lang/Integer.java +++ b/jdk/src/java.base/share/classes/java/lang/Integer.java @@ -396,7 +396,7 @@ public final class Integer extends Number implements Comparable { } while (charPos > offset); } - static final char [] DigitTens = { + static final byte[] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', @@ -409,7 +409,7 @@ public final class Integer extends Number implements Comparable { '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', } ; - static final char [] DigitOnes = { + static final byte[] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', @@ -422,21 +422,6 @@ public final class Integer extends Number implements Comparable { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', } ; - // I use the "invariant division by multiplication" trick to - // accelerate Integer.toString. In particular we want to - // avoid division by 10. - // - // The "trick" has roughly the same performance characteristics - // as the "classic" Integer.toString code on a non-JIT VM. - // The trick avoids .rem and .div calls but has a longer code - // path and is thus dominated by dispatch overhead. In the - // JIT case the dispatch overhead doesn't exist and the - // "trick" is considerably faster than the classic code. - // - // RE: Division by Invariant Integers using Multiplication - // T Gralund, P Montgomery - // ACM PLDI 1994 - // /** * Returns a {@code String} object representing the @@ -450,9 +435,7 @@ public final class Integer extends Number implements Comparable { */ @HotSpotIntrinsicCandidate public static String toString(int i) { - if (i == Integer.MIN_VALUE) - return "-2147483648"; - int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); + int size = stringSize(i); if (COMPACT_STRINGS) { byte[] buf = new byte[size]; getChars(i, size, buf); @@ -489,84 +472,105 @@ public final class Integer extends Number implements Comparable { * digit at the specified index (exclusive), and working * backwards from there. * - * Will fail if i == Integer.MIN_VALUE + * @implNote This method converts positive inputs into negative + * values, to cover the Integer.MIN_VALUE case. Converting otherwise + * (negative to positive) will expose -Integer.MIN_VALUE that overflows + * integer. */ static void getChars(int i, int index, byte[] buf) { int q, r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = i < 0; + if (!negative) { i = -i; } // Generate two digits per iteration - while (i >= 65536) { + while (i <= -100) { q = i / 100; - // really: r = i - (q * 100); - r = i - ((q << 6) + (q << 5) + (q << 2)); + r = (q * 100) - i; i = q; - buf [--charPos] = (byte)DigitOnes[r]; - buf [--charPos] = (byte)DigitTens[r]; + buf[--charPos] = DigitOnes[r]; + buf[--charPos] = DigitTens[r]; } - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (;;) { - q = (i * 52429) >>> (16+3); - r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... - buf [--charPos] = (byte)digits [r]; - i = q; - if (i == 0) break; + // We know there are at most two digits left at this point. + q = i / 10; + r = (q * 10) - i; + buf[--charPos] = (byte)('0' + r); + + // Whatever left is the remaining digit. + if (q < 0) { + buf[--charPos] = (byte)('0' - q); } - if (sign != 0) { - buf [--charPos] = (byte)sign; + + if (negative) { + buf[--charPos] = (byte)'-'; } } static void getCharsUTF16(int i, int index, byte[] buf) { int q, r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = (i < 0); + if (!negative) { i = -i; } - // Generate two digits per iteration - while (i >= 65536) { + // Get 2 digits/iteration using ints + while (i <= -100) { q = i / 100; - // really: r = i - (q * 100); - r = i - ((q << 6) + (q << 5) + (q << 2)); + r = (q * 100) - i; i = q; StringUTF16.putChar(buf, --charPos, DigitOnes[r]); StringUTF16.putChar(buf, --charPos, DigitTens[r]); } - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (;;) { - q = (i * 52429) >>> (16+3); - r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... - StringUTF16.putChar(buf, --charPos, Integer.digits[r]); - i = q; - if (i == 0) break; + // We know there are at most two digits left at this point. + q = i / 10; + r = (q * 10) - i; + StringUTF16.putChar(buf, --charPos, '0' + r); + + // Whatever left is the remaining digit. + if (q < 0) { + StringUTF16.putChar(buf, --charPos, '0' - q); } - if (sign != 0) { - StringUTF16.putChar(buf, --charPos, sign); + + if (negative) { + StringUTF16.putChar(buf, --charPos, '-'); } } + // Left here for compatibility reasons, see JDK-8143900. static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; - // Requires positive x + /** + * Returns the string representation size for a given int value. + * + * @param x int value + * @return string size + * + * @implNote There are other ways to compute this: e.g. binary search, + * but values are biased heavily towards zero, and therefore linear search + * wins. The iteration results are also routinely inlined in the generated + * code after loop unrolling. + */ static int stringSize(int x) { - for (int i=0; ; i++) - if (x <= sizeTable[i]) - return i+1; + int d = 1; + if (x >= 0) { + d = 0; + x = -x; + } + int p = -10; + for (int i = 1; i < 10; i++) { + if (x > p) + return i + d; + p = 10 * p; + } + return 10 + d; } /** diff --git a/jdk/src/java.base/share/classes/java/lang/Long.java b/jdk/src/java.base/share/classes/java/lang/Long.java index b68e2c29b7d..d7d232f23b0 100644 --- a/jdk/src/java.base/share/classes/java/lang/Long.java +++ b/jdk/src/java.base/share/classes/java/lang/Long.java @@ -448,9 +448,7 @@ public final class Long extends Number implements Comparable { * @return a string representation of the argument in base 10. */ public static String toString(long i) { - if (i == Long.MIN_VALUE) - return "-9223372036854775808"; - int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); + int size = stringSize(i); if (COMPACT_STRINGS) { byte[] buf = new byte[size]; getChars(i, size, buf); @@ -481,58 +479,59 @@ public final class Long extends Number implements Comparable { } /** - * Places characters representing the integer i into the + * Places characters representing the long i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant * digit at the specified index (exclusive), and working * backwards from there. * - * Will fail if i == Long.MIN_VALUE + * @implNote This method converts positive inputs into negative + * values, to cover the Long.MIN_VALUE case. Converting otherwise + * (negative to positive) will expose -Long.MIN_VALUE that overflows + * long. */ static void getChars(long i, int index, byte[] buf) { long q; int r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = (i < 0); + if (!negative) { i = -i; } // Get 2 digits/iteration using longs until quotient fits into an int - while (i > Integer.MAX_VALUE) { + while (i <= Integer.MIN_VALUE) { q = i / 100; - // really: r = i - (q * 100); - r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); + r = (int)((q * 100) - i); i = q; - buf[--charPos] = (byte)Integer.DigitOnes[r]; - buf[--charPos] = (byte)Integer.DigitTens[r]; + buf[--charPos] = Integer.DigitOnes[r]; + buf[--charPos] = Integer.DigitTens[r]; } // Get 2 digits/iteration using ints int q2; int i2 = (int)i; - while (i2 >= 65536) { + while (i2 <= -100) { q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); + r = (q2 * 100) - i2; i2 = q2; - buf[--charPos] = (byte)Integer.DigitOnes[r]; - buf[--charPos] = (byte)Integer.DigitTens[r]; + buf[--charPos] = Integer.DigitOnes[r]; + buf[--charPos] = Integer.DigitTens[r]; } - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (;;) { - q2 = (i2 * 52429) >>> (16+3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - buf[--charPos] = (byte)Integer.digits[r]; - i2 = q2; - if (i2 == 0) break; + // We know there are at most two digits left at this point. + q2 = i2 / 10; + r = (q2 * 10) - i2; + buf[--charPos] = (byte)('0' + r); + + // Whatever left is the remaining digit. + if (q2 < 0) { + buf[--charPos] = (byte)('0' - q2); } - if (sign != 0) { - buf[--charPos] = (byte)sign; + + if (negative) { + buf[--charPos] = (byte)'-'; } } @@ -540,18 +539,16 @@ public final class Long extends Number implements Comparable { long q; int r; int charPos = index; - char sign = 0; - if (i < 0) { - sign = '-'; + boolean negative = (i < 0); + if (!negative) { i = -i; } // Get 2 digits/iteration using longs until quotient fits into an int - while (i > Integer.MAX_VALUE) { + while (i <= Integer.MIN_VALUE) { q = i / 100; - // really: r = i - (q * 100); - r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); + r = (int)((q * 100) - i); i = q; StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]); StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]); @@ -560,38 +557,53 @@ public final class Long extends Number implements Comparable { // Get 2 digits/iteration using ints int q2; int i2 = (int)i; - while (i2 >= 65536) { + while (i2 <= -100) { q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); + r = (q2 * 100) - i2; i2 = q2; StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]); StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]); } - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (;;) { - q2 = (i2 * 52429) >>> (16+3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - StringUTF16.putChar(buf, --charPos, Integer.digits[r]); - i2 = q2; - if (i2 == 0) break; + // We know there are at most two digits left at this point. + q2 = i2 / 10; + r = (q2 * 10) - i2; + StringUTF16.putChar(buf, --charPos, '0' + r); + + // Whatever left is the remaining digit. + if (q2 < 0) { + StringUTF16.putChar(buf, --charPos, '0' - q2); } - if (sign != 0) { - StringUTF16.putChar(buf, --charPos, sign); + + if (negative) { + StringUTF16.putChar(buf, --charPos, '-'); } } - // Requires positive x + /** + * Returns the string representation size for a given long value. + * + * @param x long value + * @return string size + * + * @implNote There are other ways to compute this: e.g. binary search, + * but values are biased heavily towards zero, and therefore linear search + * wins. The iteration results are also routinely inlined in the generated + * code after loop unrolling. + */ static int stringSize(long x) { - long p = 10; - for (int i=1; i<19; i++) { - if (x < p) - return i; - p = 10*p; + int d = 1; + if (x >= 0) { + d = 0; + x = -x; } - return 19; + long p = -10; + for (int i = 1; i < 19; i++) { + if (x > p) + return i + d; + p = 10 * p; + } + return 19 + d; } /** diff --git a/jdk/src/java.base/share/classes/java/lang/Runtime.java b/jdk/src/java.base/share/classes/java/lang/Runtime.java index e75fcb439cf..668357e7067 100644 --- a/jdk/src/java.base/share/classes/java/lang/Runtime.java +++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java @@ -44,7 +44,7 @@ import sun.reflect.Reflection; */ public class Runtime { - private static Runtime currentRuntime = new Runtime(); + private static final Runtime currentRuntime = new Runtime(); /** * Returns the runtime object associated with the current Java application. diff --git a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java index 65bbe14e34e..9a7dbe73b61 100644 --- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java +++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java @@ -730,7 +730,7 @@ import jdk.internal.HotSpotIntrinsicCandidate; count = fields.get("count", 0); } - protected synchronized void getBytes(byte dst[], int dstBegin, byte coder) { + synchronized void getBytes(byte dst[], int dstBegin, byte coder) { super.getBytes(dst, dstBegin, coder); } } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index 3be1b7ea7df..2db85563d71 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -938,7 +938,7 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray Class arrayElement = arrayType.getComponentType(); MethodType mtype = type(); boolean match = true, fail = false; - for (int i = pos; i < arrayLength; i++) { + for (int i = pos; i < pos + arrayLength; i++) { Class ptype = mtype.parameterType(i); if (ptype != arrayElement) { match = false; diff --git a/jdk/src/java.base/share/classes/java/text/DateFormat.java b/jdk/src/java.base/share/classes/java/text/DateFormat.java index 710e9dd9007..3072dec87b4 100644 --- a/jdk/src/java.base/share/classes/java/text/DateFormat.java +++ b/jdk/src/java.base/share/classes/java/text/DateFormat.java @@ -418,7 +418,7 @@ public abstract class DateFormat extends Format { * index information as described above. * @return A Date parsed from the string. In case of * error, returns null. - * @exception NullPointerException if pos is null. + * @throws NullPointerException if {@code source} or {@code pos} is null. */ public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); diff --git a/jdk/src/java.base/share/classes/java/text/Format.java b/jdk/src/java.base/share/classes/java/text/Format.java index 74fcc37d1bf..f24b4ee0083 100644 --- a/jdk/src/java.base/share/classes/java/text/Format.java +++ b/jdk/src/java.base/share/classes/java/text/Format.java @@ -225,7 +225,7 @@ public abstract class Format implements Serializable, Cloneable { * index information as described above. * @return An Object parsed from the string. In case of * error, returns null. - * @exception NullPointerException if pos is null. + * @throws NullPointerException if {@code source} or {@code pos} is null. */ public abstract Object parseObject (String source, ParsePosition pos); @@ -237,6 +237,7 @@ public abstract class Format implements Serializable, Cloneable { * @return An Object parsed from the string. * @exception ParseException if the beginning of the specified string * cannot be parsed. + * @throws NullPointerException if {@code source} is null. */ public Object parseObject(String source) throws ParseException { ParsePosition pos = new ParsePosition(0); diff --git a/jdk/src/java.base/share/classes/java/text/MessageFormat.java b/jdk/src/java.base/share/classes/java/text/MessageFormat.java index dc5da063722..f907f4f9bb7 100644 --- a/jdk/src/java.base/share/classes/java/text/MessageFormat.java +++ b/jdk/src/java.base/share/classes/java/text/MessageFormat.java @@ -1068,7 +1068,7 @@ public class MessageFormat extends Format { * index information as described above. * @return An Object array parsed from the string. In case of * error, returns null. - * @exception NullPointerException if pos is null. + * @throws NullPointerException if {@code source} or {@code pos} is null. */ public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); diff --git a/jdk/src/java.base/share/classes/java/text/NumberFormat.java b/jdk/src/java.base/share/classes/java/text/NumberFormat.java index 1431187e530..68f30d12563 100644 --- a/jdk/src/java.base/share/classes/java/text/NumberFormat.java +++ b/jdk/src/java.base/share/classes/java/text/NumberFormat.java @@ -271,7 +271,7 @@ public abstract class NumberFormat extends Format { * index information as described above. * @return A Number parsed from the string. In case of * error, returns null. - * @exception NullPointerException if pos is null. + * @throws NullPointerException if {@code source} or {@code pos} is null. */ @Override public final Object parseObject(String source, ParsePosition pos) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index b2c2d2aa701..87f379abbc6 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -596,7 +596,16 @@ public class ConcurrentHashMap extends AbstractMap /** Number of CPUS, to place bounds on some sizings */ static final int NCPU = Runtime.getRuntime().availableProcessors(); - /** For serialization compatibility. */ + /** + * Serialized pseudo-fields, provided only for jdk7 compatibility. + * @serialField segments Segment[] + * The segments, each of which is a specialized hash table. + * @serialField segmentMask int + * Mask value for indexing into segments. The upper bits of a + * key's hash code are used to choose the segment. + * @serialField segmentShift int + * Shift value for indexing within segments. + */ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("segments", Segment[].class), new ObjectStreamField("segmentMask", Integer.TYPE), @@ -1382,8 +1391,8 @@ public class ConcurrentHashMap extends AbstractMap * @param s the stream * @throws java.io.IOException if an I/O error occurs * @serialData - * the key (Object) and value (Object) - * for each key-value mapping, followed by a null pair. + * the serialized fields, followed by the key (Object) and value + * (Object) for each key-value mapping, followed by a null pair. * The key-value mappings are emitted in no particular order. */ private void writeObject(java.io.ObjectOutputStream s) @@ -1419,7 +1428,6 @@ public class ConcurrentHashMap extends AbstractMap } s.writeObject(null); s.writeObject(null); - segments = null; // throw away } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java index 24c154e2f05..e863632d85a 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java @@ -185,7 +185,7 @@ package java.util.concurrent; * } * }} * - * As a further improvement, notice that the left task need not even exist. + * As a further optimization, notice that the left task need not even exist. * Instead of creating a new one, we can iterate using the original task, * and add a pending count for each fork. Additionally, because no task * in this tree implements an {@link #onCompletion(CountedCompleter)} method, @@ -208,7 +208,7 @@ package java.util.concurrent; * } * }} * - * Additional improvements of such classes might entail precomputing + * Additional optimizations of such classes might entail precomputing * pending counts so that they can be established in constructors, * specializing classes for leaf steps, subdividing by say, four, * instead of two per iteration, and using an adaptive threshold @@ -260,9 +260,9 @@ package java.util.concurrent; * }} * * In this example, as well as others in which tasks have no other - * effects except to compareAndSet a common result, the trailing - * unconditional invocation of {@code tryComplete} could be made - * conditional ({@code if (result.get() == null) tryComplete();}) + * effects except to {@code compareAndSet} a common result, the + * trailing unconditional invocation of {@code tryComplete} could be + * made conditional ({@code if (result.get() == null) tryComplete();}) * because no further bookkeeping is required to manage completions * once the root task completes. * @@ -624,7 +624,7 @@ public abstract class CountedCompleter extends ForkJoinTask { * any one (versus all) of several subtask results are obtained. * However, in the common (and recommended) case in which {@code * setRawResult} is not overridden, this effect can be obtained - * more simply using {@code quietlyCompleteRoot();}. + * more simply using {@link #quietlyCompleteRoot()}. * * @param rawResult the raw result */ @@ -639,9 +639,9 @@ public abstract class CountedCompleter extends ForkJoinTask { /** * If this task's pending count is zero, returns this task; - * otherwise decrements its pending count and returns {@code - * null}. This method is designed to be used with {@link - * #nextComplete} in completion traversal loops. + * otherwise decrements its pending count and returns {@code null}. + * This method is designed to be used with {@link #nextComplete} in + * completion traversal loops. * * @return this task, if pending count was zero, else {@code null} */ diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java index e4e91a1a187..583ffa83b4d 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java @@ -703,7 +703,8 @@ public class ForkJoinPool extends AbstractExecutorService { * Returns a new worker thread operating in the given pool. * * @param pool the pool this thread works in - * @return the new worker thread + * @return the new worker thread, or {@code null} if the request + * to create a thread is rejected * @throws NullPointerException if the pool is null */ public ForkJoinWorkerThread newThread(ForkJoinPool pool); @@ -1053,7 +1054,7 @@ public class ForkJoinPool extends AbstractExecutorService { } /** - * Shared version of pop. + * Shared version of tryUnpush. */ final boolean trySharedUnpush(ForkJoinTask task) { boolean popped = false; @@ -1064,7 +1065,8 @@ public class ForkJoinPool extends AbstractExecutorService { ForkJoinTask t = (ForkJoinTask) U.getObject(a, offset); if (t == task && U.compareAndSwapInt(this, QLOCK, 0, 1)) { - if (U.compareAndSwapObject(a, offset, task, null)) { + if (top == s + 1 && array == a && + U.compareAndSwapObject(a, offset, task, null)) { popped = true; top = s; } @@ -1250,12 +1252,14 @@ public class ForkJoinPool extends AbstractExecutorService { for (CountedCompleter r = t;;) { if (r == task) { if ((mode & IS_OWNED) == 0) { - boolean popped; + boolean popped = false; if (U.compareAndSwapInt(this, QLOCK, 0, 1)) { - if (popped = + if (top == s && array == a && U.compareAndSwapObject(a, offset, - t, null)) + t, null)) { + popped = true; top = s - 1; + } U.putOrderedInt(this, QLOCK, 0); if (popped) return t; diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java index 2839aa6eafd..5ab89f89957 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -132,11 +132,10 @@ public class ScheduledThreadPoolExecutor /* * This class specializes ThreadPoolExecutor implementation by * - * 1. Using a custom task type, ScheduledFutureTask for - * tasks, even those that don't require scheduling (i.e., - * those submitted using ExecutorService execute, not - * ScheduledExecutorService methods) which are treated as - * delayed tasks with a delay of zero. + * 1. Using a custom task type ScheduledFutureTask, even for tasks + * that don't require scheduling because they are submitted + * using ExecutorService rather than ScheduledExecutorService + * methods, which are treated as tasks with a delay of zero. * * 2. Using a custom queue (DelayedWorkQueue), a variant of * unbounded DelayQueue. The lack of capacity constraint and @@ -177,24 +176,17 @@ public class ScheduledThreadPoolExecutor */ private static final AtomicLong sequencer = new AtomicLong(); - /** - * Returns current nanosecond time. - */ - static final long now() { - return System.nanoTime(); - } - private class ScheduledFutureTask extends FutureTask implements RunnableScheduledFuture { /** Sequence number to break ties FIFO */ private final long sequenceNumber; - /** The time the task is enabled to execute in nanoTime units */ + /** The nanoTime-based time when the task is enabled to execute. */ private volatile long time; /** - * Period in nanoseconds for repeating tasks. + * Period for repeating tasks, in nanoseconds. * A positive value indicates fixed-rate execution. * A negative value indicates fixed-delay execution. * A value of 0 indicates a non-repeating (one-shot) task. @@ -244,7 +236,7 @@ public class ScheduledThreadPoolExecutor } public long getDelay(TimeUnit unit) { - return unit.convert(time - now(), NANOSECONDS); + return unit.convert(time - System.nanoTime(), NANOSECONDS); } public int compareTo(Delayed other) { @@ -287,6 +279,9 @@ public class ScheduledThreadPoolExecutor } public boolean cancel(boolean mayInterruptIfRunning) { + // The racy read of heapIndex below is benign: + // if heapIndex < 0, then OOTA guarantees that we have surely + // been removed; else we recheck under lock in remove() boolean cancelled = super.cancel(mayInterruptIfRunning); if (cancelled && removeOnCancel && heapIndex >= 0) remove(this); @@ -528,7 +523,7 @@ public class ScheduledThreadPoolExecutor * Returns the nanoTime-based trigger time of a delayed action. */ long triggerTime(long delay) { - return now() + + return System.nanoTime() + ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay)); } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index 1ec99ccc42f..d14454228f8 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -365,12 +365,17 @@ public abstract class AtomicIntegerFieldUpdater { /** * Standard hotspot implementation using intrinsics. */ - private static class AtomicIntegerFieldUpdaterImpl - extends AtomicIntegerFieldUpdater { + private static final class AtomicIntegerFieldUpdaterImpl + extends AtomicIntegerFieldUpdater { private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); private final long offset; - private final Class tclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class cclass; + /** class holding the field */ + private final Class tclass; AtomicIntegerFieldUpdaterImpl(final Class tclass, final String fieldName, @@ -399,17 +404,15 @@ public abstract class AtomicIntegerFieldUpdater { throw new RuntimeException(ex); } - Class fieldt = field.getType(); - if (fieldt != int.class) + if (field.getType() != int.class) throw new IllegalArgumentException("Must be integer type"); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; + this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; this.tclass = tclass; - offset = U.objectFieldOffset(field); + this.offset = U.objectFieldOffset(field); } /** @@ -428,81 +431,87 @@ public abstract class AtomicIntegerFieldUpdater { return false; } - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) + /** + * Checks that target argument is instance of cclass. On + * failure, throws cause. + */ + private final void accessCheck(T obj) { + if (!cclass.isInstance(obj)) + throwAccessCheckException(obj); + } + + /** + * Throws access exception if accessCheck failed due to + * protected access, else ClassCastException. + */ + private final void throwAccessCheckException(T obj) { + if (cclass == tclass) throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + else + throw new RuntimeException( + new IllegalAccessException( + "Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName())); } - public boolean compareAndSet(T obj, int expect, int update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final boolean compareAndSet(T obj, int expect, int update) { + accessCheck(obj); return U.compareAndSwapInt(obj, offset, expect, update); } - public boolean weakCompareAndSet(T obj, int expect, int update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final boolean weakCompareAndSet(T obj, int expect, int update) { + accessCheck(obj); return U.compareAndSwapInt(obj, offset, expect, update); } - public void set(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final void set(T obj, int newValue) { + accessCheck(obj); U.putIntVolatile(obj, offset, newValue); } - public void lazySet(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final void lazySet(T obj, int newValue) { + accessCheck(obj); U.putOrderedInt(obj, offset, newValue); } public final int get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + accessCheck(obj); return U.getIntVolatile(obj, offset); } - public int getAndSet(T obj, int newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final int getAndSet(T obj, int newValue) { + accessCheck(obj); return U.getAndSetInt(obj, offset, newValue); } - public int getAndIncrement(T obj) { - return getAndAdd(obj, 1); - } - - public int getAndDecrement(T obj) { - return getAndAdd(obj, -1); - } - - public int getAndAdd(T obj, int delta) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final int getAndAdd(T obj, int delta) { + accessCheck(obj); return U.getAndAddInt(obj, offset, delta); } - public int incrementAndGet(T obj) { + public final int getAndIncrement(T obj) { + return getAndAdd(obj, 1); + } + + public final int getAndDecrement(T obj) { + return getAndAdd(obj, -1); + } + + public final int incrementAndGet(T obj) { return getAndAdd(obj, 1) + 1; } - public int decrementAndGet(T obj) { + public final int decrementAndGet(T obj) { return getAndAdd(obj, -1) - 1; } - public int addAndGet(T obj, int delta) { + public final int addAndGet(T obj, int delta) { return getAndAdd(obj, delta) + delta; } - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } } } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index 870a311aebf..dccca9e15b2 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -365,11 +365,16 @@ public abstract class AtomicLongFieldUpdater { return next; } - private static class CASUpdater extends AtomicLongFieldUpdater { + private static final class CASUpdater extends AtomicLongFieldUpdater { private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); private final long offset; - private final Class tclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class cclass; + /** class holding the field */ + private final Class tclass; CASUpdater(final Class tclass, final String fieldName, final Class caller) { @@ -397,103 +402,110 @@ public abstract class AtomicLongFieldUpdater { throw new RuntimeException(ex); } - Class fieldt = field.getType(); - if (fieldt != long.class) + if (field.getType() != long.class) throw new IllegalArgumentException("Must be long type"); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; + this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; this.tclass = tclass; - offset = U.objectFieldOffset(field); + this.offset = U.objectFieldOffset(field); } - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) + /** + * Checks that target argument is instance of cclass. On + * failure, throws cause. + */ + private final void accessCheck(T obj) { + if (!cclass.isInstance(obj)) + throwAccessCheckException(obj); + } + + /** + * Throws access exception if accessCheck failed due to + * protected access, else ClassCastException. + */ + private final void throwAccessCheckException(T obj) { + if (cclass == tclass) throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + else + throw new RuntimeException( + new IllegalAccessException( + "Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName())); } - public boolean compareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final boolean compareAndSet(T obj, long expect, long update) { + accessCheck(obj); return U.compareAndSwapLong(obj, offset, expect, update); } - public boolean weakCompareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final boolean weakCompareAndSet(T obj, long expect, long update) { + accessCheck(obj); return U.compareAndSwapLong(obj, offset, expect, update); } - public void set(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final void set(T obj, long newValue) { + accessCheck(obj); U.putLongVolatile(obj, offset, newValue); } - public void lazySet(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final void lazySet(T obj, long newValue) { + accessCheck(obj); U.putOrderedLong(obj, offset, newValue); } - public long get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final long get(T obj) { + accessCheck(obj); return U.getLongVolatile(obj, offset); } - public long getAndSet(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final long getAndSet(T obj, long newValue) { + accessCheck(obj); return U.getAndSetLong(obj, offset, newValue); } - public long getAndIncrement(T obj) { - return getAndAdd(obj, 1); - } - - public long getAndDecrement(T obj) { - return getAndAdd(obj, -1); - } - - public long getAndAdd(T obj, long delta) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final long getAndAdd(T obj, long delta) { + accessCheck(obj); return U.getAndAddLong(obj, offset, delta); } - public long incrementAndGet(T obj) { + public final long getAndIncrement(T obj) { + return getAndAdd(obj, 1); + } + + public final long getAndDecrement(T obj) { + return getAndAdd(obj, -1); + } + + public final long incrementAndGet(T obj) { return getAndAdd(obj, 1) + 1; } - public long decrementAndGet(T obj) { + public final long decrementAndGet(T obj) { return getAndAdd(obj, -1) - 1; } - public long addAndGet(T obj, long delta) { + public final long addAndGet(T obj, long delta) { return getAndAdd(obj, delta) + delta; } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } } - - private static class LockedUpdater extends AtomicLongFieldUpdater { + private static final class LockedUpdater extends AtomicLongFieldUpdater { private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); private final long offset; - private final Class tclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class cclass; + /** class holding the field */ + private final Class tclass; LockedUpdater(final Class tclass, final String fieldName, final Class caller) { @@ -521,28 +533,46 @@ public abstract class AtomicLongFieldUpdater { throw new RuntimeException(ex); } - Class fieldt = field.getType(); - if (fieldt != long.class) + if (field.getType() != long.class) throw new IllegalArgumentException("Must be long type"); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; + this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; this.tclass = tclass; - offset = U.objectFieldOffset(field); + this.offset = U.objectFieldOffset(field); } - private void fullCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + /** + * Checks that target argument is instance of cclass. On + * failure, throws cause. + */ + private final void accessCheck(T obj) { + if (!cclass.isInstance(obj)) + throw accessCheckException(obj); } - public boolean compareAndSet(T obj, long expect, long update) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + /** + * Returns access exception if accessCheck failed due to + * protected access, else ClassCastException. + */ + private final RuntimeException accessCheckException(T obj) { + if (cclass == tclass) + return new ClassCastException(); + else + return new RuntimeException( + new IllegalAccessException( + "Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName())); + } + + public final boolean compareAndSet(T obj, long expect, long update) { + accessCheck(obj); synchronized (this) { long v = U.getLong(obj, offset); if (v != expect) @@ -552,42 +582,27 @@ public abstract class AtomicLongFieldUpdater { } } - public boolean weakCompareAndSet(T obj, long expect, long update) { + public final boolean weakCompareAndSet(T obj, long expect, long update) { return compareAndSet(obj, expect, update); } - public void set(T obj, long newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final void set(T obj, long newValue) { + accessCheck(obj); synchronized (this) { U.putLong(obj, offset, newValue); } } - public void lazySet(T obj, long newValue) { + public final void lazySet(T obj, long newValue) { set(obj, newValue); } - public long get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); + public final long get(T obj) { + accessCheck(obj); synchronized (this) { return U.getLong(obj, offset); } } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index aa89aead91b..f9e4989cbbe 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -286,9 +286,15 @@ public abstract class AtomicReferenceFieldUpdater { extends AtomicReferenceFieldUpdater { private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); private final long offset; - private final Class tclass; - private final Class vclass; + /** + * if field is protected, the subclass constructing updater, else + * the same as tclass + */ private final Class cclass; + /** class holding the field */ + private final Class tclass; + /** field value type */ + private final Class vclass; /* * Internal type checks within all update methods contain @@ -340,14 +346,10 @@ public abstract class AtomicReferenceFieldUpdater { if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type"); - this.cclass = (Modifier.isProtected(modifiers) && - caller != tclass) ? caller : null; + this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; this.tclass = tclass; - if (vclass == Object.class) - this.vclass = null; - else - this.vclass = vclass; - offset = U.objectFieldOffset(field); + this.vclass = vclass; + this.offset = U.objectFieldOffset(field); } /** @@ -366,83 +368,78 @@ public abstract class AtomicReferenceFieldUpdater { return false; } - void targetCheck(T obj) { - if (!tclass.isInstance(obj)) - throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + /** + * Checks that target argument is instance of cclass. On + * failure, throws cause. + */ + private final void accessCheck(T obj) { + if (!cclass.isInstance(obj)) + throwAccessCheckException(obj); } - void updateCheck(T obj, V update) { - if (!tclass.isInstance(obj) || - (update != null && vclass != null && !vclass.isInstance(update))) + /** + * Throws access exception if accessCheck failed due to + * protected access, else ClassCastException. + */ + private final void throwAccessCheckException(T obj) { + if (cclass == tclass) throw new ClassCastException(); - if (cclass != null) - ensureProtectedAccess(obj); + else + throw new RuntimeException( + new IllegalAccessException( + "Class " + + cclass.getName() + + " can not access a protected member of class " + + tclass.getName() + + " using an instance of " + + obj.getClass().getName())); } - public boolean compareAndSet(T obj, V expect, V update) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (update != null && vclass != null && - vclass != update.getClass())) - updateCheck(obj, update); + private final void valueCheck(V v) { + if (v != null && !(vclass.isInstance(v))) + throwCCE(); + } + + static void throwCCE() { + throw new ClassCastException(); + } + + public final boolean compareAndSet(T obj, V expect, V update) { + accessCheck(obj); + valueCheck(update); return U.compareAndSwapObject(obj, offset, expect, update); } - public boolean weakCompareAndSet(T obj, V expect, V update) { + public final boolean weakCompareAndSet(T obj, V expect, V update) { // same implementation as strong form for now - if (obj == null || obj.getClass() != tclass || cclass != null || - (update != null && vclass != null && - vclass != update.getClass())) - updateCheck(obj, update); + accessCheck(obj); + valueCheck(update); return U.compareAndSwapObject(obj, offset, expect, update); } - public void set(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); + public final void set(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); U.putObjectVolatile(obj, offset, newValue); } - public void lazySet(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); + public final void lazySet(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); U.putOrderedObject(obj, offset, newValue); } @SuppressWarnings("unchecked") - public V get(T obj) { - if (obj == null || obj.getClass() != tclass || cclass != null) - targetCheck(obj); + public final V get(T obj) { + accessCheck(obj); return (V)U.getObjectVolatile(obj, offset); } @SuppressWarnings("unchecked") - public V getAndSet(T obj, V newValue) { - if (obj == null || obj.getClass() != tclass || cclass != null || - (newValue != null && vclass != null && - vclass != newValue.getClass())) - updateCheck(obj, newValue); + public final V getAndSet(T obj, V newValue) { + accessCheck(obj); + valueCheck(newValue); return (V)U.getAndSetObject(obj, offset, newValue); } - - private void ensureProtectedAccess(T obj) { - if (cclass.isInstance(obj)) { - return; - } - throw new RuntimeException( - new IllegalAccessException("Class " + - cclass.getName() + - " can not access a protected member of class " + - tclass.getName() + - " using an instance of " + - obj.getClass().getName() - ) - ); - } } } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 06f50846234..cffab6b1286 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -922,7 +922,7 @@ public abstract class AbstractQueuedLongSynchronizer /** * Queries whether any threads have ever contended to acquire this - * synchronizer; that is if an acquire method has ever blocked. + * synchronizer; that is, if an acquire method has ever blocked. * *

In this implementation, this operation returns in * constant time. @@ -977,13 +977,11 @@ public abstract class AbstractQueuedLongSynchronizer * guaranteeing termination. */ - Node t = tail; Thread firstThread = null; - while (t != null && t != head) { - Thread tt = t.thread; - if (tt != null) - firstThread = tt; - t = t.prev; + for (Node p = tail; p != null && p != head; p = p.prev) { + Thread t = p.thread; + if (t != null) + firstThread = t; } return firstThread; } @@ -1031,8 +1029,8 @@ public abstract class AbstractQueuedLongSynchronizer *

An invocation of this method is equivalent to (but may be * more efficient than): *

 {@code
-     * getFirstQueuedThread() != Thread.currentThread() &&
-     * hasQueuedThreads()}
+ * getFirstQueuedThread() != Thread.currentThread() + * && hasQueuedThreads()} * *

Note that because cancellations due to interrupts and * timeouts may occur at any time, a {@code true} return does not @@ -1635,7 +1633,7 @@ public abstract class AbstractQueuedLongSynchronizer transferAfterCancelledWait(node); break; } - if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD) + if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; @@ -1723,7 +1721,7 @@ public abstract class AbstractQueuedLongSynchronizer timedout = transferAfterCancelledWait(node); break; } - if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD) + if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; @@ -1847,8 +1845,9 @@ public abstract class AbstractQueuedLongSynchronizer * Initializes head and tail fields on first contention. */ private final void initializeSyncQueue() { - if (U.compareAndSwapObject(this, HEAD, null, new Node())) - tail = head; + Node h; + if (U.compareAndSwapObject(this, HEAD, null, (h = new Node()))) + tail = h; } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 3d604a63214..5a79376d340 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -1388,7 +1388,7 @@ public abstract class AbstractQueuedSynchronizer /** * Queries whether any threads have ever contended to acquire this - * synchronizer; that is if an acquire method has ever blocked. + * synchronizer; that is, if an acquire method has ever blocked. * *

In this implementation, this operation returns in * constant time. @@ -1443,13 +1443,11 @@ public abstract class AbstractQueuedSynchronizer * guaranteeing termination. */ - Node t = tail; Thread firstThread = null; - while (t != null && t != head) { - Thread tt = t.thread; - if (tt != null) - firstThread = tt; - t = t.prev; + for (Node p = tail; p != null && p != head; p = p.prev) { + Thread t = p.thread; + if (t != null) + firstThread = t; } return firstThread; } @@ -1497,8 +1495,8 @@ public abstract class AbstractQueuedSynchronizer *

An invocation of this method is equivalent to (but may be * more efficient than): *

 {@code
-     * getFirstQueuedThread() != Thread.currentThread() &&
-     * hasQueuedThreads()}
+ * getFirstQueuedThread() != Thread.currentThread() + * && hasQueuedThreads()} * *

Note that because cancellations due to interrupts and * timeouts may occur at any time, a {@code true} return does not @@ -2099,7 +2097,7 @@ public abstract class AbstractQueuedSynchronizer transferAfterCancelledWait(node); break; } - if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD) + if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; @@ -2187,7 +2185,7 @@ public abstract class AbstractQueuedSynchronizer timedout = transferAfterCancelledWait(node); break; } - if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD) + if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD) LockSupport.parkNanos(this, nanosTimeout); if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) break; @@ -2311,8 +2309,9 @@ public abstract class AbstractQueuedSynchronizer * Initializes head and tail fields on first contention. */ private final void initializeSyncQueue() { - if (U.compareAndSwapObject(this, HEAD, null, new Node())) - tail = head; + Node h; + if (U.compareAndSwapObject(this, HEAD, null, (h = new Node()))) + tail = h; } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java b/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java index a82d2d9f736..c219ca55c7b 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java @@ -81,12 +81,17 @@ package java.util.concurrent.locks; * method is designed for use only in constructions of the form: * *

 {@code
- * while (!canProceed()) { ... LockSupport.park(this); }}
+ * while (!canProceed()) { + * // ensure request to unpark is visible to other threads + * ... + * LockSupport.park(this); + * }} * - * where neither {@code canProceed} nor any other actions prior to the - * call to {@code park} entail locking or blocking. Because only one - * permit is associated with each thread, any intermediary uses of - * {@code park} could interfere with its intended effects. + * where no actions by the thread publishing a request to unpark, + * prior to the call to {@code park}, entail locking or blocking. + * Because only one permit is associated with each thread, any + * intermediary uses of {@code park}, including implicitly via class + * loading, could lead to an unresponsive thread (a "lost unpark"). * *

Sample Usage. Here is a sketch of a first-in-first-out * non-reentrant lock class: @@ -98,26 +103,33 @@ package java.util.concurrent.locks; * * public void lock() { * boolean wasInterrupted = false; - * Thread current = Thread.currentThread(); - * waiters.add(current); + * // publish current thread for unparkers + * waiters.add(Thread.currentThread()); * * // Block while not first in queue or cannot acquire lock - * while (waiters.peek() != current || + * while (waiters.peek() != Thread.currentThread() || * !locked.compareAndSet(false, true)) { * LockSupport.park(this); - * if (Thread.interrupted()) // ignore interrupts while waiting + * // ignore interrupts while waiting + * if (Thread.interrupted()) * wasInterrupted = true; * } * * waiters.remove(); - * if (wasInterrupted) // reassert interrupt status on exit - * current.interrupt(); + * // ensure correct interrupt status on return + * if (wasInterrupted) + * Thread.currentThread().interrupt(); * } * * public void unlock() { * locked.set(false); * LockSupport.unpark(waiters.peek()); * } + * + * static { + * // Reduce the risk of "lost unpark" due to classloading + * Class ensureLoaded = LockSupport.class; + * } * }} */ public class LockSupport { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index a2c627aed3b..3f39da71270 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -188,9 +188,9 @@ import java.util.concurrent.TimeUnit; * try { return m.get(key); } * finally { r.unlock(); } * } - * public String[] allKeys() { + * public List allKeys() { * r.lock(); - * try { return m.keySet().toArray(); } + * try { return new ArrayList<>(m.keySet()); } * finally { r.unlock(); } * } * public Data put(String key, Data value) { diff --git a/jdk/src/java.base/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java b/jdk/src/java.base/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java new file mode 100644 index 00000000000..866d8d4c6bb --- /dev/null +++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.nio.ch; + +import java.nio.channels.spi.SelectorProvider; + +/** + * Creates this platform's default SelectorProvider + */ + +public class DefaultSelectorProvider { + + /** + * Prevent instantiation. + */ + private DefaultSelectorProvider() { } + + /** + * Returns the default SelectorProvider. + */ + public static SelectorProvider create() { + return new sun.nio.ch.DevPollSelectorProvider(); + } + +} diff --git a/jdk/src/java.sql/share/classes/java/sql/Connection.java b/jdk/src/java.sql/share/classes/java/sql/Connection.java index 40aa3de0730..36c61c930d2 100644 --- a/jdk/src/java.sql/share/classes/java/sql/Connection.java +++ b/jdk/src/java.sql/share/classes/java/sql/Connection.java @@ -1587,4 +1587,119 @@ throws SQLException; default void endRequest() throws SQLException { // Default method takes no action } + + /** + * Sets and validates the sharding keys for this connection. + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * + * @apiNote + * This method validates that the sharding keys are valid for the + * {@code Connection}. The timeout value indicates how long the driver + * should wait for the {@code Connection} to verify that the sharding key + * is valid before {@code setShardingKeyIfValid} returns false. + * @param shardingKey the sharding key to be validated against this connection + * @param superShardingKey the super sharding key to be validated against this + * connection. The super sharding key may be {@code null}. + * @param timeout time in seconds before which the validation process is expected to + * be completed, otherwise the validation process is aborted. A value of 0 indicates + * the validation process will not time out. + * @return true if the connection is valid and the sharding keys are valid + * and set on this connection; false if the sharding keys are not valid or + * the timeout period expires before the operation completes. + * @throws SQLException if an error occurs while performing this validation; + * the {@code shardingkey} is {@code null}; a {@code superSharedingKey} is specified + * without a {@code shardingKey}; + * this method is called on a closed {@code connection}; or + * the {@code timeout} value is less than 0. + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default boolean setShardingKeyIfValid(ShardingKey shardingKey, + ShardingKey superShardingKey, int timeout) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented"); + } + + /** + * Sets and validates the sharding key for this connection. + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * @apiNote + * This method validates that the sharding key is valid for the + * {@code Connection}. The timeout value indicates how long the driver + * should wait for the {@code Connection} to verify that the sharding key + * is valid before {@code setShardingKeyIfValid} returns false. + * @param shardingKey the sharding key to be validated against this connection + * @param timeout time in seconds before which the validation process is expected to + * be completed,else the validation process is aborted. A value of 0 indicates + * the validation process will not time out. + * @return true if the connection is valid and the sharding key is valid to be + * set on this connection; false if the sharding key is not valid or + * the timeout period expires before the operation completes. + * @throws SQLException if there is an error while performing this validation; + * this method is called on a closed {@code connection}; the {@code shardingkey} + * is {@code null}; or the {@code timeout} value is less than 0. + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented"); + } + + /** + * Specifies a shardingKey and superShardingKey to use with this Connection + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * @apiNote + * This method sets the specified sharding keys but does not require a + * round trip to the database to validate that the sharding keys are valid + * for the {@code Connection}. + * @param shardingKey the sharding key to set on this connection. + * @param superShardingKey the super sharding key to set on this connection. + * The super sharding key may be {@code null} + * @throws SQLException if an error occurs setting the sharding keys; + * this method is called on a closed {@code connection}; + * the {@code shardingkey} is {@code null}; or + * a {@code superSharedingKey} is specified without a {@code shardingKey} + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKey not implemented"); + } + + /** + * Specifies a shardingKey to use with this Connection + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * @apiNote + * This method sets the specified sharding key but does not require a + * round trip to the database to validate that the sharding key is valid + * for the {@code Connection}. + * @param shardingKey the sharding key to set on this connection. + * @throws SQLException if an error occurs setting the sharding key; + * this method is called on a closed {@code connection}; or the + * {@code shardkingKey} is {@code null} + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default void setShardingKey(ShardingKey shardingKey) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKey not implemented"); + } } diff --git a/jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java b/jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java new file mode 100644 index 00000000000..9025814a181 --- /dev/null +++ b/jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.sql; + +/** + * A builder created from a {@code DataSource} object, + * used to establish a connection to the database that the + * {@code data source} object represents. The connection + * properties that were specified for the {@code data source} are used as the + * default values by the {@code ConnectionBuilder}. + *

The following example illustrates the use of {@code ConnectionBuilder} + * to create a {@link Connection}: + * + *

{@code
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey superShardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ *                           .build();
+ *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ *                           .build();
+ *     Connection con = ds.createConnectionBuilder()
+ *                       .user("rafa")
+ *                       .password("tennis")
+ *                       .setShardingKey(shardingKey)
+ *                       .setSuperShardingKey(superShardingKey)
+ *                       .build();
+ * }
+ * + * @since 1.9 + * + */ +public interface ConnectionBuilder { + + /** + * Specifies the username to be used when creating a connection + * + * @param username the database user on whose behalf the connection is being + * made + * @return the same {@code ConnectionBuilder} instance + */ + ConnectionBuilder user(String username); + + /** + * Specifies the password to be used when creating a connection + * + * @param password the password to use for this connection. May be {@code null} + * @return the same {@code ConnectionBuilder} instance + */ + ConnectionBuilder password(String password); + + /** + * Specifies a {@code shardingKey} to be used when creating a connection + * + * @param shardingKey the ShardingKey. May be {@code null} + * @return the same {@code ConnectionBuilder} instance + * @see ShardingKey + * @see ShardingKeyBuilder + */ + ConnectionBuilder shardingKey(ShardingKey shardingKey); + + /** + * Specifies a {@code superShardingKey} to be used when creating a connection + * + * @param superShardingKey the SuperShardingKey. May be {@code null} + * @return the same {@code ConnectionBuilder} instance + * @see ShardingKey + * @see ShardingKeyBuilder + */ + ConnectionBuilder superShardingKey(ShardingKey superShardingKey); + + /** + * Returns an instance of the object defined by this builder. + * + * @return The built object + * @throws java.sql.SQLException If an error occurs building the object + */ + Connection build() throws SQLException; +} diff --git a/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java b/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java index 937e58eb6c7..6c0e0bb782f 100644 --- a/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java +++ b/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, 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 @@ -3684,4 +3684,19 @@ public interface DatabaseMetaData extends Wrapper { return false; } + // JDBC 4.3 + + /** + * Retrieves whether this database supports sharding. + * @implSpec + * The default implementation will return {@code false} + * + * @return {@code true} if this database supports sharding; + * {@code false} otherwise + * @exception SQLException if a database access error occurs + * @since 1.9 + */ + default boolean supportsSharding() throws SQLException { + return false; + } } diff --git a/jdk/src/java.sql/share/classes/java/sql/ShardingKey.java b/jdk/src/java.sql/share/classes/java/sql/ShardingKey.java new file mode 100644 index 00000000000..6dce0b27d52 --- /dev/null +++ b/jdk/src/java.sql/share/classes/java/sql/ShardingKey.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.sql; + +/** + * Interface used to indicate that this object represents a Sharding Key. A + * {@code ShardingKey} instance is only guaranteed to be compatible with the + * data source instance that it was derived from. A {@code ShardingKey} is + * created using {@link ShardingKeyBuilder}. + *

+ * The following example illustrates the use of {@link ShardingKeyBuilder} to + * create a {@code ShardingKey}: + *

+ * {@code
+ *
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("abc", JDBCType.VARCHAR)
+ *                           .subkey(94002, JDBCType.INTEGER)
+ *                           .build();
+ * }
+ * 
+ *

+ * + * A {@code ShardingKey} may also be used for specifying a + * {@code superShardingKey}. Databases that support composite Sharding may use a + * {@code superShardingKey} to specify a additional level of partitioning within + * the Shard. + *

+ * The following example illustrates the use of {@link ShardingKeyBuilder} to + * create a {@code superShardingKey} for an eastern region with a + * {@code ShardingKey} specified for the Pittsburgh branch office: + *

+ * {@code
+ *
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey superShardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ *                           .build();
+ *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ *                           .build();
+ *     Connection con = ds.createConnectionBuilder()
+ *                           .superShardingKey(superShardingKey)
+ *                           .shardingKey(shardingKey)
+ *                           .build();
+ * }
+ * 
+ * + * @since 1.9 + */ +public interface ShardingKey { + +} diff --git a/jdk/src/java.sql/share/classes/java/sql/ShardingKeyBuilder.java b/jdk/src/java.sql/share/classes/java/sql/ShardingKeyBuilder.java new file mode 100644 index 00000000000..6cf58d5e35d --- /dev/null +++ b/jdk/src/java.sql/share/classes/java/sql/ShardingKeyBuilder.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.sql; + +/** + * A builder created from a {@code DataSource} or {@code XADataSource} object, + * used to create a {@link ShardingKey} with sub-keys of supported data types. + * Implementations must + * support JDBCType.VARCHAR and may also support additional data types. + *

+ * The following example illustrates the use of {@code ShardingKeyBuilder} to + * create a {@link ShardingKey}: + *

+ * {@code
+ *
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("abc", JDBCType.VARCHAR)
+ *                           .subkey(94002, JDBCType.INTEGER)
+ *                           .build();
+ * }
+ * 
+ */ +public interface ShardingKeyBuilder { + + /** + * This method will be called to add a subkey into a Sharding Key object being + * built. The order in which subkey method is called is important as it + * indicates the order of placement of the subkey within the Sharding Key. + * + * @param subkey contains the object that needs to be part of shard sub key + * @param subkeyType sub-key data type of type java.sql.SQLType + * @return this builder object + */ + ShardingKeyBuilder subkey(Object subkey, SQLType subkeyType); + + /** + * Returns an instance of the object defined by this builder. + * + * @return The built object + * @throws java.sql.SQLException If an error occurs building the object + */ + ShardingKey build() throws SQLException; +} diff --git a/jdk/src/java.sql/share/classes/java/sql/Statement.java b/jdk/src/java.sql/share/classes/java/sql/Statement.java index 819bfdf1f42..3dd29c2a9c0 100644 --- a/jdk/src/java.sql/share/classes/java/sql/Statement.java +++ b/jdk/src/java.sql/share/classes/java/sql/Statement.java @@ -1397,9 +1397,10 @@ public interface Statement extends Wrapper, AutoCloseable { * @param val a character string * @return A string enclosed by single quotes with every single quote * converted to two single quotes - * @throws NullPointerException if val is null + * @throws NullPointerException if val is {@code null} + * @throws SQLException if a database access error occurs */ - default String enquoteLiteral(String val) { + default String enquoteLiteral(String val) throws SQLException { return "'" + val.replace("'", "''") + "'"; } @@ -1437,7 +1438,7 @@ public interface Statement extends Wrapper, AutoCloseable { * * The default implementation will throw a {@code SQLException} if: *
    - *
  • {@code identifier} contains a null character or double quote, and is not + *
  • {@code identifier} contains a {@code null} character or double quote and is not * a simple SQL identifier.
  • *
  • The length of {@code identifier} is less than 1 or greater than 128 characters *
@@ -1501,14 +1502,14 @@ public interface Statement extends Wrapper, AutoCloseable { * @throws SQLException if identifier is not a valid identifier * @throws SQLFeatureNotSupportedException if the datasource does not support * delimited identifiers - * @throws NullPointerException if identifier is null + * @throws NullPointerException if identifier is {@code null} */ default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException { int len = identifier.length(); if (len < 1 || len > 128) { throw new SQLException("Invalid name"); } - if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]+").matcher(identifier).matches()) { + if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches()) { return alwaysQuote ? "\"" + identifier + "\"" : identifier; } if (identifier.matches("^\".+\"$")) { @@ -1520,4 +1521,65 @@ public interface Statement extends Wrapper, AutoCloseable { throw new SQLException("Invalid name"); } } + + /** + * Retrieves whether {@code identifier} is a simple SQL identifier. + * + * @implSpec The default implementation uses the following criteria to + * determine a valid simple SQL identifier: + *
    + *
  • The string is not enclosed in double quotes
  • + *
  • The first character is an alphabetic character from a through z, or + * from A through Z
  • + *
  • The string only contains alphanumeric characters or the character + * "_"
  • + *
  • The string is between 1 and 128 characters in length inclusive
  • + *
+ * + *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Examples of the conversion:
identifierSimple Identifier
Hellotrue
G'Dayfalse
"Bruce Wayne"false
GoodDay$false
Hello"Worldfalse
"Hello"World"false
+ *
+ * @implNote JDBC driver implementations may need to provide their own + * implementation of this method in order to meet the requirements of the + * underlying datasource. + * @param identifier a SQL identifier + * @return true if a simple SQL identifier, false otherwise + * @throws NullPointerException if identifier is {@code null} + * @throws SQLException if a database access error occurs + */ + default boolean isSimpleIdentifier(String identifier) throws SQLException { + int len = identifier.length(); + return len >= 1 && len <= 128 + && Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches(); + } } diff --git a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java index 71fa074e204..f59da21c853 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java @@ -26,7 +26,10 @@ package javax.sql; import java.sql.Connection; +import java.sql.ConnectionBuilder; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.ShardingKeyBuilder; import java.sql.Wrapper; /** @@ -106,4 +109,35 @@ public interface DataSource extends CommonDataSource, Wrapper { */ Connection getConnection(String username, String password) throws SQLException; + + // JDBC 4.3 + + /** + * Create a new {@code ConnectionBuilder} instance + * @implSpec + * The default implementation will throw a {@code SQLFeatureNotSupportedException} + * @return The ConnectionBuilder instance that was created + * @throws SQLException if an error occurs creating the builder + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see createConnectionBuilder + */ + default ConnectionBuilder createConnectionBuilder() throws SQLException { + throw new SQLFeatureNotSupportedException("createConnectionBuilder not implemented"); + }; + + /** + * Create a new {@code ShardingKeyBuilder} instance + * @implSpec + * The default implementation will throw a {@code SQLFeatureNotSupportedException} + * @return The ShardingKeyBuilder instance that was created + * @throws SQLException if an error occurs creating the builder + * @throws SQLFeatureNotSupportedException if the driver does not support this method + * @since 1.9 + * @see ShardingKeyBuilder + */ + default ShardingKeyBuilder createShardingKeyBuilder() + throws SQLException { + throw new SQLFeatureNotSupportedException("createShardingKeyBuilder not implemented"); + }; } diff --git a/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java b/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java index 394e269d47f..a72eff76346 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java +++ b/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, 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 @@ -22,40 +22,151 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package javax.sql; import java.sql.*; - /** - * An object that provides support for distributed - * transactions. An XAConnection object may be enlisted - * in a distributed transaction by means of an XAResource object. - * A transaction manager, usually part of a middle tier server, manages an - * XAConnection object through the XAResource object. + * An object that provides support for distributed transactions. An + * {@code XAConnection} object may be enlisted in a distributed transaction + * by means of an {@code XAResource} object. A transaction manager, usually + * part of a middle tier server, manages an {@code XAConnection} object + * through the {@code XAResource} object. *

- * An application programmer does not use this interface directly; rather, - * it is used by a transaction manager working in the middle tier server. + * An application programmer does not use this interface directly; rather, it is + * used by a transaction manager working in the middle tier server. * * @since 1.4 */ - public interface XAConnection extends PooledConnection { + /** + * Retrieves an {@code XAResource} object that the transaction manager + * will use to manage this {@code XAConnection} object's participation + * in a distributed transaction. + * + * @return the {@code XAResource} object + * @exception SQLException if a database access error occurs + * @exception SQLFeatureNotSupportedException if the JDBC driver does not + * support this method + * @since 1.4 + */ + javax.transaction.xa.XAResource getXAResource() throws SQLException; - /** - * Retrieves an XAResource object that - * the transaction manager will use - * to manage this XAConnection object's participation in a - * distributed transaction. - * - * @return the XAResource object - * @exception SQLException if a database access error occurs - * @exception SQLFeatureNotSupportedException if the JDBC driver does not support - * this method - * @since 1.4 - */ - javax.transaction.xa.XAResource getXAResource() throws SQLException; + // JDBC 4.3 - } + /** + * Sets and validates the sharding keys for this connection. + * + * @implSpec The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * + * @apiNote This method validates that the sharding keys are valid for the + * {@code Connection}. The timeout value indicates how long the driver + * should wait for the {@code Connection} to verify that the sharding key is + * valid before {@code setShardingKeyIfValid} returns false. + * @param shardingKey the sharding key to be validated against this + * connection + * @param superShardingKey the super sharding key to be validated against + * this connection. The super sharding key may be {@code null}. + * @param timeout time in seconds before which the validation process is + * expected to be completed, otherwise the validation process is aborted. A + * value of 0 indicates the validation process will not time out. + * @return true if the connection is valid and the sharding keys are valid + * and set on this connection; false if the sharding keys are not valid or + * the timeout period expires before the operation completes. + * @throws SQLException if an error occurs while performing this validation; + * the {@code shardingkey} is {@code null}; a {@code superSharedingKey} is specified + * without a {@code shardingKey}; this method is called on a closed + * {@code connection}; or the {@code timeout} value is less than 0. + * @throws SQLFeatureNotSupportedException if the driver does not support + * sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default boolean setShardingKeyIfValid(ShardingKey shardingKey, + ShardingKey superShardingKey, int timeout) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented"); + } + + /** + * Sets and validates the sharding key for this connection. + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * @apiNote + * This method validates that the sharding key is valid for the + * {@code Connection}. The timeout value indicates how long the driver + * should wait for the {@code Connection} to verify that the sharding key + * is valid before {@code setShardingKeyIfValid} returns false. + * @param shardingKey the sharding key to be validated against this connection + * @param timeout time in seconds before which the validation process is expected to + * be completed,else the validation process is aborted. A value of 0 indicates + * the validation process will not time out. + * @return true if the connection is valid and the sharding key is valid to be + * set on this connection; false if the sharding key is not valid or + * the timeout period expires before the operation completes. + * @throws SQLException if there is an error while performing this validation; + * this method is called on a closed {@code connection}; the {@code shardingkey} + * is {@code null}; or the {@code timeout} value is less than 0. + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented"); + } + + /** + * Specifies a shardingKey and superShardingKey to use with this Connection + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * @apiNote + * This method sets the specified sharding keys but does not require a + * round trip to the database to validate that the sharding keys are valid + * for the {@code Connection}. + * @param shardingKey the sharding key to set on this connection. + * @param superShardingKey the super sharding key to set on this connection. + * The super sharding key may be {@code null} + * @throws SQLException if an error occurs setting the sharding keys; + * this method is called on a closed {@code connection}; + * the {@code shardingkey} is {@code null}; or + * a {@code superSharedingKey} is specified without a {@code shardingKey} + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKey not implemented"); + } + + /** + * Specifies a shardingKey to use with this Connection + * @implSpec + * The default implementation will throw a + * {@code SQLFeatureNotSupportedException}. + * @apiNote + * This method sets the specified sharding key but does not require a + * round trip to the database to validate that the sharding key is valid + * for the {@code Connection}. + * @param shardingKey the sharding key to set on this connection. + * @throws SQLException if an error occurs setting the sharding key; + * this method is called on a closed {@code connection}; or the + * {@code shardkingKey} is {@code null} + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see ShardingKey + * @see ShardingKeyBuilder + */ + default void setShardingKey(ShardingKey shardingKey) + throws SQLException { + throw new SQLFeatureNotSupportedException("setShardingKey not implemented"); + } +} diff --git a/jdk/src/java.sql/share/classes/javax/sql/XAConnectionBuilder.java b/jdk/src/java.sql/share/classes/javax/sql/XAConnectionBuilder.java new file mode 100644 index 00000000000..865172a15e5 --- /dev/null +++ b/jdk/src/java.sql/share/classes/javax/sql/XAConnectionBuilder.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.sql; + +import java.sql.SQLException; +import java.sql.ShardingKey; + +/** + * A builder created from a {@code XADataSource} object, + * used to establish a connection to the database that the + * {@code data source} object represents. The connection + * properties that were specified for the {@code data source} are used as the + * default values by the {@code XAConnectionBuilder}. + *

The following example illustrates the use of {@code XAConnectionBuilder} + * to create a {@link XAConnection}: + * + *

{@code
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey superShardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ *                           .build();
+ *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ *                           .build();
+ *     XAConnection con = ds.createXAConnectionBuilder()
+ *                       .user("rafa")
+ *                       .password("tennis")
+ *                       .setShardingKey(shardingKey)
+ *                       .setSuperShardingKey(superShardingKey)
+ *                       .build();
+ * }
+ * + * @since 1.9 + * + */ +public interface XAConnectionBuilder { + + /** + * Specifies the username to be used when creating a connection + * + * @param username the database user on whose behalf the connection is being + * made + * @return the same {@code XAConnectionBuilder} instance + */ + XAConnectionBuilder user(String username); + + /** + * Specifies the password to be used when creating a connection + * + * @param password the password to use for this connection. May be {@code null} + * @return the same {@code XAConnectionBuilder} instance + */ + XAConnectionBuilder password(String password); + + /** + * Specifies a {@code shardingKey} to be used when creating a connection + * + * @param shardingKey the ShardingKey. May be {@code null} + * @return the same {@code XAConnectionBuilder} instance + * @see java.sql.ShardingKey + * @see java.sql.ShardingKeyBuilder + */ + XAConnectionBuilder shardingKey(ShardingKey shardingKey); + + /** + * Specifies a {@code superShardingKey} to be used when creating a connection + * + * @param superShardingKey the SuperShardingKey. May be {@code null} + * @return the same {@code XAConnectionBuilder} instance + * @see java.sql.ShardingKey + * @see java.sql.ShardingKeyBuilder + */ + XAConnectionBuilder superShardingKey(ShardingKey superShardingKey); + + /** + * Returns an instance of the object defined by this builder. + * + * @return The built object + * @throws java.sql.SQLException If an error occurs building the object + */ + XAConnection build() throws SQLException; + +} diff --git a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java index b768601c7f3..221dbe41339 100644 --- a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java +++ b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, 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 @@ -80,4 +80,35 @@ public interface XADataSource extends CommonDataSource { */ XAConnection getXAConnection(String user, String password) throws SQLException; + + // JDBC 4.3 + + /** + * Creates a new {@code XAConnectionBuilder} instance + * @implSpec + * The default implementation will throw a {@code SQLFeatureNotSupportedException}. + * @return The ConnectionBuilder instance that was created + * @throws SQLException if an error occurs creating the builder + * @throws SQLFeatureNotSupportedException if the driver does not support sharding + * @since 1.9 + * @see XAConnectionBuilder + */ + default XAConnectionBuilder createXAConnectionBuilder() throws SQLException { + throw new SQLFeatureNotSupportedException("createXAConnectionBuilder not implemented"); + }; + + /** + * Creates a new {@code ShardingKeyBuilder} instance + * @implSpec + * The default implementation will throw a {@code SQLFeatureNotSupportedException}. + * @return The ShardingKeyBuilder instance that was created + * @throws SQLException if an error occurs creating the builder + * @throws SQLFeatureNotSupportedException if the driver does not support this method + * @since 1.9 + * @see ShardingKeyBuilder + */ + default ShardingKeyBuilder createShardingKeyBuilder() + throws SQLException { + throw new SQLFeatureNotSupportedException("createShardingKeyBuilder not implemented"); + }; } diff --git a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java index 00fdf8c2ba8..4e5b5875b34 100644 --- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java +++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java @@ -389,10 +389,22 @@ abstract class KeyStore extends KeyStoreSpi { } } + X509Certificate[] xchain; + if (chain != null) { + if (chain instanceof X509Certificate[]) { + xchain = (X509Certificate[]) chain; + } else { + xchain = new X509Certificate[chain.length]; + System.arraycopy(chain, 0, xchain, 0, chain.length); + } + } else { + xchain = null; + } + if (! found) { entry = //TODO new KeyEntry(alias, key, (X509Certificate[]) chain); - new KeyEntry(alias, null, (X509Certificate[]) chain); + new KeyEntry(alias, null, xchain); entries.add(entry); } @@ -400,7 +412,7 @@ abstract class KeyStore extends KeyStoreSpi { try { entry.setPrivateKey((RSAPrivateCrtKey) key); - entry.setCertificateChain((X509Certificate[]) chain); + entry.setCertificateChain(xchain); } catch (CertificateException ce) { throw new KeyStoreException(ce); diff --git a/jdk/src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService b/jdk/src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService new file mode 100644 index 00000000000..9ae6583ef3e --- /dev/null +++ b/jdk/src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService @@ -0,0 +1 @@ +sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/package.html b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/package.html rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteHostImpl.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteHostImpl.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteVmImpl.java b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java similarity index 100% rename from jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteVmImpl.java rename to jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java diff --git a/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService b/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService index b106c0fc9a9..f559e14c4b4 100644 --- a/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService +++ b/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService @@ -1,3 +1,2 @@ sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostLocalService -sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java index 85365ce056c..8df13ca7f30 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java @@ -26,11 +26,8 @@ package sun.jvmstat.perfdata.monitor; import java.util.List; -import java.lang.reflect.*; -import java.io.*; import sun.jvmstat.monitor.*; -import sun.jvmstat.monitor.remote.*; import sun.jvmstat.monitor.event.VmListener; /** diff --git a/jdk/test/com/sun/jdi/DoubleAgentTest.java b/jdk/test/com/sun/jdi/DoubleAgentTest.java index 91babd72e26..be3b8d8ffdc 100644 --- a/jdk/test/com/sun/jdi/DoubleAgentTest.java +++ b/jdk/test/com/sun/jdi/DoubleAgentTest.java @@ -31,7 +31,7 @@ import jdk.testlibrary.Utils; * * @library /lib/testlibrary * @modules java.management - * @build jdk.testlibarary.* + * @build jdk.testlibrary.* * @build DoubleAgentTest Exit0 * @run driver DoubleAgentTest */ diff --git a/jdk/test/com/sun/jdi/SuspendNoFlagTest.java b/jdk/test/com/sun/jdi/SuspendNoFlagTest.java index 8f91db2bac5..346dcca8923 100644 --- a/jdk/test/com/sun/jdi/SuspendNoFlagTest.java +++ b/jdk/test/com/sun/jdi/SuspendNoFlagTest.java @@ -29,7 +29,7 @@ import jdk.testlibrary.ProcessTools; * @summary Test for JDWP: -agentlib:jdwp=suspend=n hanging * @library /lib/testlibrary * @modules java.management - * @build jdk.testlibarary.* + * @build jdk.testlibrary.* * @compile -g HelloWorld.java * @run driver SuspendNoFlagTest */ diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java index 1a64ae0d0a5..8a2c224f461 100644 --- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java @@ -41,9 +41,9 @@ import com.sun.management.HotSpotDiagnosticMXBean; * @library /test/lib/share/classes * @build jdk.testlibrary.* * @build jdk.test.lib.hprof.* - * @build jdk.test.lib.hprof.module.* + * @build jdk.test.lib.hprof.model.* * @build jdk.test.lib.hprof.parser.* - * @build jdk.test.lib.hprof.utils.* + * @build jdk.test.lib.hprof.util.* * @run main DumpHeap */ public class DumpHeap { diff --git a/jdk/test/java/lang/Integer/ToString.java b/jdk/test/java/lang/Integer/ToString.java new file mode 100644 index 00000000000..060e0666eb9 --- /dev/null +++ b/jdk/test/java/lang/Integer/ToString.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8136500 + * @summary Test Integer.toString method + */ + +public class ToString { + + public static void main(String[] args) throws Exception { + test("-2147483648", Integer.MIN_VALUE); + test("2147483647", Integer.MAX_VALUE); + test("0", 0); + + // Wiggle around the exponentially increasing base. + final int LIMIT = (1 << 15); + int base = 10000; + while (base < Integer.MAX_VALUE / 10) { + for (int d = -LIMIT; d < LIMIT; d++) { + int c = base + d; + if (c > 0) { + buildAndTest(c); + } + } + base *= 10; + } + + for (int c = 1; c < LIMIT; c++) { + buildAndTest(Integer.MAX_VALUE - LIMIT + c); + } + } + + private static void buildAndTest(int c) { + if (c <= 0) { + throw new IllegalArgumentException("Test bug: can only handle positives, " + c); + } + + StringBuilder sbN = new StringBuilder(); + StringBuilder sbP = new StringBuilder(); + + int t = c; + while (t > 0) { + char digit = (char) ('0' + (t % 10)); + sbN.append(digit); + sbP.append(digit); + t = t / 10; + } + + sbN.append("-"); + sbN.reverse(); + sbP.reverse(); + + test(sbN.toString(), -c); + test(sbP.toString(), c); + } + + private static void test(String expected, int value) { + String actual = Integer.toString(value); + if (!expected.equals(actual)) { + throw new RuntimeException("Expected " + expected + ", but got " + actual); + } + } +} diff --git a/jdk/test/java/lang/Long/ToString.java b/jdk/test/java/lang/Long/ToString.java new file mode 100644 index 00000000000..a420e3ed25e --- /dev/null +++ b/jdk/test/java/lang/Long/ToString.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8136500 + * @summary Test Long.toString method + */ + +public class ToString { + + public static void main(String[] args) throws Exception { + test("-9223372036854775808", Long.MIN_VALUE); + test("9223372036854775807", Long.MAX_VALUE); + test("0", 0); + + // Wiggle around the exponentially increasing base. + final int LIMIT = (1 << 15); + long base = 10000; + while (base < Long.MAX_VALUE / 10) { + for (int d = -LIMIT; d < LIMIT; d++) { + long c = base + d; + if (c > 0) { + buildAndTest(c); + } + } + base *= 10; + } + + for (int c = 1; c < LIMIT; c++) { + buildAndTest(Long.MAX_VALUE - LIMIT + c); + } + } + + private static void buildAndTest(long c) { + if (c <= 0) { + throw new IllegalArgumentException("Test bug: can only handle positives, " + c); + } + + StringBuilder sbN = new StringBuilder(); + StringBuilder sbP = new StringBuilder(); + + long t = c; + while (t > 0) { + char digit = (char) ('0' + (t % 10)); + sbN.append(digit); + sbP.append(digit); + t = t / 10; + } + + sbN.append("-"); + sbN.reverse(); + sbP.reverse(); + + test(sbN.toString(), -c); + test(sbP.toString(), c); + } + + private static void test(String expected, long value) { + String actual = Long.toString(value); + if (!expected.equals(actual)) { + throw new RuntimeException("Expected " + expected + ", but got " + actual); + } + } +} diff --git a/jdk/test/java/lang/invoke/T8139885.java b/jdk/test/java/lang/invoke/T8139885.java index 913111c9efe..fb6ba77301b 100644 --- a/jdk/test/java/lang/invoke/T8139885.java +++ b/jdk/test/java/lang/invoke/T8139885.java @@ -34,6 +34,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; +import java.lang.invoke.WrongMethodTypeException; import java.util.*; import static java.lang.invoke.MethodType.methodType; @@ -412,6 +413,18 @@ public class T8139885 { assertEquals(illegalPos.length, caught); } + @Test + public static void testAsSpreaderIllegalMethodType() throws Throwable { + MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class); + boolean caught = false; + try { + MethodHandle s = h.asSpreader(String[].class, 1); + } catch (WrongMethodTypeException wmte) { + caught = true; + } + assertTrue(caught); + } + @Test public static void testAsCollector() throws Throwable { MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1); diff --git a/jdk/test/java/sql/testng/test/sql/StatementTests.java b/jdk/test/java/sql/testng/test/sql/StatementTests.java index aad91c805bb..169b7342d04 100644 --- a/jdk/test/java/sql/testng/test/sql/StatementTests.java +++ b/jdk/test/java/sql/testng/test/sql/StatementTests.java @@ -24,6 +24,7 @@ package test.sql; import java.sql.SQLException; import static org.testng.Assert.assertEquals; +import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -33,18 +34,29 @@ import util.StubStatement; public class StatementTests extends BaseTest { protected StubStatement stmt; + protected static String maxIdentifier; @BeforeMethod public void setUpMethod() throws Exception { stmt = new StubStatement(); } + @BeforeClass + public static void setUpClass() throws Exception { + int maxLen = 128; + StringBuilder s = new StringBuilder(maxLen); + for (int i = 0; i < maxLen; i++) { + s.append('a'); + } + maxIdentifier = s.toString(); + } /* * Verify that enquoteLiteral creates a valid literal and converts every * single quote to two single quotes */ + @Test(dataProvider = "validEnquotedLiteralValues") - public void test00(String s, String expected) { + public void test00(String s, String expected) throws SQLException { assertEquals(stmt.enquoteLiteral(s), expected); } @@ -53,7 +65,7 @@ public class StatementTests extends BaseTest { * enquoteLiteral is null */ @Test(expectedExceptions = NullPointerException.class) - public void test01() { + public void test01() throws SQLException { stmt.enquoteLiteral(null); } @@ -89,6 +101,24 @@ public class StatementTests extends BaseTest { } + /* + * Validate that isSimpleIdentifier returns the expected value + */ + @Test(dataProvider = "simpleIdentifierValues") + public void test05(String s, boolean expected) throws SQLException { + assertEquals(stmt.isSimpleIdentifier(s), expected); + } + + /* + * Validate a NullPointerException is thrown is the string passed to + * isSimpleIdentifier is null + */ + @Test(expectedExceptions = NullPointerException.class) + public void test06() throws SQLException { + stmt.isSimpleIdentifier(null); + + } + /* * DataProvider used to provide strings that will be used to validate * that enquoteLiteral converts a string to a literal and every instance of @@ -114,6 +144,10 @@ public class StatementTests extends BaseTest { @DataProvider(name = "validIdentifierValues") protected Object[][] validEnquotedIdentifierValues() { return new Object[][]{ + {"b", false, "b"}, + {"b", true, "\"b\""}, + {maxIdentifier, false, maxIdentifier}, + {maxIdentifier, true, "\"" + maxIdentifier + "\""}, {"Hello", false, "Hello"}, {"Hello", true, "\"Hello\""}, {"G'Day", false, "\"G'Day\""}, @@ -130,16 +164,34 @@ public class StatementTests extends BaseTest { */ @DataProvider(name = "invalidIdentifierValues") protected Object[][] invalidEnquotedIdentifierValues() { - int invalidLen = 129; - StringBuilder s = new StringBuilder(invalidLen); - for (int i = 0; i < invalidLen; i++) { - s.append('a'); - } return new Object[][]{ {"Hel\"lo", false}, {"\"Hel\"lo\"", true}, {"Hello" + '\0', false}, {"", false}, - {s.toString(), false},}; + {maxIdentifier + 'a', false}, + }; } + + /* + * DataProvider used to provide strings that will be used to validate + * that isSimpleIdentifier returns the correct value based on the + * identifier specified. + */ + @DataProvider(name = "simpleIdentifierValues") + protected Object[][] simpleIdentifierValues() { + return new Object[][]{ + {"b", true}, + {"Hello", true}, + {"\"Gotham\"", false}, + {"G'Day", false}, + {"Bruce Wayne", false}, + {"GoodDay$", false}, + {"Dick_Grayson", true}, + {"Batmobile1966", true}, + {maxIdentifier, true}, + {maxIdentifier + 'a', false}, + {"", false},}; + } + } diff --git a/jdk/test/java/util/Collections/CheckedMapBash.java b/jdk/test/java/util/Collections/CheckedMapBash.java index 1603cc6709c..3b0b5d7b528 100644 --- a/jdk/test/java/util/Collections/CheckedMapBash.java +++ b/jdk/test/java/util/Collections/CheckedMapBash.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4904067 5023830 7129185 + * @bug 4904067 5023830 7129185 8072015 * @summary Unit test for Collections.checkedMap * @author Josh Bloch * @run testng CheckedMapBash @@ -53,7 +53,7 @@ public class CheckedMapBash { Object newHead; do { newHead = new Integer(rnd.nextInt()); - } while (m.containsKey(newHead)); + } while (m.containsKey(newHead) || newHead.equals(nil)); m.put(newHead, head); head = newHead; } @@ -99,16 +99,16 @@ public class CheckedMapBash { } @Test(dataProvider = "Supplier>") - public static void testCheckeMap2(String description, Supplier> supplier) { + public static void testCheckedMap2(String description, Supplier> supplier) { Map m = supplier.get(); for (int i=0; i iters = new ArrayList<>(makeCheckedMaps()); iters.ensureCapacity(numItr * iters.size()); for (int each=1; each < numItr; each++) { - iters.addAll( makeCheckedMaps()); + iters.addAll(makeCheckedMaps()); } return iters.iterator(); } @@ -158,19 +158,20 @@ public class CheckedMapBash { } public static Collection makeCheckedMaps() { - return Arrays.asList( - new Object[]{"Collections.checkedMap(HashMap)", - (Supplier) () -> {return Collections.checkedMap(new HashMap(), Integer.class, Integer.class);}}, - new Object[]{"Collections.checkedMap(TreeSet(reverseOrder)", - (Supplier) () -> {return Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class);}}, - new Object[]{"Collections.checkedMap(TreeSet).descendingSet()", - (Supplier) () -> {return Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class);}}, - new Object[]{"Collections.checkedNavigableMap(TreeSet)", - (Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class);}}, - new Object[]{"Collections.checkedNavigableMap(TreeSet(reverseOrder)", - (Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class);}}, - new Object[]{"Collections.checkedNavigableMap().descendingSet()", - (Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class);}} - ); + Object[][] params = { + {"Collections.checkedMap(HashMap)", + (Supplier) () -> Collections.checkedMap(new HashMap(), Integer.class, Integer.class)}, + {"Collections.checkedMap(TreeMap(reverseOrder))", + (Supplier) () -> Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)}, + {"Collections.checkedMap(TreeMap.descendingMap())", + (Supplier) () -> Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class)}, + {"Collections.checkedNavigableMap(TreeMap)", + (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)}, + {"Collections.checkedNavigableMap(TreeMap(reverseOrder))", + (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)}, + {"Collections.checkedNavigableMap(TreeMap.descendingMap())", + (Supplier) () -> Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class)}, + }; + return Arrays.asList(params); } } diff --git a/jdk/test/java/util/Collections/CheckedSetBash.java b/jdk/test/java/util/Collections/CheckedSetBash.java index c8e05dfba86..2f3979230c1 100644 --- a/jdk/test/java/util/Collections/CheckedSetBash.java +++ b/jdk/test/java/util/Collections/CheckedSetBash.java @@ -146,25 +146,26 @@ public class CheckedSetBash { ArrayList iters = new ArrayList<>(makeCheckedSets()); iters.ensureCapacity(numItr * iters.size()); for (int each=1; each < numItr; each++) { - iters.addAll( makeCheckedSets()); + iters.addAll(makeCheckedSets()); } return iters.iterator(); } public static Collection makeCheckedSets() { - return Arrays.asList( - new Object[]{"Collections.checkedSet(HashSet)", - (Supplier) () -> {return Collections.checkedSet(new HashSet(), Integer.class);}}, - new Object[]{"Collections.checkedSet(TreeSet(reverseOrder)", - (Supplier) () -> {return Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class);}}, - new Object[]{"Collections.checkedSet(TreeSet).descendingSet()", - (Supplier) () -> {return Collections.checkedSet(new TreeSet().descendingSet(), Integer.class);}}, - new Object[]{"Collections.checkedNavigableSet(TreeSet)", - (Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet(), Integer.class);}}, - new Object[]{"Collections.checkedNavigableSet(TreeSet(reverseOrder)", - (Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class);}}, - new Object[]{"Collections.checkedNavigableSet().descendingSet()", - (Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class);}} - ); + Object[][] params = { + {"Collections.checkedSet(HashSet)", + (Supplier) () -> Collections.checkedSet(new HashSet(), Integer.class)}, + {"Collections.checkedSet(TreeSet(reverseOrder))", + (Supplier) () -> Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class)}, + {"Collections.checkedSet(TreeSet.descendingSet())", + (Supplier) () -> Collections.checkedSet(new TreeSet().descendingSet(), Integer.class)}, + {"Collections.checkedNavigableSet(TreeSet)", + (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(), Integer.class)}, + {"Collections.checkedNavigableSet(TreeSet(reverseOrder))", + (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class)}, + {"Collections.checkedNavigableSet(TreeSet.descendingSet())", + (Supplier) () -> Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class)}, + }; + return Arrays.asList(params); } } diff --git a/jdk/test/java/util/Collections/EmptyCollectionSerialization.java b/jdk/test/java/util/Collections/EmptyCollectionSerialization.java index 471b74cf377..553ce167d88 100644 --- a/jdk/test/java/util/Collections/EmptyCollectionSerialization.java +++ b/jdk/test/java/util/Collections/EmptyCollectionSerialization.java @@ -58,7 +58,7 @@ public class EmptyCollectionSerialization { Object singleton = o.get(); assertSame(o.get(), singleton, description + ": broken Supplier not returning singleton"); Object copy = patheticDeepCopy(singleton); - assertSame( copy, singleton, description + ": " + + assertSame(copy, singleton, description + ": " + copy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(copy)) + " is not the singleton " + singleton.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(singleton))); @@ -73,27 +73,28 @@ public class EmptyCollectionSerialization { } public static Collection makeSingletons() { - return Arrays.asList( - new Object[]{"Collections.EMPTY_LIST", - (Supplier) () -> {return Collections.EMPTY_LIST;}}, - new Object[]{"Collections.EMPTY_MAP", - (Supplier) () -> {return Collections.EMPTY_MAP;}}, - new Object[]{"Collections.EMPTY_SET", - (Supplier) () -> {return Collections.EMPTY_SET;}}, - new Object[]{"Collections.singletonMap()", - (Supplier) () -> {return Collections.emptyList();}}, - new Object[]{"Collections.emptyMap()", - (Supplier) () -> {return Collections.emptyMap();}}, - new Object[]{"Collections.emptySet()", - (Supplier) () -> {return Collections.emptySet();}}, - new Object[]{"Collections.emptySortedSet()", - (Supplier) () -> {return Collections.emptySortedSet();}}, - new Object[]{"Collections.emptySortedMap()", - (Supplier) () -> {return Collections.emptySortedMap();}}, - new Object[]{"Collections.emptyNavigableSet()", - (Supplier) () -> {return Collections.emptyNavigableSet();}}, - new Object[]{"Collections.emptyNavigableMap()", - (Supplier) () -> {return Collections.emptyNavigableMap();}} - ); + Object[][] params = { + {"Collections.EMPTY_LIST", + (Supplier) () -> Collections.EMPTY_LIST}, + {"Collections.EMPTY_MAP", + (Supplier) () -> Collections.EMPTY_MAP}, + {"Collections.EMPTY_SET", + (Supplier) () -> Collections.EMPTY_SET}, + {"Collections.emptyList()", + (Supplier) () -> Collections.emptyList()}, + {"Collections.emptyMap()", + (Supplier) () -> Collections.emptyMap()}, + {"Collections.emptySet()", + (Supplier) () -> Collections.emptySet()}, + {"Collections.emptySortedSet()", + (Supplier) () -> Collections.emptySortedSet()}, + {"Collections.emptySortedMap()", + (Supplier) () -> Collections.emptySortedMap()}, + {"Collections.emptyNavigableSet()", + (Supplier) () -> Collections.emptyNavigableSet()}, + {"Collections.emptyNavigableMap()", + (Supplier) () -> Collections.emptyNavigableMap()}, + }; + return Arrays.asList(params); } } diff --git a/jdk/test/java/util/Locale/LocaleEnhanceTest.java b/jdk/test/java/util/Locale/LocaleEnhanceTest.java index 704d2b3839f..7c7779bfcbe 100644 --- a/jdk/test/java/util/Locale/LocaleEnhanceTest.java +++ b/jdk/test/java/util/Locale/LocaleEnhanceTest.java @@ -1180,8 +1180,11 @@ public class LocaleEnhanceTest extends LocaleTestFmwk { dataDir = new File(dataDirName); } - if (dataDir == null || !dataDir.isDirectory()) { - errln("Could not locate the serialized test case data location"); + if (dataDir == null) { + errln("'dataDir' is null. serialized.data.dir Property value is "+dataDirName); + return; + } else if (!dataDir.isDirectory()) { + errln("'dataDir' is not a directory. dataDir: "+dataDir.toString()); return; } diff --git a/jdk/test/java/util/ResourceBundle/Test4300693.java b/jdk/test/java/util/ResourceBundle/Test4300693.java index 13875a8e89a..ecc4802a8e2 100644 --- a/jdk/test/java/util/ResourceBundle/Test4300693.java +++ b/jdk/test/java/util/ResourceBundle/Test4300693.java @@ -22,7 +22,6 @@ */ /* @test - @ignore 6876961 @summary test that ResourceBundle.getBundle can be called recursively @build Test4300693RB @run main Test4300693 diff --git a/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java b/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java index bb687f3ca54..e6180e34b61 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java +++ b/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java @@ -202,9 +202,9 @@ public class SpliteratorLateBindingFailFastTest { db.addCollection(PriorityQueue::new); - // ArrayDeque fails some tests since it's fail-fast support is weaker + // ArrayDeque fails some tests since its fail-fast support is weaker // than other collections and limited to detecting most, but not all, - // removals. It probably requires it's own test since it is difficult + // removals. It probably requires its own test since it is difficult // to abstract out the conditions under which it fails-fast. // db.addCollection(ArrayDeque::new); diff --git a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java index d9593001b04..ed48ac22b1e 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java +++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java @@ -85,7 +85,7 @@ import static org.testng.Assert.assertEquals; @Test public class SpliteratorTraversingAndSplittingTest { - private static final List SIZES = Arrays.asList(0, 1, 10, 100, 1000); + private static final List SIZES = Arrays.asList(0, 1, 10, 42); private static final String LOW = new String(new char[] {Character.MIN_LOW_SURROGATE}); private static final String HIGH = new String(new char[] {Character.MIN_HIGH_SURROGATE}); diff --git a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java index 74a902ae754..c822e7d3b98 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java @@ -34,150 +34,148 @@ /* * @test * @bug 4486658 - * @run main/timeout=7000 CancelledProducerConsumerLoops * @summary Checks for responsiveness of blocking queues to cancellation. - * Runs under the assumption that ITERS computations require more than - * TIMEOUT msecs to complete. */ -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.List; +import java.util.SplittableRandom; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; public class CancelledProducerConsumerLoops { - static final int CAPACITY = 100; - static final long TIMEOUT = 100; - - static final ExecutorService pool = Executors.newCachedThreadPool(); - static boolean print = false; + static ExecutorService pool; public static void main(String[] args) throws Exception { - int maxPairs = 8; - int iters = 1000000; - - if (args.length > 0) - maxPairs = Integer.parseInt(args[0]); - - print = true; + final int maxPairs = (args.length > 0) ? Integer.parseInt(args[0]) : 5; + pool = Executors.newCachedThreadPool(); for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) { - System.out.println("Pairs:" + i); - try { - oneTest(i, iters); - } - catch (BrokenBarrierException bb) { - // OK, ignore - } - Thread.sleep(100); + final List> queues = new ArrayList<>(); + queues.add(new ArrayBlockingQueue(100)); + queues.add(new LinkedBlockingQueue(100)); + queues.add(new LinkedBlockingDeque(100)); + queues.add(new SynchronousQueue()); + // unbounded queue implementations are prone to OOME: + // PriorityBlockingQueue, LinkedTransferQueue + for (BlockingQueue queue : queues) + new CancelledProducerConsumerLoops(i, queue).run(); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) - throw new Error(); - } + if (! pool.awaitTermination(10L, TimeUnit.SECONDS)) + throw new AssertionError("timed out"); + pool = null; + } - static void oneRun(BlockingQueue q, int npairs, int iters) throws Exception { - if (print) - System.out.printf("%-18s", q.getClass().getSimpleName()); - LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); - CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer); + final int npairs; + final BlockingQueue queue; + final CountDownLatch producersInterrupted; + final CountDownLatch consumersInterrupted; + final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); + final CyclicBarrier barrier; + final SplittableRandom rnd = new SplittableRandom(); + volatile boolean done = false; + + CancelledProducerConsumerLoops(int npairs, BlockingQueue queue) { + this.npairs = npairs; + this.queue = queue; + this.producersInterrupted = new CountDownLatch(npairs - 1); + this.consumersInterrupted = new CountDownLatch(npairs - 1); + this.barrier = new CyclicBarrier(npairs * 2 + 1, timer); + } + + void run() throws Exception { Future[] prods = new Future[npairs]; Future[] cons = new Future[npairs]; - for (int i = 0; i < npairs; ++i) { - prods[i] = pool.submit(new Producer(q, barrier, iters)); - cons[i] = pool.submit(new Consumer(q, barrier, iters)); + for (int i = 0; i < npairs; i++) { + prods[i] = pool.submit(new Producer()); + cons[i] = pool.submit(new Consumer()); } barrier.await(); - Thread.sleep(TIMEOUT); - boolean tooLate = false; + Thread.sleep(rnd.nextInt(5)); - for (int i = 1; i < npairs; ++i) { - if (!prods[i].cancel(true)) - tooLate = true; - if (!cons[i].cancel(true)) - tooLate = true; + for (int i = 1; i < npairs; i++) { + if (!prods[i].cancel(true) || + !cons[i].cancel(true)) + throw new AssertionError("completed before done"); } - Object p0 = prods[0].get(); - Object c0 = cons[0].get(); - - if (!tooLate) { - for (int i = 1; i < npairs; ++i) { - if (!prods[i].isDone() || !prods[i].isCancelled()) - throw new Error("Only one producer thread should complete"); - if (!cons[i].isDone() || !cons[i].isCancelled()) - throw new Error("Only one consumer thread should complete"); - } + for (int i = 1; i < npairs; i++) { + assertCancelled(prods[i]); + assertCancelled(cons[i]); } - else - System.out.print("(cancelled too late) "); - long endTime = System.nanoTime(); - long time = endTime - timer.startTime; - if (print) { - double secs = (double)(time) / 1000000000.0; - System.out.println("\t " + secs + "s run time"); - } + if (!producersInterrupted.await(10L, TimeUnit.SECONDS)) + throw new AssertionError("timed out"); + if (!consumersInterrupted.await(10L, TimeUnit.SECONDS)) + throw new AssertionError("timed out"); + if (prods[0].isDone() || prods[0].isCancelled()) + throw new AssertionError("completed too early"); + + done = true; + + if (! (prods[0].get(10L, TimeUnit.SECONDS) instanceof Integer)) + throw new AssertionError("expected Integer"); + if (! (cons[0].get(10L, TimeUnit.SECONDS) instanceof Integer)) + throw new AssertionError("expected Integer"); } - static void oneTest(int pairs, int iters) throws Exception { - - oneRun(new ArrayBlockingQueue(CAPACITY), pairs, iters); - oneRun(new LinkedBlockingQueue(CAPACITY), pairs, iters); - oneRun(new LinkedBlockingDeque(CAPACITY), pairs, iters); - oneRun(new SynchronousQueue(), pairs, iters / 8); - - /* unbounded queue implementations are prone to OOME - oneRun(new PriorityBlockingQueue(iters / 2 * pairs), pairs, iters / 4); - oneRun(new LinkedTransferQueue(), pairs, iters); - */ + void assertCancelled(Future future) throws Exception { + if (!future.isDone()) + throw new AssertionError("not done"); + if (!future.isCancelled()) + throw new AssertionError("not cancelled"); + try { + future.get(10L, TimeUnit.SECONDS); + throw new AssertionError("should throw CancellationException"); + } catch (CancellationException success) {} } - abstract static class Stage implements Callable { - final BlockingQueue queue; - final CyclicBarrier barrier; - final int iters; - Stage(BlockingQueue q, CyclicBarrier b, int iters) { - queue = q; - barrier = b; - this.iters = iters; - } - } - - static class Producer extends Stage { - Producer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - + class Producer implements Callable { public Integer call() throws Exception { barrier.await(); - int s = 0; - int l = 4321; - for (int i = 0; i < iters; ++i) { - l = LoopHelpers.compute1(l); - s += LoopHelpers.compute2(l); - if (!queue.offer(new Integer(l), 1, TimeUnit.SECONDS)) - break; + int sum = 0; + try { + int x = 4321; + while (!done) { + if (Thread.interrupted()) throw new InterruptedException(); + x = LoopHelpers.compute1(x); + sum += LoopHelpers.compute2(x); + queue.offer(new Integer(x), 1, TimeUnit.MILLISECONDS); + } + } catch (InterruptedException cancelled) { + producersInterrupted.countDown(); } - return new Integer(s); + return sum; } } - static class Consumer extends Stage { - Consumer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - + class Consumer implements Callable { public Integer call() throws Exception { barrier.await(); - int l = 0; - int s = 0; - for (int i = 0; i < iters; ++i) { - Integer x = queue.poll(1, TimeUnit.SECONDS); - if (x == null) - break; - l = LoopHelpers.compute1(x.intValue()); - s += l; + int sum = 0; + try { + while (!done) { + Integer x = queue.poll(1, TimeUnit.MILLISECONDS); + if (x != null) + sum += LoopHelpers.compute1(x.intValue()); + } + } catch (InterruptedException cancelled) { + consumersInterrupted.countDown(); } - return new Integer(s); + return sum; } } } diff --git a/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java b/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java index 864947cc9fe..8654f4c6ae1 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java @@ -37,8 +37,19 @@ * @summary Test drainTo failing due to c.add throwing */ -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.FutureTask; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; @SuppressWarnings({"unchecked", "rawtypes"}) public class DrainToFails { diff --git a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java index 59d82df7bae..f3f130bb2c7 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java @@ -28,9 +28,19 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledThreadPoolExecutor; public class Interrupt { @@ -61,7 +71,7 @@ public class Interrupt { checkInterrupted0(fs, immediateExecutor); checkInterrupted0(fs, delayedExecutor); stpe.shutdown(); - check(stpe.awaitTermination(10, SECONDS)); + check(stpe.awaitTermination(10L, SECONDS)); } static void testQueue(final BlockingQueue q) { diff --git a/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java b/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java index d8cf75fa425..545201c3d14 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java @@ -28,8 +28,13 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.Iterator; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.PriorityBlockingQueue; public class LastElement { void test(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java b/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java index d9859f30066..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java @@ -31,13 +31,11 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -74,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java b/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java index 47b7347174d..6fafe5453c2 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java @@ -34,151 +34,124 @@ /* * @test * @bug 4486658 - * @run main/timeout=3600 MultipleProducersSingleConsumerLoops * @summary multiple producers and single consumer using blocking queues */ -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.atomic.AtomicInteger; public class MultipleProducersSingleConsumerLoops { - static final int CAPACITY = 100; - static final ExecutorService pool = Executors.newCachedThreadPool(); - static boolean print = false; - static int producerSum; - static int consumerSum; - - static synchronized void addProducerSum(int x) { - producerSum += x; - } - - static synchronized void addConsumerSum(int x) { - consumerSum += x; - } - - static synchronized void checkSum() { - if (producerSum != consumerSum) - throw new Error("CheckSum mismatch"); - } + static ExecutorService pool; public static void main(String[] args) throws Exception { - int maxProducers = 5; - int iters = 100000; - - if (args.length > 0) - maxProducers = Integer.parseInt(args[0]); - - print = false; - System.out.println("Warmup..."); - oneTest(1, 10000); - Thread.sleep(100); - oneTest(2, 10000); - Thread.sleep(100); - print = true; + final int maxProducers = (args.length > 0) + ? Integer.parseInt(args[0]) + : 5; + pool = Executors.newCachedThreadPool(); for (int i = 1; i <= maxProducers; i += (i+1) >>> 1) { - System.out.println("----------------------------------------"); - System.out.println("Producers:" + i); - oneTest(i, iters); - Thread.sleep(100); + // Adjust iterations to limit typical single runs to <= 10 ms; + // Notably, fair queues get fewer iters. + // Unbounded queues can legitimately OOME if iterations + // high enough, but we have a sufficiently low limit here. + run(new ArrayBlockingQueue(100), i, 300); + run(new LinkedBlockingQueue(100), i, 700); + run(new LinkedBlockingDeque(100), i , 500); + run(new LinkedTransferQueue(), i, 1000); + run(new PriorityBlockingQueue(), i, 1000); + run(new SynchronousQueue(), i, 500); + run(new SynchronousQueue(true), i, 200); + run(new ArrayBlockingQueue(100, true), i, 100); } + pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(10L, SECONDS)) throw new Error(); - } - - static void oneTest(int producers, int iters) throws Exception { - oneRun(new ArrayBlockingQueue(CAPACITY), producers, iters); - oneRun(new LinkedBlockingQueue(CAPACITY), producers, iters); - oneRun(new LinkedBlockingDeque(CAPACITY), producers, iters); - oneRun(new LinkedTransferQueue(), producers, iters); - - // Don't run PBQ since can legitimately run out of memory - // if (print) - // System.out.print("PriorityBlockingQueue "); - // oneRun(new PriorityBlockingQueue(), producers, iters); - - oneRun(new SynchronousQueue(), producers, iters); - if (print) - System.out.println("fair implementations:"); - oneRun(new SynchronousQueue(true), producers, iters); - oneRun(new ArrayBlockingQueue(CAPACITY, true), producers, iters); + pool = null; } - abstract static class Stage implements Runnable { - final int iters; - final BlockingQueue queue; - final CyclicBarrier barrier; - Stage(BlockingQueue q, CyclicBarrier b, int iters) { - queue = q; - barrier = b; - this.iters = iters; - } + static void run(BlockingQueue queue, int nproducers, int iters) throws Exception { + new MultipleProducersSingleConsumerLoops(queue, nproducers, iters).run(); } - static class Producer extends Stage { - Producer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } + final BlockingQueue queue; + final int nproducers; + final int iters; + final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); + final CyclicBarrier barrier; + final AtomicInteger checksum = new AtomicInteger(0); + Throwable fail; - public void run() { - try { - barrier.await(); - int s = 0; - int l = hashCode(); - for (int i = 0; i < iters; ++i) { - l = LoopHelpers.compute1(l); - l = LoopHelpers.compute2(l); - queue.put(new Integer(l)); - s += l; - } - addProducerSum(s); - barrier.await(); - } - catch (Exception ie) { - ie.printStackTrace(); - return; - } - } + MultipleProducersSingleConsumerLoops(BlockingQueue queue, int nproducers, int iters) { + this.queue = queue; + this.nproducers = nproducers; + this.iters = iters; + this.barrier = new CyclicBarrier(nproducers + 2, timer); } - static class Consumer extends Stage { - Consumer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - - public void run() { - try { - barrier.await(); - int s = 0; - for (int i = 0; i < iters; ++i) { - s += queue.take().intValue(); - } - addConsumerSum(s); - barrier.await(); - } - catch (Exception ie) { - ie.printStackTrace(); - return; - } - } - - } - - static void oneRun(BlockingQueue q, int nproducers, int iters) throws Exception { - if (print) - System.out.printf("%-18s", q.getClass().getSimpleName()); - LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); - CyclicBarrier barrier = new CyclicBarrier(nproducers + 2, timer); - for (int i = 0; i < nproducers; ++i) { - pool.execute(new Producer(q, barrier, iters)); - } - pool.execute(new Consumer(q, barrier, iters * nproducers)); + void run() throws Exception { + for (int i = 0; i < nproducers; i++) + pool.execute(new Producer()); + pool.execute(new Consumer()); barrier.await(); barrier.await(); - long time = timer.getTime(); - checkSum(); - if (print) - System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nproducers)) + " ns per transfer"); + System.out.printf("%s, nproducers=%d: %d ms%n", + queue.getClass().getSimpleName(), nproducers, + NANOSECONDS.toMillis(timer.getTime())); + if (checksum.get() != 0) throw new AssertionError("checksum mismatch"); + if (fail != null) throw new AssertionError(fail); } + abstract class CheckedRunnable implements Runnable { + abstract void realRun() throws Throwable; + public final void run() { + try { + realRun(); + } catch (Throwable t) { + fail = t; + t.printStackTrace(); + throw new AssertionError(t); + } + } + } + + class Producer extends CheckedRunnable { + void realRun() throws Throwable { + barrier.await(); + int s = 0; + int l = hashCode(); + for (int i = 0; i < iters; i++) { + l = LoopHelpers.compute1(l); + l = LoopHelpers.compute2(l); + queue.put(new Integer(l)); + s += l; + } + checksum.getAndAdd(s); + barrier.await(); + } + } + + class Consumer extends CheckedRunnable { + void realRun() throws Throwable { + barrier.await(); + int s = 0; + for (int i = 0; i < nproducers * iters; i++) { + s += queue.take().intValue(); + } + checksum.getAndAdd(-s); + barrier.await(); + } + } } diff --git a/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java index 049bf293b37..9154683995d 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java @@ -34,13 +34,20 @@ /* * @test * @bug 6805775 6815766 - * @run main OfferDrainToLoops 300 + * @run main OfferDrainToLoops 100 * @summary Test concurrent offer vs. drainTo */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.util.ArrayList; +import java.util.List; +import java.util.SplittableRandom; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.atomic.AtomicLong; @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) public class OfferDrainToLoops { @@ -66,22 +73,22 @@ public class OfferDrainToLoops { test(new LinkedTransferQueue()); } - Random getRandom() { - return ThreadLocalRandom.current(); - } - void test(final BlockingQueue q) throws Throwable { System.out.println(q.getClass().getSimpleName()); final long testDurationNanos = testDurationMillis * 1000L * 1000L; final long quittingTimeNanos = System.nanoTime() + testDurationNanos; final long timeoutMillis = 10L * 1000L; + final SplittableRandom rnd = new SplittableRandom(); /** Poor man's bounded buffer. */ final AtomicLong approximateCount = new AtomicLong(0L); abstract class CheckedThread extends Thread { - CheckedThread(String name) { + final SplittableRandom rnd; + + CheckedThread(String name, SplittableRandom rnd) { super(name); + this.rnd = rnd; setDaemon(true); start(); } @@ -99,7 +106,7 @@ public class OfferDrainToLoops { } } - Thread offerer = new CheckedThread("offerer") { + Thread offerer = new CheckedThread("offerer", rnd.split()) { protected void realRun() { long c = 0; for (long i = 0; ! quittingTime(i); i++) { @@ -113,9 +120,8 @@ public class OfferDrainToLoops { Thread.yield(); }}}}; - Thread drainer = new CheckedThread("drainer") { + Thread drainer = new CheckedThread("drainer", rnd.split()) { protected void realRun() { - final Random rnd = getRandom(); while (! quittingTime()) { List list = new ArrayList(); int n = rnd.nextBoolean() ? @@ -131,9 +137,8 @@ public class OfferDrainToLoops { approximateCount.set(0); // Releases waiting offerer thread }}; - Thread scanner = new CheckedThread("scanner") { + Thread scanner = new CheckedThread("scanner", rnd.split()) { protected void realRun() { - final Random rnd = getRandom(); while (! quittingTime()) { switch (rnd.nextInt(3)) { case 0: checkNotContainsNull(q); break; @@ -157,8 +162,6 @@ public class OfferDrainToLoops { failed++; for (StackTraceElement e : thread.getStackTrace()) System.err.println(e); - // Kludge alert - thread.stop(); thread.join(timeoutMillis); } } diff --git a/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java b/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java index 417fa7ee6c9..43b64923c61 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java @@ -40,7 +40,12 @@ * number of aborted timed waits occur without a signal. */ -import java.util.concurrent.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; public class PollMemoryLeak { public static void main(String[] args) throws InterruptedException { diff --git a/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java b/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java index e8770cd0d39..6cc57e7f319 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java @@ -34,149 +34,126 @@ /* * @test * @bug 4486658 - * @run main/timeout=3600 ProducerConsumerLoops * @summary multiple producers and consumers using blocking queues */ -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.atomic.AtomicInteger; public class ProducerConsumerLoops { - static final int CAPACITY = 100; - - static final ExecutorService pool = Executors.newCachedThreadPool(); - static boolean print = false; - static int producerSum; - static int consumerSum; - static synchronized void addProducerSum(int x) { - producerSum += x; - } - - static synchronized void addConsumerSum(int x) { - consumerSum += x; - } - - static synchronized void checkSum() { - if (producerSum != consumerSum) - throw new Error("CheckSum mismatch"); - } + static ExecutorService pool; public static void main(String[] args) throws Exception { - int maxPairs = 8; + final int maxPairs = (args.length > 0) + ? Integer.parseInt(args[0]) + : 5; int iters = 10000; - if (args.length > 0) - maxPairs = Integer.parseInt(args[0]); - - print = false; - System.out.println("Warmup..."); - oneTest(1, 10000); - Thread.sleep(100); - oneTest(2, 10000); - Thread.sleep(100); - print = true; - + pool = Executors.newCachedThreadPool(); for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) { - System.out.println("----------------------------------------"); - System.out.println("Pairs: " + i); - oneTest(i, iters); - Thread.sleep(100); + // Adjust iterations to limit typical single runs to <= 10 ms; + // Notably, fair queues get fewer iters. + // Unbounded queues can legitimately OOME if iterations + // high enough, but we have a sufficiently low limit here. + run(new ArrayBlockingQueue(100), i, 500); + run(new LinkedBlockingQueue(100), i, 1000); + run(new LinkedBlockingDeque(100), i, 1000); + run(new LinkedTransferQueue(), i, 1000); + run(new PriorityBlockingQueue(), i, 1000); + run(new SynchronousQueue(), i, 400); + run(new SynchronousQueue(true), i, 300); + run(new ArrayBlockingQueue(100, true), i, 100); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); + pool = null; } - static void oneTest(int pairs, int iters) throws Exception { - oneRun(new ArrayBlockingQueue(CAPACITY), pairs, iters); - oneRun(new LinkedBlockingQueue(CAPACITY), pairs, iters); - oneRun(new LinkedBlockingDeque(CAPACITY), pairs, iters); - oneRun(new LinkedTransferQueue(), pairs, iters); - oneRun(new PriorityBlockingQueue(), pairs, iters); - oneRun(new SynchronousQueue(), pairs, iters); - - if (print) - System.out.println("fair implementations:"); - - oneRun(new SynchronousQueue(true), pairs, iters); - oneRun(new ArrayBlockingQueue(CAPACITY, true), pairs, iters); + static void run(BlockingQueue queue, int pairs, int iters) throws Exception { + new ProducerConsumerLoops(queue, pairs, iters).run(); } - abstract static class Stage implements Runnable { - final int iters; - final BlockingQueue queue; - final CyclicBarrier barrier; - Stage(BlockingQueue q, CyclicBarrier b, int iters) { - queue = q; - barrier = b; - this.iters = iters; - } + final BlockingQueue queue; + final int pairs; + final int iters; + final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); + final CyclicBarrier barrier; + final AtomicInteger checksum = new AtomicInteger(0); + Throwable fail; + + ProducerConsumerLoops(BlockingQueue queue, int pairs, int iters) { + this.queue = queue; + this.pairs = pairs; + this.iters = iters; + this.barrier = new CyclicBarrier(2 * pairs + 1, timer); } - static class Producer extends Stage { - Producer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - - public void run() { - try { - barrier.await(); - int s = 0; - int l = hashCode(); - for (int i = 0; i < iters; ++i) { - l = LoopHelpers.compute2(l); - queue.put(new Integer(l)); - s += LoopHelpers.compute1(l); - } - addProducerSum(s); - barrier.await(); - } - catch (Exception ie) { - ie.printStackTrace(); - return; - } - } - } - - static class Consumer extends Stage { - Consumer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - - public void run() { - try { - barrier.await(); - int l = 0; - int s = 0; - for (int i = 0; i < iters; ++i) { - l = LoopHelpers.compute1(queue.take().intValue()); - s += l; - } - addConsumerSum(s); - barrier.await(); - } - catch (Exception ie) { - ie.printStackTrace(); - return; - } - } - - } - - static void oneRun(BlockingQueue q, int npairs, int iters) throws Exception { - if (print) - System.out.printf("%-18s", q.getClass().getSimpleName()); - LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); - CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer); - for (int i = 0; i < npairs; ++i) { - pool.execute(new Producer(q, barrier, iters)); - pool.execute(new Consumer(q, barrier, iters)); + void run() throws Exception { + for (int i = 0; i < pairs; i++) { + pool.execute(new Producer()); + pool.execute(new Consumer()); } barrier.await(); barrier.await(); - long time = timer.getTime(); - checkSum(); - if (print) - System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * npairs)) + " ns per transfer"); + System.out.printf("%s, pairs=%d: %d ms%n", + queue.getClass().getSimpleName(), pairs, + NANOSECONDS.toMillis(timer.getTime())); + if (checksum.get() != 0) throw new AssertionError("checksum mismatch"); + if (fail != null) throw new AssertionError(fail); } + abstract class CheckedRunnable implements Runnable { + abstract void realRun() throws Throwable; + public final void run() { + try { + realRun(); + } catch (Throwable t) { + fail = t; + t.printStackTrace(); + throw new AssertionError(t); + } + } + } + + class Producer extends CheckedRunnable { + void realRun() throws Throwable { + barrier.await(); + int s = 0; + int l = hashCode(); + for (int i = 0; i < iters; i++) { + l = LoopHelpers.compute2(l); + queue.put(new Integer(l)); + s += LoopHelpers.compute1(l); + } + checksum.getAndAdd(s); + barrier.await(); + } + } + + class Consumer extends CheckedRunnable { + void realRun() throws Throwable { + barrier.await(); + int l = 0; + int s = 0; + for (int i = 0; i < iters; i++) { + l = LoopHelpers.compute1(queue.take().intValue()); + s += l; + } + checksum.getAndAdd(-s); + barrier.await(); + } + } } diff --git a/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java b/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java index 51efc7ac7f3..662b6b277aa 100644 --- a/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java +++ b/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java @@ -34,135 +34,126 @@ /* * @test * @bug 4486658 - * @run main/timeout=600 SingleProducerMultipleConsumerLoops * @summary check ordering for blocking queues with 1 producer and multiple consumers */ -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.SynchronousQueue; public class SingleProducerMultipleConsumerLoops { - static final int CAPACITY = 100; - - static final ExecutorService pool = Executors.newCachedThreadPool(); - static boolean print = false; + static ExecutorService pool; public static void main(String[] args) throws Exception { - int maxConsumers = 5; - int iters = 10000; - - if (args.length > 0) - maxConsumers = Integer.parseInt(args[0]); - - print = false; - System.out.println("Warmup..."); - oneTest(1, 10000); - Thread.sleep(100); - oneTest(2, 10000); - Thread.sleep(100); - print = true; + final int maxConsumers = (args.length > 0) + ? Integer.parseInt(args[0]) + : 5; + pool = Executors.newCachedThreadPool(); for (int i = 1; i <= maxConsumers; i += (i+1) >>> 1) { - System.out.println("----------------------------------------"); - System.out.println("Consumers: " + i); - oneTest(i, iters); - Thread.sleep(100); + // Adjust iterations to limit typical single runs to <= 10 ms; + // Notably, fair queues get fewer iters. + // Unbounded queues can legitimately OOME if iterations + // high enough, but we have a sufficiently low limit here. + run(new ArrayBlockingQueue(100), i, 1000); + run(new LinkedBlockingQueue(100), i, 1000); + run(new LinkedBlockingDeque(100), i, 1000); + run(new LinkedTransferQueue(), i, 700); + run(new PriorityBlockingQueue(), i, 1000); + run(new SynchronousQueue(), i, 300); + run(new SynchronousQueue(true), i, 200); + run(new ArrayBlockingQueue(100, true), i, 100); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); + pool = null; } - static void oneTest(int consumers, int iters) throws Exception { - oneRun(new ArrayBlockingQueue(CAPACITY), consumers, iters); - oneRun(new LinkedBlockingQueue(CAPACITY), consumers, iters); - oneRun(new LinkedBlockingDeque(CAPACITY), consumers, iters); - oneRun(new LinkedTransferQueue(), consumers, iters); - oneRun(new PriorityBlockingQueue(), consumers, iters); - oneRun(new SynchronousQueue(), consumers, iters); - if (print) - System.out.println("fair implementations:"); - oneRun(new SynchronousQueue(true), consumers, iters); - oneRun(new ArrayBlockingQueue(CAPACITY, true), consumers, iters); + static void run(BlockingQueue queue, int consumers, int iters) throws Exception { + new SingleProducerMultipleConsumerLoops(queue, consumers, iters).run(); } - abstract static class Stage implements Runnable { - final int iters; - final BlockingQueue queue; - final CyclicBarrier barrier; + final BlockingQueue queue; + final int consumers; + final int iters; + final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); + final CyclicBarrier barrier; + Throwable fail; + + SingleProducerMultipleConsumerLoops(BlockingQueue queue, int consumers, int iters) { + this.queue = queue; + this.consumers = consumers; + this.iters = iters; + this.barrier = new CyclicBarrier(consumers + 2, timer); + } + + void run() throws Exception { + pool.execute(new Producer()); + for (int i = 0; i < consumers; i++) { + pool.execute(new Consumer()); + } + barrier.await(); + barrier.await(); + System.out.printf("%s, consumers=%d: %d ms%n", + queue.getClass().getSimpleName(), consumers, + NANOSECONDS.toMillis(timer.getTime())); + if (fail != null) throw new AssertionError(fail); + } + + abstract class CheckedRunnable implements Runnable { + abstract void realRun() throws Throwable; + public final void run() { + try { + realRun(); + } catch (Throwable t) { + fail = t; + t.printStackTrace(); + throw new AssertionError(t); + } + } + } + + class Producer extends CheckedRunnable { volatile int result; - Stage(BlockingQueue q, CyclicBarrier b, int iters) { - queue = q; - barrier = b; - this.iters = iters; + void realRun() throws Throwable { + barrier.await(); + for (int i = 0; i < iters * consumers; i++) { + queue.put(new Integer(i)); + } + barrier.await(); + result = 432; } } - static class Producer extends Stage { - Producer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - - public void run() { - try { - barrier.await(); - for (int i = 0; i < iters; ++i) { - queue.put(new Integer(i)); - } - barrier.await(); - result = 432; - } - catch (Exception ie) { - ie.printStackTrace(); - return; + class Consumer extends CheckedRunnable { + volatile int result; + void realRun() throws Throwable { + barrier.await(); + int l = 0; + int s = 0; + int last = -1; + for (int i = 0; i < iters; i++) { + Integer item = queue.take(); + int v = item.intValue(); + if (v < last) + throw new Error("Out-of-Order transfer"); + last = v; + l = LoopHelpers.compute1(v); + s += l; } + barrier.await(); + result = s; } } - - static class Consumer extends Stage { - Consumer(BlockingQueue q, CyclicBarrier b, int iters) { - super(q, b, iters); - } - - public void run() { - try { - barrier.await(); - int l = 0; - int s = 0; - int last = -1; - for (int i = 0; i < iters; ++i) { - Integer item = queue.take(); - int v = item.intValue(); - if (v < last) - throw new Error("Out-of-Order transfer"); - last = v; - l = LoopHelpers.compute1(v); - s += l; - } - barrier.await(); - result = s; - } - catch (Exception ie) { - ie.printStackTrace(); - return; - } - } - - } - - static void oneRun(BlockingQueue q, int nconsumers, int iters) throws Exception { - if (print) - System.out.printf("%-18s", q.getClass().getSimpleName()); - LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); - CyclicBarrier barrier = new CyclicBarrier(nconsumers + 2, timer); - pool.execute(new Producer(q, barrier, iters * nconsumers)); - for (int i = 0; i < nconsumers; ++i) { - pool.execute(new Consumer(q, barrier, iters)); - } - barrier.await(); - barrier.await(); - long time = timer.getTime(); - if (print) - System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nconsumers)) + " ns per transfer"); - } - } diff --git a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java index 8f09dd6b389..4470604b3f0 100644 --- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java +++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java @@ -40,17 +40,19 @@ * @author Chris Hegarty */ +import static java.util.concurrent.CompletableFuture.runAsync; +import static java.util.concurrent.CompletableFuture.supplyAsync; +import static java.util.concurrent.ForkJoinPool.commonPool; +import static java.util.concurrent.TimeUnit.SECONDS; + import java.lang.reflect.Array; import java.util.concurrent.Phaser; -import static java.util.concurrent.TimeUnit.*; import java.util.concurrent.CompletableFuture; -import static java.util.concurrent.CompletableFuture.*; import java.util.concurrent.CompletionException; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import static java.util.concurrent.ForkJoinPool.*; import java.util.concurrent.atomic.AtomicInteger; public class Basic { @@ -112,7 +114,7 @@ public class Basic { test(executor); } finally { executor.shutdown(); - executor.awaitTermination(30, SECONDS); + executor.awaitTermination(30L, SECONDS); } } diff --git a/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java b/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java index d9859f30066..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java @@ -31,13 +31,11 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -74,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java index 8eae65088b7..6337436a2cd 100644 --- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java +++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java @@ -38,8 +38,20 @@ * @summary Times and checks basic map operations */ -import java.util.*; -import java.io.*; +import java.io.Serializable; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.SplittableRandom; public class MapCheck { @@ -599,12 +611,11 @@ public class MapCheck { Stats(double t) { least = t; } } - static Random rng = new Random(); - static void shuffle(Object[] keys) { + SplittableRandom rnd = new SplittableRandom(); int size = keys.length; for (int i=size; i>1; i--) { - int r = rng.nextInt(i); + int r = rnd.nextInt(i); Object t = keys[i-1]; keys[i-1] = keys[r]; keys[r] = t; diff --git a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java index 1a2bcd83e37..767f035ab62 100644 --- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java +++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java @@ -44,15 +44,22 @@ * parsing from command line.) */ -import java.util.*; -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.List; +import java.util.Map; +import java.util.SplittableRandom; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class MapLoops { - static int nkeys = 10000; + static int nkeys = 1000; // 10_000 static int pinsert = 60; static int premove = 2; static int maxThreads = 100; - static int nops = 100000; + static int nops = 10000; // 100_000 static int removesPerMaxRandom; static int insertsPerMaxRandom; @@ -104,7 +111,6 @@ public class MapLoops { int k = 1; int warmups = 2; for (int i = 1; i <= maxThreads;) { - Thread.sleep(100); test(i, nkeys, mapClass); if (warmups > 0) --warmups; @@ -120,7 +126,7 @@ public class MapLoops { i = k; } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); if (! throwables.isEmpty()) @@ -129,17 +135,17 @@ public class MapLoops { } static Integer[] makeKeys(int n) { - LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); + SplittableRandom rnd = new SplittableRandom(); Integer[] key = new Integer[n]; for (int i = 0; i < key.length; ++i) - key[i] = new Integer(rng.next()); + key[i] = new Integer(rnd.nextInt()); return key; } static void shuffleKeys(Integer[] key) { - Random rng = new Random(); + SplittableRandom rnd = new SplittableRandom(); for (int i = key.length; i > 1; --i) { - int j = rng.nextInt(i); + int j = rnd.nextInt(i); Integer tmp = key[j]; key[j] = key[i-1]; key[i-1] = tmp; @@ -155,8 +161,9 @@ public class MapLoops { // map.put(key[j], key[j]); LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); CyclicBarrier barrier = new CyclicBarrier(i+1, timer); + SplittableRandom rnd = new SplittableRandom(); for (int t = 0; t < i; ++t) - pool.execute(new Runner(map, key, barrier)); + pool.execute(new Runner(map, key, barrier, rnd.split())); barrier.await(); barrier.await(); long time = timer.getTime(); @@ -170,21 +177,25 @@ public class MapLoops { static class Runner implements Runnable { final Map map; final Integer[] key; - final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); final CyclicBarrier barrier; + final SplittableRandom rnd; int position; int total; - Runner(Map map, Integer[] key, CyclicBarrier barrier) { + Runner(Map map, + Integer[] key, + CyclicBarrier barrier, + SplittableRandom rnd) { this.map = map; this.key = key; this.barrier = barrier; + this.rnd = rnd; position = key.length / 2; } int step() { // random-walk around key positions, bunching accesses - int r = rng.next(); + int r = rnd.nextInt(Integer.MAX_VALUE); position += (r & 7) - 3; while (position >= key.length) position -= key.length; while (position < 0) position += key.length; diff --git a/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java b/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java index 4c5871a444a..a2bf50ccc33 100644 --- a/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java +++ b/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java @@ -27,8 +27,11 @@ * @summary Reasonable things should happen if mutating while iterating. */ -import java.util.*; -import java.util.concurrent.*; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentSkipListMap; public class ConcurrentModification { static volatile int passed = 0, failed = 0; diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java index 4706794b5f9..8b7511f71e9 100644 --- a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java @@ -38,9 +38,25 @@ * @summary Checks that a set of threads can repeatedly get and modify items */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.atomic.AtomicInteger; public class ConcurrentQueueLoops { ExecutorService pool; @@ -99,7 +115,7 @@ public class ConcurrentQueueLoops { oneRun(i, items, q); } pool.shutdown(); - check(pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)); + check(pool.awaitTermination(60L, SECONDS)); } class Stage implements Callable { diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java index 4b1b858c0b6..d3e63001d55 100644 --- a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java @@ -31,15 +31,28 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -import java.util.*; -import java.util.concurrent.*; - /* * @test * @bug 6805775 6815766 * @summary Check weak consistency of concurrent queue iterators */ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Queue; +import java.util.Random; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; + @SuppressWarnings({"unchecked", "rawtypes"}) public class IteratorWeakConsistency { final Random rnd = new Random(); diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java index d9859f30066..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java @@ -31,13 +31,11 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -74,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java b/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java index 46faedeb1a1..96008fa67b2 100644 --- a/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java @@ -29,10 +29,21 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import static java.util.concurrent.TimeUnit.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.Arrays; +import java.util.Queue; +import java.util.SplittableRandom; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedTransferQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadLocalRandom; @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) public class OfferRemoveLoops { @@ -61,10 +72,6 @@ public class OfferRemoveLoops { testQueue(new LinkedTransferQueue()); } - Random getRandom() { - return ThreadLocalRandom.current(); - } - void testQueue(final Queue q) throws Throwable { System.err.println(q.getClass().getSimpleName()); final long testDurationNanos = testDurationMillis * 1000L * 1000L; @@ -73,13 +80,17 @@ public class OfferRemoveLoops { final int maxChunkSize = 1042; final int maxQueueSize = 10 * maxChunkSize; final CountDownLatch done = new CountDownLatch(3); + final SplittableRandom rnd = new SplittableRandom(); /** Poor man's bounded buffer; prevents unbounded queue expansion. */ final Semaphore offers = new Semaphore(maxQueueSize); abstract class CheckedThread extends Thread { - CheckedThread(String name) { + final SplittableRandom rnd; + + CheckedThread(String name, SplittableRandom rnd) { super(name); + this.rnd = rnd; setDaemon(true); start(); } @@ -97,9 +108,9 @@ public class OfferRemoveLoops { } } - Thread offerer = new CheckedThread("offerer") { + Thread offerer = new CheckedThread("offerer", rnd.split()) { protected void realRun() throws InterruptedException { - final int chunkSize = getRandom().nextInt(maxChunkSize) + 20; + final int chunkSize = rnd.nextInt(maxChunkSize) + 20; long c = 0; while (! quittingTime()) { if (q.offer(Long.valueOf(c))) { @@ -113,9 +124,9 @@ public class OfferRemoveLoops { done.countDown(); }}; - Thread remover = new CheckedThread("remover") { + Thread remover = new CheckedThread("remover", rnd.split()) { protected void realRun() { - final int chunkSize = getRandom().nextInt(maxChunkSize) + 20; + final int chunkSize = rnd.nextInt(maxChunkSize) + 20; long c = 0; while (! quittingTime()) { if (q.remove(Long.valueOf(c))) { @@ -131,9 +142,8 @@ public class OfferRemoveLoops { done.countDown(); }}; - Thread scanner = new CheckedThread("scanner") { + Thread scanner = new CheckedThread("scanner", rnd.split()) { protected void realRun() { - final Random rnd = getRandom(); while (! quittingTime()) { switch (rnd.nextInt(3)) { case 0: checkNotContainsNull(q); break; diff --git a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java index c79e994699f..49897626e79 100644 --- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java +++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java @@ -26,6 +26,7 @@ * @bug 8011645 * @summary CopyOnWriteArrayList.COWSubList.subList does not validate range properly */ + import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; diff --git a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java index 7445d26dbb1..be883b11aa1 100644 --- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java +++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java @@ -28,8 +28,10 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; public class EqualsRace { private static void realMain(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java b/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java index addfb0961cd..66f57a377f4 100644 --- a/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java +++ b/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java @@ -28,8 +28,10 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; public class RacingCows { private static void realMain(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/CountDownLatch/Basic.java b/jdk/test/java/util/concurrent/CountDownLatch/Basic.java index 5c32f6c43ca..1553bb85e0b 100644 --- a/jdk/test/java/util/concurrent/CountDownLatch/Basic.java +++ b/jdk/test/java/util/concurrent/CountDownLatch/Basic.java @@ -28,7 +28,8 @@ * @author Seetharam Avadhanam, Martin Buchholz */ -import java.util.concurrent.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; interface AwaiterFactory { diff --git a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java index b6b8d637b2f..da62643e5d5 100644 --- a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java +++ b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java @@ -28,10 +28,17 @@ * @author Martin Buchholz, David Holmes */ -import java.util.*; -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; -import static java.util.concurrent.TimeUnit.*; public class Basic { diff --git a/jdk/test/java/util/concurrent/DelayQueue/Iterate.java b/jdk/test/java/util/concurrent/DelayQueue/Iterate.java index b0fd76d4ad2..7639fcb2bd8 100644 --- a/jdk/test/java/util/concurrent/DelayQueue/Iterate.java +++ b/jdk/test/java/util/concurrent/DelayQueue/Iterate.java @@ -28,9 +28,11 @@ * @author Martin Buchholz */ -import java.io.*; -import java.util.*; -import java.util.concurrent.*; +import java.util.Arrays; +import java.util.Iterator; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; public class Iterate { private static class Godot implements Delayed { diff --git a/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java b/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java index ef835642b5e..0d00c31403e 100644 --- a/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java +++ b/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java @@ -28,7 +28,9 @@ * @author Martin Buchholz */ -import java.util.concurrent.*; +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; public class PollUnexpired { private static class Godot implements Delayed { diff --git a/jdk/test/java/util/concurrent/DelayQueue/Stress.java b/jdk/test/java/util/concurrent/DelayQueue/Stress.java index e4cef482825..8d6145819e2 100644 --- a/jdk/test/java/util/concurrent/DelayQueue/Stress.java +++ b/jdk/test/java/util/concurrent/DelayQueue/Stress.java @@ -21,8 +21,11 @@ * questions. */ -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.DelayQueue; +import java.util.concurrent.Delayed; /** * This is not a regression test, but a stress benchmark test for diff --git a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java index e25435108f9..8af16e2955c 100644 --- a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java +++ b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java @@ -38,7 +38,12 @@ * @summary checks to make sure a pipeline of exchangers passes data. */ -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Exchanger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class ExchangeLoops { static final ExecutorService pool = Executors.newCachedThreadPool(); @@ -66,7 +71,7 @@ public class ExchangeLoops { oneRun(i, iters); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); } diff --git a/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java b/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java index 5a6924c687e..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java @@ -30,13 +30,12 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ + +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -73,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java index 79a869cc3d4..e5afd0a4dfc 100644 --- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java +++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java @@ -38,10 +38,15 @@ * @summary Exercise ExecutorCompletionServiceLoops */ -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class ExecutorCompletionServiceLoops { - static final int POOLSIZE = 100; + static final int POOLSIZE = 100; static final ExecutorService pool = Executors.newFixedThreadPool(POOLSIZE); static final ExecutorCompletionService ecs = @@ -66,7 +71,7 @@ public class ExecutorCompletionServiceLoops { Thread.sleep(100); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); } diff --git a/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java b/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java index 5a6924c687e..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java @@ -30,13 +30,12 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ + +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -73,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/ExecutorService/Invoke.java b/jdk/test/java/util/concurrent/ExecutorService/Invoke.java index 4eac62f715b..185660f56fb 100644 --- a/jdk/test/java/util/concurrent/ExecutorService/Invoke.java +++ b/jdk/test/java/util/concurrent/ExecutorService/Invoke.java @@ -28,9 +28,13 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicLong; public class Invoke { static volatile int passed = 0, failed = 0; diff --git a/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java b/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java index 3c4ff896958..afe3a475410 100644 --- a/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java +++ b/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java @@ -29,10 +29,18 @@ * @author Martin Buchholz */ -import java.util.concurrent.*; -import java.util.*; -import java.security.*; -import static java.util.concurrent.Executors.*; +import static java.util.concurrent.Executors.privilegedCallable; +import static java.util.concurrent.Executors.privilegedCallableUsingCurrentClassLoader; +import static java.util.concurrent.Executors.privilegedThreadFactory; + +import java.security.AccessControlException; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.ProtectionDomain; +import java.util.Random; +import java.util.concurrent.Callable; public class PrivilegedCallables { Callable real; @@ -44,7 +52,7 @@ public class PrivilegedCallables { final Random rnd = new Random(); @SuppressWarnings("serial") - Throwable[] throwables = { + final Throwable[] throwables = { new Exception() {}, new RuntimeException() {}, new Error() {} diff --git a/jdk/test/java/util/concurrent/Executors/Throws.java b/jdk/test/java/util/concurrent/Executors/Throws.java index 402472df366..6852c16f870 100644 --- a/jdk/test/java/util/concurrent/Executors/Throws.java +++ b/jdk/test/java/util/concurrent/Executors/Throws.java @@ -28,12 +28,24 @@ * @author Martin Buchholz */ -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import static java.util.concurrent.Executors.*; +import static java.util.concurrent.Executors.callable; +import static java.util.concurrent.Executors.defaultThreadFactory; +import static java.util.concurrent.Executors.newCachedThreadPool; +import static java.util.concurrent.Executors.newFixedThreadPool; +import static java.util.concurrent.Executors.newScheduledThreadPool; +import static java.util.concurrent.Executors.newSingleThreadExecutor; +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; +import static java.util.concurrent.Executors.privilegedCallable; +import static java.util.concurrent.Executors.unconfigurableExecutorService; +import static java.util.concurrent.Executors.unconfigurableScheduledExecutorService; + import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; +import java.util.concurrent.Callable; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; public class Throws { private static void realMain(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java b/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java index b37664aeaf9..ad92d063da2 100644 --- a/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java +++ b/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java @@ -28,8 +28,13 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; /** * Adapted from Doug Lea, which was... @@ -71,7 +76,7 @@ public class BlockingTaskExecutor { // are blocked. This should cause the tasks to be // interrupted. executor.shutdownNow(); - if (! executor.awaitTermination(5, TimeUnit.SECONDS)) + if (! executor.awaitTermination(5L, TimeUnit.SECONDS)) throw new Error("Executor stuck"); // Wait for the invocation thread to complete. diff --git a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java index 5575bb4505a..12a26b84302 100644 --- a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java +++ b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java @@ -40,13 +40,21 @@ * TIMEOUT msecs to complete. */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.SplittableRandom; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.Callable; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.locks.ReentrantLock; public final class CancelledFutureLoops { static final ExecutorService pool = Executors.newCachedThreadPool(); - static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); + static final SplittableRandom rnd = new SplittableRandom(); static boolean print = false; static final int ITERS = 1000000; static final long TIMEOUT = 100; @@ -61,7 +69,7 @@ public final class CancelledFutureLoops { for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) { System.out.print("Threads: " + i); try { - new FutureLoop(i).test(); + new FutureLoop(i, rnd.split()).test(); } catch (BrokenBarrierException bb) { // OK; ignore @@ -72,19 +80,22 @@ public final class CancelledFutureLoops { Thread.sleep(TIMEOUT); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); } static final class FutureLoop implements Callable { - private int v = rng.next(); + private final int nthreads; + private final SplittableRandom rnd; private final ReentrantLock lock = new ReentrantLock(); private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); private final CyclicBarrier barrier; - private final int nthreads; - FutureLoop(int nthreads) { + private int v; + FutureLoop(int nthreads, SplittableRandom rnd) { this.nthreads = nthreads; + this.rnd = rnd; barrier = new CyclicBarrier(nthreads+1, timer); + v = rnd.nextInt(); } final void test() throws Exception { @@ -100,7 +111,7 @@ public final class CancelledFutureLoops { tooLate = true; // Unbunch some of the cancels if ( (i & 3) == 0) - Thread.sleep(1 + rng.next() % 10); + Thread.sleep(1 + rnd.nextInt(5)); } Object f0 = futures[0].get(); diff --git a/jdk/test/java/util/concurrent/FutureTask/Customized.java b/jdk/test/java/util/concurrent/FutureTask/Customized.java index a1afd9015a1..91223bb03ff 100644 --- a/jdk/test/java/util/concurrent/FutureTask/Customized.java +++ b/jdk/test/java/util/concurrent/FutureTask/Customized.java @@ -28,9 +28,12 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; public class Customized { static final AtomicLong doneCount = new AtomicLong(0); diff --git a/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java b/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java index f8f3d08900a..8c0e21984f8 100644 --- a/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java +++ b/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java @@ -38,9 +38,10 @@ * will never throw TimeoutException. */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) public class DoneTimedGetLoops { @@ -141,8 +142,6 @@ public class DoneTimedGetLoops { failed++; for (StackTraceElement e : thread.getStackTrace()) System.err.println(e); - // Kludge alert - thread.stop(); thread.join(timeoutMillis); } } diff --git a/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java b/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java index 5a6924c687e..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java @@ -30,13 +30,12 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ + +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -73,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/FutureTask/Throw.java b/jdk/test/java/util/concurrent/FutureTask/Throw.java index a6c1f98cf5a..59d643b6dc4 100644 --- a/jdk/test/java/util/concurrent/FutureTask/Throw.java +++ b/jdk/test/java/util/concurrent/FutureTask/Throw.java @@ -27,7 +27,10 @@ * @summary Check exceptional behavior in run and done methods */ -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; public class Throw { diff --git a/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java b/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java index 5c7e48d4b3a..8933ad95dab 100644 --- a/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java +++ b/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java @@ -28,8 +28,8 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.Collection; +import java.util.concurrent.LinkedBlockingQueue; public class ToArray { public static void main(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/Phaser/Basic.java b/jdk/test/java/util/concurrent/Phaser/Basic.java index c516a969b39..951e22fc0ac 100644 --- a/jdk/test/java/util/concurrent/Phaser/Basic.java +++ b/jdk/test/java/util/concurrent/Phaser/Basic.java @@ -39,13 +39,19 @@ * @author Chris Hegarty */ +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.util.Iterator; import java.util.LinkedList; import java.util.concurrent.Phaser; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; -import static java.util.concurrent.TimeUnit.*; public class Basic { @@ -86,25 +92,30 @@ public class Basic { //---------------------------------------------------------------- // Mechanism to get all test threads into "running" mode. //---------------------------------------------------------------- - private static Phaser atTheStartingGate = new Phaser(3); + private static Phaser startingGate = new Phaser(3); private static void toTheStartingGate() { try { - boolean expectNextPhase = false; - if (atTheStartingGate.getUnarrivedParties() == 1) { - expectNextPhase = true; + boolean expectNextPhase = (startingGate.getUnarrivedParties() == 1); + int phase = startingGate.getPhase(); + equal(phase, startingGate.arrive()); + int awaitPhase; + for (boolean interrupted = false;;) { + try { + awaitPhase = startingGate.awaitAdvanceInterruptibly + (phase, 30, SECONDS); + if (interrupted) Thread.currentThread().interrupt(); + break; + } catch (InterruptedException ie) { + interrupted = true; + } } - int phase = atTheStartingGate.getPhase(); - equal(phase, atTheStartingGate.arrive()); - int awaitPhase = atTheStartingGate.awaitAdvanceInterruptibly - (phase, 30, SECONDS); if (expectNextPhase) check(awaitPhase == phase + 1); else check(awaitPhase == phase || awaitPhase == phase + 1); - pass(); } catch (Throwable t) { unexpected(t); - // reset(atTheStartingGate); + // reset(startingGate); throw new Error(t); } } @@ -210,12 +221,23 @@ public class Basic { public void remove() {throw new UnsupportedOperationException();}}; } - private static void realMain(String[] args) throws Throwable { + static class SimpleTimer { + long startTime = System.nanoTime(); + long elapsedMillis() { + long now = System.nanoTime(); + long elapsed = NANOSECONDS.toMillis(now - startTime); + startTime = now; + return elapsed; + } + void printElapsed() { System.out.println(elapsedMillis() + " ms"); } + } + private static void realMain(String[] args) throws Throwable { + SimpleTimer timer = new SimpleTimer(); Thread.currentThread().setName("mainThread"); //---------------------------------------------------------------- - // Normal use + System.out.print("Normal use: "); //---------------------------------------------------------------- try { Phaser phaser = new Phaser(3); @@ -243,9 +265,10 @@ public class Basic { equal(phaser.getArrivedParties(), 0); } } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); //---------------------------------------------------------------- - // One thread interrupted + System.out.print("One thread interrupted: "); //---------------------------------------------------------------- try { Phaser phaser = new Phaser(3); @@ -268,9 +291,10 @@ public class Basic { phase++; } } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); //---------------------------------------------------------------- - // Phaser is terminated while threads are waiting + System.out.print("Phaser is terminated while threads are waiting: "); //---------------------------------------------------------------- try { for (int i = 0; i < 10; i++) { @@ -291,9 +315,10 @@ public class Basic { equal(phaser.getArrivedParties(), arrivedParties); } } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); //---------------------------------------------------------------- - // Adds new unarrived parties to this phaser + System.out.print("Adds new unarrived parties to this phaser: "); //---------------------------------------------------------------- try { Phaser phaser = new Phaser(1); @@ -301,7 +326,7 @@ public class Basic { LinkedList arriverList = new LinkedList(); int phase = phaser.getPhase(); for (int i = 1; i < 5; i++) { - atTheStartingGate = new Phaser(1+(3*i)); + startingGate = new Phaser(1+(3*i)); check(phaser.getPhase() == phase); // register 3 more phaser.register(); phaser.register(); phaser.register(); @@ -323,32 +348,34 @@ public class Basic { arriverList.clear(); phase++; } - atTheStartingGate = new Phaser(3); + startingGate = new Phaser(3); } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); //---------------------------------------------------------------- - // One thread timed out + System.out.print("One thread timed out: "); //---------------------------------------------------------------- try { Phaser phaser = new Phaser(3); Iterator arrivers = arriverIterator(phaser); - for (long timeout : new long[] { 0L, 5L }) { - for (int i = 0; i < 2; i++) { - Awaiter a1 = awaiter(phaser, timeout, SECONDS); a1.start(); - Arriver a2 = arrivers.next(); a2.start(); - toTheStartingGate(); - a1.join(); - checkResult(a1, TimeoutException.class); - phaser.arrive(); - a2.join(); - checkResult(a2, null); - check(!phaser.isTerminated()); - } + for (long timeout : new long[] { 0L, 12L }) { + Awaiter a1 = awaiter(phaser, timeout, MILLISECONDS); + a1.start(); + Arriver a2 = arrivers.next(); + a2.start(); + toTheStartingGate(); + a1.join(); + checkResult(a1, TimeoutException.class); + phaser.arrive(); + a2.join(); + checkResult(a2, null); + check(!phaser.isTerminated()); } } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); //---------------------------------------------------------------- - // Barrier action completed normally + System.out.print("Barrier action completed normally: "); //---------------------------------------------------------------- try { final AtomicInteger count = new AtomicInteger(0); @@ -390,15 +417,43 @@ public class Basic { checkTerminated(phaser); } } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); } //--------------------- Infrastructure --------------------------- + + /** + * A debugging tool to print stack traces of most threads, as jstack does. + * Uninteresting threads are filtered out. + */ + static void dumpTestThreads() { + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + System.err.println("------ stacktrace dump start ------"); + for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { + String name = info.getThreadName(); + if ("Signal Dispatcher".equals(name)) + continue; + if ("Reference Handler".equals(name) + && info.getLockName().startsWith("java.lang.ref.Reference$Lock")) + continue; + if ("Finalizer".equals(name) + && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock")) + continue; + if ("process reaper".equals(name)) + continue; + if (name != null && name.startsWith("ForkJoinPool.commonPool-worker")) + continue; + System.err.print(info); + } + System.err.println("------ stacktrace dump end ------"); + } + static volatile int passed = 0, failed = 0; static void pass() {passed++;} static void fail() {failed++; Thread.dumpStack();} static void fail(String msg) {System.out.println(msg); fail();} - static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static void unexpected(Throwable t) {failed++; t.printStackTrace(); dumpTestThreads();} static void check(boolean cond) {if (cond) pass(); else fail();} static void equal(Object x, Object y) { if (x == null ? y == null : x.equals(y)) pass(); diff --git a/jdk/test/java/util/concurrent/Phaser/FickleRegister.java b/jdk/test/java/util/concurrent/Phaser/FickleRegister.java index c3bc7dda50e..9ee00946f1d 100644 --- a/jdk/test/java/util/concurrent/Phaser/FickleRegister.java +++ b/jdk/test/java/util/concurrent/Phaser/FickleRegister.java @@ -37,9 +37,9 @@ * @run main FickleRegister 300 */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.util.ArrayList; +import java.util.concurrent.Phaser; +import java.util.concurrent.atomic.AtomicLong; public class FickleRegister { final AtomicLong count = new AtomicLong(0); diff --git a/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java b/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java index d9c8954d05d..746f60cff59 100644 --- a/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java +++ b/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java @@ -36,8 +36,8 @@ * @summary stress test for arrivals in a tiered phaser * @run main TieredArriveLoops 300 */ -import java.util.*; -import java.util.concurrent.*; + +import java.util.concurrent.Phaser; public class TieredArriveLoops { final long testDurationMillisDefault = 10L * 1000L; diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java index fa3bcbc30af..d9da860cb70 100644 --- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java @@ -28,8 +28,12 @@ * @summary Check effectiveness of RemoveOnCancelPolicy */ -import java.util.concurrent.*; import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; /** * Simple timer cancellation test. Submits tasks to a scheduled executor @@ -60,7 +64,7 @@ public class BasicCancelTest { equal(tpe.getActiveCount(), 0); equal(tpe.getPoolSize(), 0); equal(tpe.getTaskCount(), tpe.getCompletedTaskCount()); - check(tpe.awaitTermination(0, TimeUnit.SECONDS)); + check(tpe.awaitTermination(0L, TimeUnit.SECONDS)); } catch (Throwable t) { unexpected(t); } } diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java index 826ba084c55..12528a0efdd 100644 --- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java @@ -27,7 +27,13 @@ * @summary Test ScheduledThreadPoolExecutor.decorateTask */ -import java.util.concurrent.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; public class DecorateTask { diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java index eae050aefc7..36af2e10e5a 100644 --- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java @@ -37,7 +37,10 @@ * @summary Check for long overflow in task time comparison. */ -import java.util.concurrent.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class DelayOverflow { static void waitForNanoTimeTick() { diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java index be7488aa277..c39fcc07cf3 100644 --- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java @@ -36,8 +36,14 @@ * @summary Ensure that waiting pool threads don't retain refs to tasks. */ -import java.lang.ref.*; -import java.util.concurrent.*; +import java.lang.ref.WeakReference; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; public class GCRetention { /** @@ -110,7 +116,7 @@ public class GCRetention { Thread.sleep(10); } pool.shutdown(); - pool.awaitTermination(10, TimeUnit.SECONDS); + pool.awaitTermination(10L, TimeUnit.SECONDS); if (cleared < size) throw new Error(String.format ("references to %d/%d tasks retained (\"leaked\")", diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java index a1290877b8b..05038fdaf6f 100644 --- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java @@ -21,7 +21,7 @@ * questions. */ -import java.util.concurrent.*; +import java.util.concurrent.ScheduledThreadPoolExecutor; /** * This is not a regression test, but a stress benchmark test for diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java index c412dfecc9d..2a610edbf22 100644 --- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java @@ -37,10 +37,14 @@ * @summary Ensure relative sanity when zero core threads */ -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.*; -import java.util.concurrent.locks.*; -import java.lang.reflect.*; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.lang.reflect.Field; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; public class ZeroCoreThreads { static boolean hasWaiters(ReentrantLock lock, Condition condition) { diff --git a/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java index 379192326f1..deb4b6b1616 100644 --- a/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java +++ b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java @@ -27,8 +27,10 @@ * @summary Checks that fairness setting is respected. */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; public class Fairness { private static void testFairness(boolean fair, diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java index d89ee28333e..2418acc18c5 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java @@ -29,11 +29,19 @@ * @author Martin Buchholz */ -import java.security.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import static java.util.concurrent.TimeUnit.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.security.Permission; +import java.util.Random; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicInteger; public class ConfigChanges { static final ThreadGroup tg = new ThreadGroup("pool"); @@ -86,7 +94,7 @@ public class ConfigChanges { equal(tpe.getActiveCount(), 0); equal(tpe.getPoolSize(), 0); equal(tpe.getTaskCount(), tpe.getCompletedTaskCount()); - check(tpe.awaitTermination(0, SECONDS)); + check(tpe.awaitTermination(0L, SECONDS)); } catch (Throwable t) { unexpected(t); } } diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java index 6ac437a9561..8b80814e1d7 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java @@ -28,7 +28,12 @@ * @author Martin Buchholz */ -import java.util.concurrent.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class CoreThreadTimeOut { @@ -84,7 +89,7 @@ public class CoreThreadTimeOut { equal(countExecutorThreads(), 0); tpe.shutdown(); check(tpe.allowsCoreThreadTimeOut()); - check(tpe.awaitTermination(10, TimeUnit.SECONDS)); + check(tpe.awaitTermination(10L, TimeUnit.SECONDS)); System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new Exception("Some tests failed"); diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java index 6a253e989fd..9fded6a58d4 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java @@ -28,8 +28,15 @@ * @author Martin Buchholz */ -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; public class Custom { static volatile int passed = 0, failed = 0; @@ -99,7 +106,7 @@ public class Custom { equal(countExecutorThreads(), threadCount); equal(CustomTask.births.get(), threadCount); tpe.shutdown(); - tpe.awaitTermination(120, TimeUnit.SECONDS); + tpe.awaitTermination(120L, TimeUnit.SECONDS); Thread.sleep(1000); equal(countExecutorThreads(), 0); @@ -109,7 +116,7 @@ public class Custom { equal(CustomSTPE.decorations.get(), threadCount); equal(countExecutorThreads(), threadCount); stpe.shutdown(); - stpe.awaitTermination(120, TimeUnit.SECONDS); + stpe.awaitTermination(120L, TimeUnit.SECONDS); Thread.sleep(1000); equal(countExecutorThreads(), 0); diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java index 611db366a08..325ecef58a2 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java @@ -37,7 +37,10 @@ * @summary Should be able to shutdown a pool when worker creation failed. */ -import java.util.concurrent.*; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class FlakyThreadFactory { void test(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java index fdcd028ce48..ec08802d220 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java @@ -28,7 +28,9 @@ * @author Martin Buchholz */ -import java.util.concurrent.*; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class ModifyCorePoolSize { static void awaitPoolSize(ThreadPoolExecutor pool, int n) { diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java index 9eeda4927d7..7cda336e2b2 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java @@ -30,9 +30,18 @@ // based on a test kindly provided by Holger Hoffstaette -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + public class ScheduledTickleService { // We get intermittent ClassCastException if greater than 1 diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java index 1fdc930fa2d..9211ff28d95 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java @@ -27,7 +27,10 @@ * @summary non-idle worker threads should not be interrupted */ -import java.util.concurrent.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class SelfInterrupt { void test(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java index 780aa4eeb06..bcba32000da 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java @@ -33,8 +33,10 @@ // add a call to Thread.yield() before the call to t.start() // in ThreadPoolExecutor.addWorker. -import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class ShutdownNowExecuteRace { static volatile boolean quit = false; diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java index 2f69cf9a6be..1b485867ce2 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java @@ -38,9 +38,12 @@ * be kept alive to service a delayed task waiting in the queue. */ -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.*; -import java.util.concurrent.atomic.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicLong; public class ThreadRestarts { public static void main(String[] args) throws Exception { @@ -60,7 +63,8 @@ public class ThreadRestarts { MILLISECONDS.sleep(100L); } finally { stpe.shutdownNow(); - stpe.awaitTermination(Long.MAX_VALUE, MILLISECONDS); + if (!stpe.awaitTermination(60L, SECONDS)) + throw new AssertionError("timed out"); } if (ctf.count.get() > 1) throw new AssertionError( diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java index 8a45bfcc625..56a1c9cf551 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java @@ -28,10 +28,22 @@ * @author Martin Buchholz */ -import java.security.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; +import java.security.Permission; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock; public class ThrowingTasks { @@ -151,7 +163,7 @@ public class ThrowingTasks { equal(tpe.getActiveCount(), 0); equal(tpe.getPoolSize(), 0); equal(tpe.getTaskCount(), tpe.getCompletedTaskCount()); - check(tpe.awaitTermination(0, TimeUnit.SECONDS)); + check(tpe.awaitTermination(0L, TimeUnit.SECONDS)); } catch (Throwable t) { unexpected(t); } } diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java index 94ca1e3857f..8778b401d27 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java @@ -28,8 +28,10 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class TimeOutShrink { static void checkPoolSizes(ThreadPoolExecutor pool, @@ -61,7 +63,7 @@ public class TimeOutShrink { Thread.sleep(100); checkPoolSizes(pool, n, n, 2*n); pool.shutdown(); - pool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + check(pool.awaitTermination(60L, TimeUnit.SECONDS)); } //--------------------- Infrastructure --------------------------- diff --git a/jdk/test/java/util/concurrent/TimeUnit/Basic.java b/jdk/test/java/util/concurrent/TimeUnit/Basic.java index c218f6f99b5..444a61c614c 100644 --- a/jdk/test/java/util/concurrent/TimeUnit/Basic.java +++ b/jdk/test/java/util/concurrent/TimeUnit/Basic.java @@ -27,10 +27,22 @@ * @author Martin Buchholz */ -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import static java.util.concurrent.TimeUnit.*; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; public class Basic { private static void realMain(String[] args) throws Throwable { diff --git a/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java b/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java index 8728224ce8e..9345ffadde7 100644 --- a/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java +++ b/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java @@ -31,9 +31,20 @@ * accessible fields in different locations with/without a security * manager */ -import java.util.concurrent.atomic.*; -import java.lang.reflect.*; -import java.security.*; + +import java.lang.reflect.Field; +import java.security.AccessControlException; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; public class AtomicUpdaters { enum TYPE { INT, LONG, REF } @@ -76,9 +87,9 @@ public class AtomicUpdaters { // Would like to test a public volatile in a class in another // package - but of course there aren't any - new Config(java.util.concurrent.atomic.AtomicInteger.class, "value", "private", hasSM ? false : true, false, "private int field of class in different package", TYPE.INT), - new Config(java.util.concurrent.atomic.AtomicLong.class, "value", "private", hasSM ? false : true, false, "private long field of class in different package", TYPE.LONG), - new Config(java.util.concurrent.atomic.AtomicReference.class, "value", "private", hasSM ? false : true, false, "private reference field of class in different package", TYPE.REF), + new Config(AtomicInteger.class, "value", "private", hasSM ? false : true, false, "private int field of class in different package", TYPE.INT), + new Config(AtomicLong.class, "value", "private", hasSM ? false : true, false, "private long field of class in different package", TYPE.LONG), + new Config(AtomicReference.class, "value", "private", hasSM ? false : true, false, "private reference field of class in different package", TYPE.REF), }; } diff --git a/jdk/test/java/util/concurrent/atomic/Lazy.java b/jdk/test/java/util/concurrent/atomic/Lazy.java index aadaff2be60..a528589534d 100644 --- a/jdk/test/java/util/concurrent/atomic/Lazy.java +++ b/jdk/test/java/util/concurrent/atomic/Lazy.java @@ -27,8 +27,16 @@ * @summary lazySet methods */ -import java.util.concurrent.atomic.*; -import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerArray; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongArray; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; public class Lazy { volatile int ii; diff --git a/jdk/test/java/util/concurrent/atomic/Serial.java b/jdk/test/java/util/concurrent/atomic/Serial.java index e0a39678189..2aa6cd4a7e1 100644 --- a/jdk/test/java/util/concurrent/atomic/Serial.java +++ b/jdk/test/java/util/concurrent/atomic/Serial.java @@ -44,7 +44,6 @@ import java.io.IOException; * Basic test to exercise the j.u.c.atomic classes that use serialization * proxies. */ - public class Serial { public static void main(String[] args) { diff --git a/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java b/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java index f4580d524ac..372febce6b8 100644 --- a/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java +++ b/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java @@ -36,17 +36,17 @@ * @author Doug Lea * @bug 8004138 * @summary Check if ForkJoinPool table leaks thrown exceptions. - * @run main/othervm/timeout=1200 -Xmx32m FJExceptionTableLeak + * @run main/othervm -Xmx2200k FJExceptionTableLeak */ -import java.util.concurrent.*; + +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RecursiveAction; public class FJExceptionTableLeak { - // TODO: make this test use less time! - - // Run with TASKS_PER_STEP * 40 < Xmx < STEPS * TASKS_PER_STEP * 40 - // These work for Xmx32m: - static final int STEPS = 2000; - static final int TASKS_PER_STEP = 1000; + // This test was observed to fail with jdk7 -Xmx2200k, + // using STEPS = 220 and TASKS_PER_STEP = 100 + static final int STEPS = 500; + static final int TASKS_PER_STEP = 100; static class FailingTaskException extends RuntimeException {} static class FailingTask extends RecursiveAction { diff --git a/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java b/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java index 823f72e50c8..a8f7bbe5daf 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java +++ b/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java @@ -34,104 +34,72 @@ /* * @test * @bug 4486658 - * @run main/timeout=7200 CheckedLockLoops * @summary basic safety and liveness of ReentrantLocks, and other locks based on them */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; public final class CheckedLockLoops { - static final ExecutorService pool = Executors.newCachedThreadPool(); - static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); - static boolean print = false; - static boolean doBuiltin = false; + static ExecutorService pool; + static final SplittableRandom rnd = new SplittableRandom(); public static void main(String[] args) throws Exception { - int maxThreads = 5; - int iters = 100000; - - if (args.length > 0) - maxThreads = Integer.parseInt(args[0]); - - rng.setSeed(3122688L); - - print = false; - System.out.println("Warmup..."); - oneTest(3, 10000); - Thread.sleep(1000); - oneTest(2, 10000); - Thread.sleep(100); - oneTest(1, 100000); - Thread.sleep(100); - oneTest(1, 100000); - Thread.sleep(1000); - print = true; + final int maxThreads = (args.length > 0) + ? Integer.parseInt(args[0]) + : 5; + int iters = 3000; + pool = Executors.newCachedThreadPool(); for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) { - System.out.println("Threads:" + i); oneTest(i, iters / i); - Thread.sleep(100); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(10L, SECONDS)) throw new Error(); + pool = null; } static void oneTest(int nthreads, int iters) throws Exception { - int v = rng.next(); - if (doBuiltin) { - if (print) - System.out.print("builtin lock "); - new BuiltinLockLoop().test(v, nthreads, iters); - Thread.sleep(10); - } + System.out.println("Threads: " + nthreads); + int v = rnd.nextInt(); + System.out.print("builtin lock "); + new BuiltinLockLoop().test(v, nthreads, iters); - if (print) - System.out.print("ReentrantLock "); + System.out.print("ReentrantLock "); new ReentrantLockLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("Mutex "); + System.out.print("Mutex "); new MutexLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("ReentrantWriteLock "); + System.out.print("ReentrantWriteLock "); new ReentrantWriteLockLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("ReentrantReadWriteLock"); + System.out.print("ReentrantReadWriteLock"); new ReentrantReadWriteLockLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("Semaphore "); + System.out.print("Semaphore "); new SemaphoreLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("fair Semaphore "); + System.out.print("fair Semaphore "); new FairSemaphoreLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("FairReentrantLock "); + System.out.print("FairReentrantLock "); new FairReentrantLockLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("FairRWriteLock "); + System.out.print("FairRWriteLock "); new FairReentrantWriteLockLoop().test(v, nthreads, iters); - Thread.sleep(10); - if (print) - System.out.print("FairRReadWriteLock "); + System.out.print("FairRReadWriteLock "); new FairReentrantReadWriteLockLoop().test(v, nthreads, iters); - Thread.sleep(10); } abstract static class LockLoop implements Runnable { @@ -164,13 +132,11 @@ public final class CheckedLockLoops { barrier.await(); barrier.await(); long time = timer.getTime(); - if (print) { - long tpi = time / (iters * nthreads); - System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update"); - // double secs = (double)(time) / 1000000000.0; - // System.out.print("\t " + secs + "s run time"); - System.out.println(); - } + long tpi = time / (iters * nthreads); + System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update"); + // double secs = (double)(time) / 1000000000.0; + // System.out.print("\t " + secs + "s run time"); + System.out.println(); if (result == 0) // avoid overoptimization System.out.println("useless result: " + result); @@ -322,6 +288,7 @@ public final class CheckedLockLoops { return sum; } } + private static class FairSemaphoreLoop extends LockLoop { private final Semaphore sem = new Semaphore(1, true); final int loop(int n) { @@ -373,7 +340,6 @@ public final class CheckedLockLoops { } return sum; } - } private static class FairReentrantReadWriteLockLoop extends LockLoop { @@ -407,6 +373,5 @@ public final class CheckedLockLoops { } return sum; } - } } diff --git a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java index 59c99855085..cf1605197cf 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java +++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java @@ -28,9 +28,14 @@ * @author Martin Buchholz */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; +import java.util.Random; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.AbstractQueuedLongSynchronizer; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; /** * This uses a variant of the standard Mutex demo, except with a @@ -86,7 +91,7 @@ public class FlakyMutex implements Lock { } catch (Throwable t) { unexpected(t); }}});} barrier.await(); es.shutdown(); - check(es.awaitTermination(30, TimeUnit.SECONDS)); + check(es.awaitTermination(30L, TimeUnit.SECONDS)); } private static class FlakySync extends AbstractQueuedLongSynchronizer { diff --git a/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java b/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java index d9859f30066..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java @@ -31,13 +31,11 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -74,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/locks/Lock/Mutex.java b/jdk/test/java/util/concurrent/locks/Lock/Mutex.java index f00148a8995..40bb16064a8 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/Mutex.java +++ b/jdk/test/java/util/concurrent/locks/Lock/Mutex.java @@ -31,11 +31,13 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.concurrent.atomic.*; -import java.io.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.atomic.AtomicInteger; +import java.io.IOException; +import java.io.ObjectInputStream; /** * A sample user extension of AbstractQueuedSynchronizer. diff --git a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java index 9c0431f4d20..9d7fc654121 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java +++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java @@ -26,7 +26,8 @@ * @summary Repeated timed tryAcquire shouldn't hang. */ -import java.util.concurrent.*; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; public class TimedAcquire { public static void main(String[] args) throws Exception { diff --git a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java index 8d6f769cd67..a3440ec8b8d 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java +++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java @@ -40,7 +40,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.Reader; import java.lang.ref.WeakReference; -import java.util.Random; +import java.util.SplittableRandom; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; @@ -187,7 +187,7 @@ public class TimedAcquireLeak { final String childClassName = Job.class.getName(); final String classToCheckForLeaks = Job.classToCheckForLeaks(); final String uniqueID = - String.valueOf(new Random().nextInt(Integer.MAX_VALUE)); + String.valueOf(new SplittableRandom().nextInt(Integer.MAX_VALUE)); final String[] jobCmd = { java, "-Xmx8m", "-XX:+UsePerfData", @@ -270,7 +270,7 @@ public class TimedAcquireLeak { for (int i = 0; i < threads; i++) new Thread() { public void run() { try { - final Random rnd = new Random(); + final SplittableRandom rnd = new SplittableRandom(); for (int j = 0; j < iterations; j++) { if (j == iterations/10 || j == iterations - 1) { cb.await(); // Quiesce diff --git a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java index 74c77060b2e..1e44e4a5d13 100644 --- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java +++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java @@ -41,6 +41,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; +import java.util.SplittableRandom; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -49,7 +50,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.locks.LockSupport; public final class ParkLoops { - static final int THREADS = 4; // must be power of two + static final int THREADS = 4; // static final int ITERS = 2_000_000; // static final int TIMEOUT = 3500; // in seconds static final int ITERS = 100_000; @@ -64,18 +65,19 @@ public final class ParkLoops { private final AtomicReferenceArray threads; private final CountDownLatch done; + private final SplittableRandom rnd; - Parker(AtomicReferenceArray threads, CountDownLatch done) { - this.threads = threads; - this.done = done; + Parker(AtomicReferenceArray threads, + CountDownLatch done, + SplittableRandom rnd) { + this.threads = threads; this.done = done; this.rnd = rnd; } public void run() { - final SimpleRandom rng = new SimpleRandom(); final Thread current = Thread.currentThread(); for (int k = ITERS, j; k > 0; k--) { do { - j = rng.next() & (THREADS - 1); + j = rnd.nextInt(THREADS); } while (!threads.compareAndSet(j, null, current)); do { // handle spurious wakeups LockSupport.park(); @@ -94,16 +96,17 @@ public final class ParkLoops { private final AtomicReferenceArray threads; private final CountDownLatch done; + private final SplittableRandom rnd; - Unparker(AtomicReferenceArray threads, CountDownLatch done) { - this.threads = threads; - this.done = done; + Unparker(AtomicReferenceArray threads, + CountDownLatch done, + SplittableRandom rnd) { + this.threads = threads; this.done = done; this.rnd = rnd; } public void run() { - final SimpleRandom rng = new SimpleRandom(); for (int n = 0; (n++ & 0xff) != 0 || done.getCount() > 0;) { - int j = rng.next() & (THREADS - 1); + int j = rnd.nextInt(THREADS); Thread parker = threads.get(j); if (parker != null && threads.compareAndSet(j, parker, null)) { @@ -114,12 +117,13 @@ public final class ParkLoops { } public static void main(String[] args) throws Exception { + final SplittableRandom rnd = new SplittableRandom(); final ExecutorService pool = Executors.newCachedThreadPool(); final AtomicReferenceArray threads = new AtomicReferenceArray<>(THREADS); final CountDownLatch done = new CountDownLatch(THREADS); - final Runnable parker = new Parker(threads, done); - final Runnable unparker = new Unparker(threads, done); + final Runnable parker = new Parker(threads, done, rnd.split()); + final Runnable unparker = new Unparker(threads, done, rnd.split()); for (int i = 0; i < THREADS; i++) { pool.submit(parker); pool.submit(unparker); @@ -142,22 +146,4 @@ public final class ParkLoops { System.err.print(threadInfo); } } - - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } } diff --git a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java index 48aeebd5a73..dbbc2fbb638 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java @@ -33,51 +33,45 @@ /* * @test - * @bug 4486658 - * @run main/timeout=2800 CancelledLockLoops + * @bug 4486658 8040928 8140468 * @summary tests ReentrantLock.lockInterruptibly. - * Checks for responsiveness of locks to interrupts. Runs under the - * assumption that ITERS computations require more than TIMEOUT msecs - * to complete. + * Checks for responsiveness of locks to interrupts. */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.locks.ReentrantLock; public final class CancelledLockLoops { - static final Random rng = new Random(); - static boolean print = false; - static final int ITERS = 1000000; - static final long TIMEOUT = 100; + static final SplittableRandom rnd = new SplittableRandom(); public static void main(String[] args) throws Exception { - int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5; + final int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5; + final int reps = 1; // increase for stress testing - print = true; - - for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) { - System.out.print("Threads: " + i); - try { - new ReentrantLockLoop(i).test(); + for (int j = 0; j < reps; j++) { + for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) { + new Loops(i).test(); } - catch (BrokenBarrierException bb) { - // OK, ignore - } - Thread.sleep(TIMEOUT); } } - static final class ReentrantLockLoop implements Runnable { - private int v = rng.nextInt(); - private int completed; + static final class Loops implements Runnable { + private final boolean print = false; + private volatile boolean done = false; + private int v = rnd.nextInt(); + private int completed = 0; private volatile int result = 17; private final ReentrantLock lock = new ReentrantLock(); private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); private final CyclicBarrier barrier; private final int nthreads; - ReentrantLockLoop(int nthreads) { + private volatile Throwable fail = null; + Loops(int nthreads) { this.nthreads = nthreads; + if (print) System.out.print("Threads: " + nthreads); barrier = new CyclicBarrier(nthreads+1, timer); } @@ -88,15 +82,15 @@ public final class CancelledLockLoops { for (int i = 0; i < threads.length; ++i) threads[i].start(); Thread[] cancels = threads.clone(); - Collections.shuffle(Arrays.asList(cancels), rng); barrier.await(); - Thread.sleep(TIMEOUT); + Thread.sleep(rnd.nextInt(5)); for (int i = 0; i < cancels.length-2; ++i) { cancels[i].interrupt(); // make sure all OK even when cancellations spaced out if ( (i & 3) == 0) - Thread.sleep(1 + rng.nextInt(10)); + Thread.sleep(1 + rnd.nextInt(5)); } + done = true; barrier.await(); if (print) { long time = timer.getTime(); @@ -117,20 +111,25 @@ public final class CancelledLockLoops { int r = result; if (r == 0) // avoid overoptimization System.out.println("useless result: " + r); + if (fail != null) throw new RuntimeException(fail); } public final void run() { try { barrier.await(); + boolean interrupted = false; + long startTime = System.nanoTime(); int sum = v; int x = 0; - int n = ITERS; - boolean done = false; - do { + while (!done || Thread.currentThread().isInterrupted()) { try { lock.lockInterruptibly(); } catch (InterruptedException ie) { + interrupted = true; + if (print) + System.out.printf("interrupted after %d millis%n", + NANOSECONDS.toMillis(System.nanoTime() - startTime)); break; } try { @@ -140,8 +139,11 @@ public final class CancelledLockLoops { lock.unlock(); } sum += LoopHelpers.compute2(x); - } while (n-- > 0); - if (n <= 0) { + } + if (!interrupted) { + if (print) + System.out.printf("completed after %d millis%n", + NANOSECONDS.toMillis(System.nanoTime() - startTime)); lock.lock(); try { ++completed; @@ -153,9 +155,9 @@ public final class CancelledLockLoops { barrier.await(); result += sum; } - catch (Exception ex) { - ex.printStackTrace(); - return; + catch (Throwable ex) { + fail = ex; + throw new RuntimeException(ex); } } } diff --git a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java index c0a62906d7b..b8d49c73863 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java @@ -38,13 +38,17 @@ * @summary Checks for missed signals by locking and unlocking each of an array of locks once per thread */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.ReentrantLock; public final class LockOncePerThreadLoops { static final ExecutorService pool = Executors.newCachedThreadPool(); - static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); + static final SplittableRandom rnd = new SplittableRandom(); static boolean print = false; static int nlocks = 50000; static int nthreads = 100; @@ -65,12 +69,12 @@ public final class LockOncePerThreadLoops { Thread.sleep(100); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); } static final class ReentrantLockLoop implements Runnable { - private int v = rng.next(); + private int v = rnd.nextInt(); private volatile int result = 17; final ReentrantLock[]locks = new ReentrantLock[nlocks]; diff --git a/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java b/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java index 5a6924c687e..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java @@ -30,13 +30,12 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ + +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -73,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java index bd650022cd9..9e6ed4533f7 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java @@ -38,13 +38,17 @@ * @summary multiple threads using a single lock */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.ReentrantLock; public final class SimpleReentrantLockLoops { static final ExecutorService pool = Executors.newCachedThreadPool(); - static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); + static final SplittableRandom rnd = new SplittableRandom(); static boolean print = false; static int iters = 1000000; @@ -66,12 +70,12 @@ public final class SimpleReentrantLockLoops { } } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, SECONDS)) throw new Error(); } static final class ReentrantLockLoop implements Runnable { - private int v = rng.next(); + private int v = rnd.nextInt(); private volatile int result = 17; private final ReentrantLock lock = new ReentrantLock(); private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); diff --git a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java index f6a47215b64..3e4e0cfb059 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java @@ -33,27 +33,26 @@ /* * @test - * @bug 4486658 5031862 + * @bug 4486658 5031862 8140471 * @run main TimeoutLockLoops * @summary Checks for responsiveness of locks to timeouts. - * Runs under the assumption that ITERS computations require more than - * TIMEOUT msecs to complete, which seems to be a safe assumption for - * another decade. */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; public final class TimeoutLockLoops { static final ExecutorService pool = Executors.newCachedThreadPool(); - static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); + static final SplittableRandom rnd = new SplittableRandom(); static boolean print = false; - static final int ITERS = Integer.MAX_VALUE; - static final long TIMEOUT = 100; + static final long TIMEOUT = 10; public static void main(String[] args) throws Exception { - int maxThreads = 100; + int maxThreads = 8; if (args.length > 0) maxThreads = Integer.parseInt(args[0]); @@ -62,21 +61,20 @@ public final class TimeoutLockLoops { for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) { System.out.print("Threads: " + i); new ReentrantLockLoop(i).test(); - Thread.sleep(10); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(60L, TimeUnit.SECONDS)) throw new Error(); } static final class ReentrantLockLoop implements Runnable { - private int v = rng.next(); - private volatile boolean completed; + private int v = rnd.nextInt(); private volatile int result = 17; private final ReentrantLock lock = new ReentrantLock(); private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); private final CyclicBarrier barrier; private final int nthreads; + private volatile Throwable fail = null; ReentrantLockLoop(int nthreads) { this.nthreads = nthreads; barrier = new CyclicBarrier(nthreads+1, timer); @@ -89,7 +87,7 @@ public final class TimeoutLockLoops { lock.unlock(); } barrier.await(); - Thread.sleep(TIMEOUT); + Thread.sleep(rnd.nextInt(5)); while (!lock.tryLock()); // Jam lock // lock.lock(); barrier.await(); @@ -99,11 +97,10 @@ public final class TimeoutLockLoops { System.out.println("\t " + secs + "s run time"); } - if (completed) - throw new Error("Some thread completed instead of timing out"); int r = result; if (r == 0) // avoid overoptimization System.out.println("useless result: " + r); + if (fail != null) throw new RuntimeException(fail); } public final void run() { @@ -111,15 +108,8 @@ public final class TimeoutLockLoops { barrier.await(); int sum = v; int x = 17; - int n = ITERS; final ReentrantLock lock = this.lock; - for (;;) { - if (x != 0) { - if (n-- <= 0) - break; - } - if (!lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) - break; + while (lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) { try { v = x = LoopHelpers.compute1(v); } @@ -128,14 +118,12 @@ public final class TimeoutLockLoops { } sum += LoopHelpers.compute2(x); } - if (n <= 0) - completed = true; barrier.await(); result += sum; } - catch (Exception ex) { - ex.printStackTrace(); - return; + catch (Throwable ex) { + fail = ex; + throw new RuntimeException(ex); } } } diff --git a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java index 92714ba3604..4d1c8d9ba02 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java @@ -27,8 +27,9 @@ * @summary Check that regaining a read lock succeeds after a write * lock attempt times out */ -import java.util.concurrent.locks.*; -import java.util.concurrent.*; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class Bug6571733 { diff --git a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java index 1cbc3ec9f2e..6341a817257 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java @@ -28,10 +28,20 @@ * @author Martin Buchholz */ -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Random; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; // I am the Cownt, and I lahve to cownt. public class Count { @@ -92,7 +102,7 @@ public class Count { barrier.await(); } catch (Throwable t) { unexpected(t); }}});} es.shutdown(); - check(es.awaitTermination(10, TimeUnit.SECONDS)); + check(es.awaitTermination(10L, TimeUnit.SECONDS)); } void testReentrantLocks(final boolean fair, diff --git a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java index 5a6924c687e..ed3d8719dff 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java @@ -30,13 +30,12 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ + +import java.util.concurrent.atomic.AtomicLong; + /** * Misc utilities in JSR166 performance tests */ - -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - class LoopHelpers { // Some mindless computation to do between synchronizations... @@ -73,28 +72,6 @@ class LoopHelpers { return x; } - /** - * An actually useful random number generator, but unsynchronized. - * Basically same as java.util.Random. - */ - public static class SimpleRandom { - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - static final AtomicLong seq = new AtomicLong(1); - private long seed = System.nanoTime() + seq.getAndIncrement(); - - public void setSeed(long s) { - seed = s; - } - - public int next() { - long nextseed = (seed * multiplier + addend) & mask; - seed = nextseed; - return ((int)(nextseed >>> 17)) & 0x7FFFFFFF; - } - } - public static class BarrierTimer implements Runnable { public volatile long startTime; public volatile long endTime; diff --git a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java index c12f9a509aa..f82327ac8a4 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java @@ -34,7 +34,6 @@ /* * @test * @bug 4486658 - * @run main/timeout=4700 MapLoops * @summary Exercise multithreaded maps, by default ConcurrentHashMap. * Multithreaded hash table test. Each thread does a random walk * though elements of "key" array. On each iteration, it checks if @@ -44,15 +43,20 @@ * parsing from command line.) */ -import java.util.*; -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.Map; +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class MapLoops { static final int NKEYS = 100000; static int pinsert = 60; static int premove = 2; static int maxThreads = 5; - static int nops = 1000000; + static int nops = 10000; // 1000000 static int removesPerMaxRandom; static int insertsPerMaxRandom; @@ -89,10 +93,10 @@ public class MapLoops { System.out.println("Using " + mapClass.getName()); - Random rng = new Random(315312); + SplittableRandom rnd = new SplittableRandom(); Integer[] key = new Integer[NKEYS]; for (int i = 0; i < key.length; ++i) - key[i] = new Integer(rng.nextInt()); + key[i] = new Integer(rnd.nextInt()); // warmup System.out.println("Warmup..."); @@ -100,9 +104,8 @@ public class MapLoops { Map map = (Map)mapClass.newInstance(); LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); CyclicBarrier barrier = new CyclicBarrier(1, timer); - new Runner(map, key, barrier).run(); + new Runner(map, key, barrier, rnd.split()).run(); map.clear(); - Thread.sleep(100); } for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) { @@ -111,7 +114,7 @@ public class MapLoops { LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); CyclicBarrier barrier = new CyclicBarrier(i+1, timer); for (int k = 0; k < i; ++k) - pool.execute(new Runner(map, key, barrier)); + pool.execute(new Runner(map, key, barrier, rnd.split())); barrier.await(); barrier.await(); long time = timer.getTime(); @@ -122,28 +125,32 @@ public class MapLoops { map.clear(); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) + if (! pool.awaitTermination(10L, SECONDS)) throw new Error(); } static class Runner implements Runnable { final Map map; final Integer[] key; - final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); final CyclicBarrier barrier; + final SplittableRandom rnd; int position; int total; - Runner(Map map, Integer[] key, CyclicBarrier barrier) { + Runner(Map map, + Integer[] key, + CyclicBarrier barrier, + SplittableRandom rnd) { this.map = map; this.key = key; this.barrier = barrier; + this.rnd = rnd; position = key.length / 2; } int step() { // random-walk around key positions, bunching accesses - int r = rng.next(); + int r = rnd.nextInt(Integer.MAX_VALUE); position += (r & 7) - 3; while (position >= key.length) position -= key.length; while (position < 0) position += key.length; diff --git a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java index aac4f4561cd..6b56c0b6daf 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java @@ -31,9 +31,11 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * This is an incomplete implementation of a wrapper class diff --git a/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java index d9662388089..dde4fed0030 100644 --- a/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java +++ b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java @@ -38,10 +38,13 @@ * @author Chris Hegarty */ +import static java.util.concurrent.TimeUnit.SECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + import java.util.Iterator; import java.util.concurrent.Phaser; import java.util.concurrent.TimeUnit; -import static java.util.concurrent.TimeUnit.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -287,12 +290,34 @@ public class Basic { public void remove() {throw new UnsupportedOperationException();}}; } - private static void realMain(String[] args) throws Throwable { + static class SimpleTimer { + long startTime = System.nanoTime(); + long elapsedMillis() { + long now = System.nanoTime(); + long elapsed = NANOSECONDS.toMillis(now - startTime); + startTime = now; + return elapsed; + } + void printElapsed() { System.out.println(elapsedMillis() + " ms"); } + } - Thread.currentThread().setName("mainThread"); + static void waitForThreadToBlock(Thread thread) { + for (long startTime = 0;;) { + Thread.State state = thread.getState(); + if (state == Thread.State.WAITING || + state == Thread.State.TIMED_WAITING) + break; + if (startTime == 0) startTime = System.nanoTime(); + else if (System.nanoTime() - startTime > 10L * 1000L * 1000L * 1000L) + throw new AssertionError("timed out waiting for thread to block"); + } + } + + private static void realMain(String[] args) throws Throwable { + SimpleTimer timer = new SimpleTimer(); //---------------------------------------------------------------- - // Some basic sanity + System.out.print("Some basic sanity: "); //---------------------------------------------------------------- try { final StampedLock sl = new StampedLock(); @@ -309,10 +334,10 @@ public class Basic { check(!sl.isReadLocked()); check(sl.isWriteLocked()); check(sl.tryReadLock() == 0L); - check(sl.tryReadLock(100, MILLISECONDS) == 0L); + check(sl.tryReadLock(1, MILLISECONDS) == 0L); check(sl.tryOptimisticRead() == 0L); check(sl.tryWriteLock() == 0L); - check(sl.tryWriteLock(100, MILLISECONDS) == 0L); + check(sl.tryWriteLock(1, MILLISECONDS) == 0L); check(!sl.tryUnlockRead()); check(sl.tryConvertToWriteLock(stamp) == stamp); try { @@ -334,7 +359,7 @@ public class Basic { check(!sl.isWriteLocked()); check(sl.tryOptimisticRead() != 0L); check(sl.tryWriteLock() == 0L); - check(sl.tryWriteLock(100, MILLISECONDS) == 0L); + check(sl.tryWriteLock(1, MILLISECONDS) == 0L); check(!sl.tryUnlockWrite()); check(sl.tryConvertToReadLock(stamp) == stamp); try { @@ -349,105 +374,136 @@ public class Basic { } check(!sl.isReadLocked()); - stamp = sl.tryReadLock(100, MILLISECONDS); + stamp = sl.tryReadLock(1, MILLISECONDS); try { check(stamp != 0L); } finally { sl.unlockRead(stamp); } } catch (Throwable t) { unexpected(t); } + timer.printElapsed(); //---------------------------------------------------------------- - // Multiple writers single reader + System.out.print("Multiple writers single reader: "); //---------------------------------------------------------------- try { StampedLock sl = new StampedLock(); - Phaser gate = new Phaser(102); + int nThreads = 10; + Phaser gate = new Phaser(nThreads + 2); Iterator writers = writerIterator(sl, gate); Iterator readers = readerIterator(sl, gate); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 2; i++) { check(!sl.isReadLocked()); check(!sl.isWriteLocked()); check(!sl.tryUnlockRead()); check(!sl.tryUnlockWrite()); check(sl.tryOptimisticRead() != 0L); - Locker[] wThreads = new Locker[100]; - for (int j=0; j<100; j++) + Locker[] wThreads = new Locker[nThreads]; + for (int j=0; j writers = writerIterator(sl, gate); Iterator readers = readerIterator(sl, gate); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 2; i++) { check(!sl.isReadLocked()); check(!sl.isWriteLocked()); check(!sl.tryUnlockRead()); check(!sl.tryUnlockWrite()); check(sl.tryOptimisticRead() != 0L); - Locker[] rThreads = new Locker[100]; - for (int j=0; j<100; j++) + Locker[] rThreads = new Locker[nThreads]; + for (int j=0; j'."); } diff --git a/jdk/test/sun/tools/jinfo/JInfoHelper.java b/jdk/test/sun/tools/jinfo/JInfoHelper.java index abbc862c2c8..7f945136b4f 100644 --- a/jdk/test/sun/tools/jinfo/JInfoHelper.java +++ b/jdk/test/sun/tools/jinfo/JInfoHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -60,7 +60,7 @@ public final class JInfoHelper { } } if (toPid) { - launcher.addToolArg(Integer.toString(ProcessTools.getProcessId())); + launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); } ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand()); diff --git a/jdk/test/sun/tools/jmap/BasicJMapTest.java b/jdk/test/sun/tools/jmap/BasicJMapTest.java index 03efac77cf0..75c80a2eec3 100644 --- a/jdk/test/sun/tools/jmap/BasicJMapTest.java +++ b/jdk/test/sun/tools/jmap/BasicJMapTest.java @@ -42,9 +42,9 @@ import jdk.testlibrary.ProcessTools; * @modules java.management * @build jdk.testlibrary.* * @build jdk.test.lib.hprof.* - * @build jdk.test.lib.hprof.module.* + * @build jdk.test.lib.hprof.model.* * @build jdk.test.lib.hprof.parser.* - * @build jdk.test.lib.hprof.utils.* + * @build jdk.test.lib.hprof.util.* * @run main/timeout=240 BasicJMapTest */ public class BasicJMapTest { @@ -111,7 +111,7 @@ public class BasicJMapTest { launcher.addToolArg(toolArg); } } - launcher.addToolArg(Integer.toString(ProcessTools.getProcessId())); + launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); processBuilder.command(launcher.getCommand()); System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", "")); diff --git a/jdk/test/sun/tools/jps/JpsBase.java b/jdk/test/sun/tools/jps/JpsBase.java index a1835c20b26..f119f613951 100644 --- a/jdk/test/sun/tools/jps/JpsBase.java +++ b/jdk/test/sun/tools/jps/JpsBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -59,7 +59,7 @@ public final class JpsBase { } public static void main(String[] args) throws Exception { - int pid = ProcessTools.getProcessId(); + long pid = ProcessTools.getProcessId(); List> combinations = JpsHelper.JpsArg.generateCombinations(); for (List combination : combinations) { @@ -76,7 +76,7 @@ public final class JpsBase { // 30673 isQuiet = true; JpsHelper.verifyJpsOutput(output, "^\\d+$"); - output.shouldContain(Integer.toString(pid)); + output.shouldContain(Long.toString(pid)); break; case l: // If '-l' is specified output should contain the full package name for the application's main class diff --git a/jdk/test/sun/tools/jstack/BasicJStackTest.java b/jdk/test/sun/tools/jstack/BasicJStackTest.java index ba35054b8eb..9fd0b66b578 100644 --- a/jdk/test/sun/tools/jstack/BasicJStackTest.java +++ b/jdk/test/sun/tools/jstack/BasicJStackTest.java @@ -63,7 +63,7 @@ public class BasicJStackTest { launcher.addToolArg(toolArg); } } - launcher.addToolArg(Integer.toString(ProcessTools.getProcessId())); + launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); processBuilder.command(launcher.getCommand()); System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", "")); diff --git a/jdk/test/tools/pack200/MultiRelease.java b/jdk/test/tools/pack200/MultiRelease.java new file mode 100644 index 00000000000..7b3f8a3b91a --- /dev/null +++ b/jdk/test/tools/pack200/MultiRelease.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2015, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + r You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @bug 8066272 + * @summary tests a simple multi-versioned jar file + * @compile -XDignore.symbol.file Utils.java MultiRelease.java + * @run main MultiRelease + * @author ksrini + */ + +public class MultiRelease { + private static final File cwd = new File("."); + private static int pass = 0; + private static int fail = 0; + // specify alternate name via arguments to verify + // if permanent fix works + + private static final String PropKey = "pack200.MultiRelease.META-INF"; + private static final String MetaInfName = System.getProperty(PropKey, "META-INF"); + + public static void main(String... args) throws Exception { + new MultiRelease().run(); + } + + void run() throws Exception { + List testCases = new ArrayList<>(); + testCases.add(new TestCase1()); + testCases.add(new TestCase2()); + for (TestCase tc : testCases) { + tc.run(); + } + if (fail > 0) { + throw new Exception(fail + "/" + testCases.size() + " tests fails"); + } else { + System.out.println("All tests(" + pass + ") passes"); + } + } + + /* + * An abstract class to eliminate test boiler plating. + */ + static abstract class TestCase { + final File tcwd; + final File metaInfDir; + final File versionsDir; + final File manifestFile; + + TestCase(String directory) throws IOException { + System.out.println("initializing directories"); + tcwd = new File(cwd, directory); + metaInfDir = mkdir(new File(tcwd, MetaInfName)); + versionsDir = mkdir(new File(metaInfDir, "versions")); + manifestFile = new File(tcwd, "manifest.tmp"); + List scratch = new ArrayList<>(); + scratch.add("Multi-Release: true"); + Utils.createFile(manifestFile, scratch); + } + + File mkdir(File f) throws IOException { + if (f.exists() && f.isDirectory() && f.canRead() && f.canWrite()) { + return f; + } + if (!f.mkdirs()) { + throw new IOException("mkdirs failed: " + f.getAbsolutePath()); + } + return f; + } + + abstract void emitClassFiles() throws Exception; + + void run() { + try { + emitClassFiles(); + // jar the file up + File testFile = new File(tcwd, "test" + Utils.JAR_FILE_EXT); + Utils.jar("cvfm", + testFile.getAbsolutePath(), + manifestFile.getAbsolutePath(), + "-C", + tcwd.getAbsolutePath(), + "."); + File outFile = new File(tcwd, "test-repacked" + Utils.JAR_FILE_EXT); + List cmdsList = new ArrayList<>(); + + cmdsList.add(Utils.getPack200Cmd()); + cmdsList.add("-J-ea"); + cmdsList.add("-J-esa"); + cmdsList.add("-v"); + cmdsList.add("--repack"); + cmdsList.add(outFile.getAbsolutePath()); + cmdsList.add(testFile.getAbsolutePath()); + List output = Utils.runExec(cmdsList); + Utils.doCompareVerify(testFile.getAbsoluteFile(), outFile.getAbsoluteFile()); + pass++; + } catch (Exception e) { + e.printStackTrace(System.err); + fail++; + } + } + } + + static class TestCase1 extends TestCase { + private TestCase1(String directory) throws IOException { + super(directory); + } + + public TestCase1() throws Exception { + this("case1"); + } + + @Override + void emitClassFiles() throws Exception { + emitClassFile(""); + emitClassFile("7"); + emitClassFile("8"); + emitClassFile("9"); + } + + /* + * Adds different variants of types + */ + void emitClassFile(String version) throws IOException { + final File outDir = mkdir(version.isEmpty() + ? tcwd + : new File(versionsDir, version)); + + final File srcDir = mkdir(version.isEmpty() + ? new File(tcwd, "src") + : new File(new File(versionsDir, version), "src")); + + final String fname = "Foo"; + final File srcFile = new File(srcDir, fname + Utils.JAVA_FILE_EXT); + List scratch = new ArrayList<>(); + + scratch.add("package pkg;"); + switch (version) { + case "7": + scratch.add("public class Foo {"); + scratch.add("public static final class Bar {}"); + break; + case "8": + scratch.add("public abstract class Foo {"); + scratch.add("public final class Bar {}"); + break; + case "9": + scratch.add("public interface Foo {"); + scratch.add("public final class Bar {}"); + break; + default: + scratch.add("public class Foo {"); + scratch.add("public final class Bar {}"); + break; + } + scratch.add("}"); + + Utils.createFile(srcFile, scratch); + Utils.compiler("-d", + outDir.getAbsolutePath(), + srcFile.getAbsolutePath()); + } + } + + static class TestCase2 extends TestCase { + private TestCase2(String directory) throws IOException { + super(directory); + } + + TestCase2() throws Exception { + this("case2"); + } + + @Override + void emitClassFiles() throws Exception { + emitClassFile(""); + emitClassFile("8"); + } + + /* + * Adds different variants of types and tries to invoke an + * interface or concrete method defined by them. + */ + void emitClassFile(String version) throws IOException { + + final File outDir = mkdir(version.isEmpty() + ? tcwd + : new File(versionsDir, version)); + + final File srcDir = mkdir(version.isEmpty() + ? new File(tcwd, "src") + : new File(new File(versionsDir, version), "src")); + + List scratch = new ArrayList<>(); + final String fname1 = "Ab"; + final File srcFile1 = new File(srcDir, fname1 + Utils.JAVA_FILE_EXT); + + final String fname2 = "AbNormal"; + final File srcFile2 = new File(srcDir, fname2 + Utils.JAVA_FILE_EXT); + switch (version) { + case "8": + scratch.clear(); + scratch.add("import java.io.IOException;"); + scratch.add("public interface " + fname1 + "{"); + scratch.add(" public abstract void close() throws IOException ;"); + scratch.add("}"); + Utils.createFile(srcFile1, scratch); + break; + default: + scratch.clear(); + scratch.add("import java.io.IOException;"); + scratch.add("public abstract class " + fname1 + "{"); + scratch.add(" public abstract void close() throws IOException ;"); + scratch.add("}"); + Utils.createFile(srcFile1, scratch); + } + + scratch.clear(); + scratch.add("import java.io.IOException;"); + scratch.add("public class " + fname2 + "{"); + scratch.add(" public void doSomething(Ab ab) throws IOException {"); + scratch.add(" ab.close();"); + scratch.add(" }"); + scratch.add("}"); + + Utils.createFile(srcFile2, scratch); + Utils.compiler("-d", + outDir.getAbsolutePath(), + srcFile1.getAbsolutePath(), + srcFile2.getAbsolutePath()); + } + } +}