--- a/jdk/make/gendata/GendataBreakIterator.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/gendata/GendataBreakIterator.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -58,13 +58,13 @@
# 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 @@
-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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -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
--- a/jdk/make/gensrc/GensrcCommon.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/gensrc/GensrcCommon.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -33,4 +33,3 @@
include SetupJavaCompilers.gmk
# We need the tools.
include Tools.gmk
-
--- a/jdk/make/gensrc/GensrcMisc.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/gensrc/GensrcMisc.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -100,7 +100,6 @@
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))
--- a/jdk/make/gensrc/GensrcProperties.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/gensrc/GensrcProperties.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -75,7 +75,7 @@
# Convert .../src/<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties
# to .../support/gensrc/<module>/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:
# "<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN"
$1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \
$(SUPPORT_OUTPUTDIR)/gensrc/%, \
--- a/jdk/make/launcher/Launcher-jdk.jcmd.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/launcher/Launcher-jdk.jcmd.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -30,7 +30,6 @@
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 @@
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 @@
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, \
))
--- a/jdk/make/launcher/Launcher-jdk.jconsole.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/launcher/Launcher-jdk.jconsole.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -28,7 +28,6 @@
$(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, \
))
--- a/jdk/make/launcher/Launcher-jdk.jdi.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/launcher/Launcher-jdk.jdi.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -27,5 +27,4 @@
$(eval $(call SetupBuildLauncher, jdb, \
MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \
- APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
))
--- a/jdk/make/launcher/Launcher-jdk.jvmstat.gmk Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2011, 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 LauncherCommon.gmk
-
-$(eval $(call SetupBuildLauncher, jstatd, \
- MAIN_CLASS := sun.tools.jstatd.Jstatd, \
-))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2011, 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 LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jstatd, \
+ MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+))
--- a/jdk/make/launcher/LauncherCommon.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/launcher/LauncherCommon.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -64,7 +64,6 @@
# 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 @@
$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)
--- a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk Mon Nov 30 13:27:19 2015 -0800
@@ -43,7 +43,7 @@
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)
--- a/jdk/make/src/classes/build/tools/module/ext.modules Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/make/src/classes/build/tools/module/ext.modules Mon Nov 30 13:27:19 2015 -0800
@@ -9,6 +9,7 @@
jdk.crypto.mscapi
jdk.crypto.pkcs11
jdk.crypto.ucrypto
+jdk.dynalink
jdk.localedata
jdk.naming.dns
jdk.scripting.nashorn
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java Mon Nov 30 13:27:19 2015 -0800
@@ -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.PollSelectorProvider();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java Mon Nov 30 13:27:19 2015 -0800
@@ -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();
+ }
+
+}
--- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Mon Nov 30 13:27:19 2015 -0800
@@ -272,22 +272,6 @@
// (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 @@
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 @@
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 @@
assert(je.isDirectory() == name.endsWith("/"));
- if (isClassFile(name)) {
+ if (inFile.mustProcess()) {
file = readClass(name, bits.getInputStream());
}
if (file == null) {
@@ -429,7 +436,7 @@
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 @@
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();
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Mon Nov 30 13:27:19 2015 -0800
@@ -732,13 +732,7 @@
* @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 @@
* @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);
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java Mon Nov 30 13:27:19 2015 -0800
@@ -396,7 +396,7 @@
} 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 @@
'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 @@
'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 @@
*/
@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 @@
* 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;
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/Long.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java Mon Nov 30 13:27:19 2015 -0800
@@ -448,9 +448,7 @@
* @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 @@
}
/**
- * 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 @@
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 @@
// 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;
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java Mon Nov 30 13:27:19 2015 -0800
@@ -44,7 +44,7 @@
*/
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.
--- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Mon Nov 30 13:27:19 2015 -0800
@@ -730,7 +730,7 @@
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);
}
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Mon Nov 30 13:27:19 2015 -0800
@@ -938,7 +938,7 @@
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;
--- a/jdk/src/java.base/share/classes/java/text/DateFormat.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/text/DateFormat.java Mon Nov 30 13:27:19 2015 -0800
@@ -418,7 +418,7 @@
* index information as described above.
* @return A <code>Date</code> parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);
--- a/jdk/src/java.base/share/classes/java/text/Format.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/text/Format.java Mon Nov 30 13:27:19 2015 -0800
@@ -225,7 +225,7 @@
* index information as described above.
* @return An <code>Object</code> parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public abstract Object parseObject (String source, ParsePosition pos);
@@ -237,6 +237,7 @@
* @return An <code>Object</code> 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);
--- a/jdk/src/java.base/share/classes/java/text/MessageFormat.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/text/MessageFormat.java Mon Nov 30 13:27:19 2015 -0800
@@ -1068,7 +1068,7 @@
* index information as described above.
* @return An <code>Object</code> array parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);
--- a/jdk/src/java.base/share/classes/java/text/NumberFormat.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/text/NumberFormat.java Mon Nov 30 13:27:19 2015 -0800
@@ -271,7 +271,7 @@
* index information as described above.
* @return A <code>Number</code> parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
@Override
public final Object parseObject(String source, ParsePosition pos) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Mon Nov 30 13:27:19 2015 -0800
@@ -596,7 +596,16 @@
/** 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 @@
* @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 @@
}
s.writeObject(null);
s.writeObject(null);
- segments = null; // throw away
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Mon Nov 30 13:27:19 2015 -0800
@@ -185,7 +185,7 @@
* }
* }}</pre>
*
- * 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 @@
* }
* }}</pre>
*
- * 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 @@
* }}</pre>
*
* 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 @@
* 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 @@
/**
* 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}
*/
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Mon Nov 30 13:27:19 2015 -0800
@@ -703,7 +703,8 @@
* 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 @@
}
/**
- * Shared version of pop.
+ * Shared version of tryUnpush.
*/
final boolean trySharedUnpush(ForkJoinTask<?> task) {
boolean popped = false;
@@ -1064,7 +1065,8 @@
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 @@
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;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Mon Nov 30 13:27:19 2015 -0800
@@ -132,11 +132,10 @@
/*
* 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 @@
*/
private static final AtomicLong sequencer = new AtomicLong();
- /**
- * Returns current nanosecond time.
- */
- static final long now() {
- return System.nanoTime();
- }
-
private class ScheduledFutureTask<V>
extends FutureTask<V> implements RunnableScheduledFuture<V> {
/** 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 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 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 @@
* 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));
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Mon Nov 30 13:27:19 2015 -0800
@@ -365,12 +365,17 @@
/**
* Standard hotspot implementation using intrinsics.
*/
- private static class AtomicIntegerFieldUpdaterImpl<T>
- extends AtomicIntegerFieldUpdater<T> {
+ private static final class AtomicIntegerFieldUpdaterImpl<T>
+ extends AtomicIntegerFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
- private final Class<?> cclass;
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
final String fieldName,
@@ -399,17 +404,15 @@
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 @@
return false;
}
- 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))
+ throwAccessCheckException(obj);
}
- public boolean compareAndSet(T obj, int expect, int update) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(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();
+ 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 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()
- )
- );
- }
}
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Mon Nov 30 13:27:19 2015 -0800
@@ -365,11 +365,16 @@
return next;
}
- private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
+ private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
- private final Class<?> cclass;
CASUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
@@ -397,103 +402,110 @@
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);
+ }
+
+ /**
+ * Checks that target argument is instance of cclass. On
+ * failure, throws cause.
+ */
+ private final void accessCheck(T obj) {
+ if (!cclass.isInstance(obj))
+ throwAccessCheckException(obj);
}
- private void fullCheck(T obj) {
- if (!tclass.isInstance(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) {
+ public final long getAndAdd(T obj, long delta) {
+ accessCheck(obj);
+ return U.getAndAddLong(obj, offset, delta);
+ }
+
+ public final long getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
- public long getAndDecrement(T obj) {
+ public final 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);
- return U.getAndAddLong(obj, offset, delta);
- }
-
- public long incrementAndGet(T obj) {
+ 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<T> extends AtomicLongFieldUpdater<T> {
+ private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
- private final Class<?> cclass;
LockedUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
@@ -521,28 +533,46 @@
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);
+ }
+
+ /**
+ * 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);
}
- private void fullCheck(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
- if (cclass != null)
- ensureProtectedAccess(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 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);
synchronized (this) {
long v = U.getLong(obj, offset);
if (v != expect)
@@ -552,42 +582,27 @@
}
}
- 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()
- )
- );
- }
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Mon Nov 30 13:27:19 2015 -0800
@@ -286,9 +286,15 @@
extends AtomicReferenceFieldUpdater<T,V> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
+ /** field value type */
private final Class<V> vclass;
- private final Class<?> cclass;
/*
* Internal type checks within all update methods contain
@@ -340,14 +346,10 @@
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 @@
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()
- )
- );
- }
}
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Mon Nov 30 13:27:19 2015 -0800
@@ -922,7 +922,7 @@
/**
* 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.
*
* <p>In this implementation, this operation returns in
* constant time.
@@ -977,13 +977,11 @@
* 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 @@
* <p>An invocation of this method is equivalent to (but may be
* more efficient than):
* <pre> {@code
- * getFirstQueuedThread() != Thread.currentThread() &&
- * hasQueuedThreads()}</pre>
+ * getFirstQueuedThread() != Thread.currentThread()
+ * && hasQueuedThreads()}</pre>
*
* <p>Note that because cancellations due to interrupts and
* timeouts may occur at any time, a {@code true} return does not
@@ -1635,7 +1633,7 @@
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 @@
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 @@
* 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;
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Mon Nov 30 13:27:19 2015 -0800
@@ -1388,7 +1388,7 @@
/**
* 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.
*
* <p>In this implementation, this operation returns in
* constant time.
@@ -1443,13 +1443,11 @@
* 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 @@
* <p>An invocation of this method is equivalent to (but may be
* more efficient than):
* <pre> {@code
- * getFirstQueuedThread() != Thread.currentThread() &&
- * hasQueuedThreads()}</pre>
+ * getFirstQueuedThread() != Thread.currentThread()
+ * && hasQueuedThreads()}</pre>
*
* <p>Note that because cancellations due to interrupts and
* timeouts may occur at any time, a {@code true} return does not
@@ -2099,7 +2097,7 @@
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 @@
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 @@
* 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;
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Mon Nov 30 13:27:19 2015 -0800
@@ -81,12 +81,17 @@
* method is designed for use only in constructions of the form:
*
* <pre> {@code
- * while (!canProceed()) { ... LockSupport.park(this); }}</pre>
+ * while (!canProceed()) {
+ * // ensure request to unpark is visible to other threads
+ * ...
+ * LockSupport.park(this);
+ * }}</pre>
*
- * 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").
*
* <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
* non-reentrant lock class:
@@ -98,26 +103,33 @@
*
* 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;
+ * }
* }}</pre>
*/
public class LockSupport {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Mon Nov 30 13:27:19 2015 -0800
@@ -188,9 +188,9 @@
* try { return m.get(key); }
* finally { r.unlock(); }
* }
- * public String[] allKeys() {
+ * public List<String> allKeys() {
* r.lock();
- * try { return m.keySet().toArray(); }
+ * try { return new ArrayList<>(m.keySet()); }
* finally { r.unlock(); }
* }
* public Data put(String key, Data value) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java Mon Nov 30 13:27:19 2015 -0800
@@ -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();
+ }
+
+}
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2001, 2012, 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;
-import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
-
-/**
- * Creates this platform's default SelectorProvider
- */
-
-public class DefaultSelectorProvider {
-
- /**
- * Prevent instantiation.
- */
- private DefaultSelectorProvider() { }
-
- @SuppressWarnings("unchecked")
- private static SelectorProvider createProvider(String cn) {
- Class<SelectorProvider> c;
- try {
- c = (Class<SelectorProvider>)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();
- }
-
-}
--- a/jdk/src/java.sql/share/classes/java/sql/Connection.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.sql/share/classes/java/sql/Connection.java Mon Nov 30 13:27:19 2015 -0800
@@ -1587,4 +1587,119 @@
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");
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java Mon Nov 30 13:27:19 2015 -0800
@@ -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}.
+ * <p>The following example illustrates the use of {@code ConnectionBuilder}
+ * to create a {@link Connection}:
+ *
+ * <pre>{@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();
+ * }</pre>
+ *
+ * @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;
+}
--- a/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ShardingKey.java Mon Nov 30 13:27:19 2015 -0800
@@ -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}.
+ * <p>
+ * The following example illustrates the use of {@link ShardingKeyBuilder} to
+ * create a {@code ShardingKey}:
+ * <pre>
+ * {@code
+ *
+ * DataSource ds = new MyDataSource();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("abc", JDBCType.VARCHAR)
+ * .subkey(94002, JDBCType.INTEGER)
+ * .build();
+ * }
+ * </pre>
+ * <p>
+ *
+ * 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.
+ * <p>
+ * 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:
+ * <pre>
+ * {@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();
+ * }
+ * </pre>
+ *
+ * @since 1.9
+ */
+public interface ShardingKey {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ShardingKeyBuilder.java Mon Nov 30 13:27:19 2015 -0800
@@ -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.
+ * <p>
+ * The following example illustrates the use of {@code ShardingKeyBuilder} to
+ * create a {@link ShardingKey}:
+ * <pre>
+ * {@code
+ *
+ * DataSource ds = new MyDataSource();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("abc", JDBCType.VARCHAR)
+ * .subkey(94002, JDBCType.INTEGER)
+ * .build();
+ * }
+ * </pre>
+ */
+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;
+}
--- a/jdk/src/java.sql/share/classes/java/sql/Statement.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.sql/share/classes/java/sql/Statement.java Mon Nov 30 13:27:19 2015 -0800
@@ -1397,9 +1397,10 @@
* @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 @@
*
* The default implementation will throw a {@code SQLException} if:
* <ul>
- * <li>{@code identifier} contains a null character or double quote, and is not
+ * <li>{@code identifier} contains a {@code null} character or double quote and is not
* a simple SQL identifier.</li>
* <li>The length of {@code identifier} is less than 1 or greater than 128 characters
* </ul>
@@ -1501,14 +1502,14 @@
* @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 @@
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:
+ * <ul>
+ * <li>The string is not enclosed in double quotes</li>
+ * <li>The first character is an alphabetic character from a through z, or
+ * from A through Z</li>
+ * <li>The string only contains alphanumeric characters or the character
+ * "_"</li>
+ * <li>The string is between 1 and 128 characters in length inclusive</li>
+ * </ul>
+ *
+ * <blockquote>
+ * <table border = 1 cellspacing=0 cellpadding=5 >
+ * <caption>Examples of the conversion:</caption>
+ * <tr>
+ * <th>identifier</th>
+ * <th>Simple Identifier</th>
+ *
+ * <tr>
+ * <td align='center'>Hello</td>
+ * <td align='center'>true</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>G'Day</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>"Bruce Wayne"</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>GoodDay$</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>Hello"World</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>"Hello"World"</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * @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();
+ }
}
--- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
*/
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");
+ };
}
--- a/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 <code>XAConnection</code> object may be enlisted
- * in a distributed transaction by means of an <code>XAResource</code> object.
- * A transaction manager, usually part of a middle tier server, manages an
- * <code>XAConnection</code> object through the <code>XAResource</code> 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.
* <P>
- * 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 <code>XAResource</code> object that
- * the transaction manager will use
- * to manage this <code>XAConnection</code> object's participation in a
- * distributed transaction.
- *
- * @return the <code>XAResource</code> 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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/javax/sql/XAConnectionBuilder.java Mon Nov 30 13:27:19 2015 -0800
@@ -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}.
+ * <p>The following example illustrates the use of {@code XAConnectionBuilder}
+ * to create a {@link XAConnection}:
+ *
+ * <pre>{@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();
+ * }</pre>
+ *
+ * @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;
+
+}
--- a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
*/
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");
+ };
}
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java Mon Nov 30 13:27:19 2015 -0800
@@ -389,10 +389,22 @@
}
}
+ 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 @@
try {
entry.setPrivateKey((RSAPrivateCrtKey) key);
- entry.setCertificateChain((X509Certificate[]) chain);
+ entry.setCertificateChain(xchain);
} catch (CertificateException ce) {
throw new KeyStoreException(ce);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,1 @@
+sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004, 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.jvmstat.monitor.remote;
+
+import sun.jvmstat.monitor.*;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.io.IOException;
+
+/**
+ * Remote Interface for discovering and attaching to remote
+ * monitorable Java Virtual Machines.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteHost extends Remote {
+
+ /**
+ * Remote method to attach to a remote HotSpot Java Virtual Machine
+ * identified by <code>vmid</code>.
+ *
+ * @param vmid The identifier for the target virtual machine.
+ * @return RemoteVm - A remote object for accessing the remote Java
+ * Virtual Machine.
+ *
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ *
+ */
+ RemoteVm attachVm(int vmid, String mode) throws RemoteException,
+ MonitorException;
+
+ /**
+ * Remote method to detach from a remote HotSpot Java Virtual Machine
+ * identified by <code>vmid</code>.
+ *
+ * @param rvm The remote object for the target Java Virtual
+ * Machine.
+ *
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ */
+ void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
+
+ /**
+ * Get a list of Local Virtual Machine Identifiers for the active
+ * Java Virtual Machine the remote system. A Local Virtual Machine
+ * Identifier is also known as an <em>lvmid</em>.
+ *
+ * @return int[] - A array of <em>lvmid</em>s.
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ */
+ int[] activeVms() throws RemoteException, MonitorException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004, 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.jvmstat.monitor.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * Interface for accessing the instrumentation exported by a
+ * Java Virtual Machine running on a remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteVm extends Remote {
+
+ /**
+ * Interface to get the bytes associated with the instrumentation
+ * for the remote Java Virtual Machine.
+ *
+ * @return byte[] - a byte array containing the current bytes
+ * for the instrumentation exported by the
+ * remote Java Virtual Machine.
+ * @throws RemoteException Thrown on any communication error
+ */
+ byte[] getBytes() throws RemoteException;
+
+ /**
+ * Interface to get the size of the instrumentation buffer
+ * for the target Java Virtual Machine.
+ *
+ * @return int - the size of the instrumentation buffer for the
+ * remote Java Virtual Machine.
+ * @throws RemoteException Thrown on any communication error
+ */
+ int getCapacity() throws RemoteException;
+
+ /**
+ * Interface to return the Local Virtual Machine Identifier for
+ * the remote Java Virtual Machine. The Local Virtual Machine
+ * Identifier is also know as the <em>lvmid</em>.
+ *
+ * @throws RemoteException Thrown on any communication error
+ */
+ int getLocalVmId() throws RemoteException;
+
+ /**
+ * Interface to detach from the remote Java Virtual Machine.
+ *
+ * @throws RemoteException Thrown on any communication error
+ */
+ void detach() throws RemoteException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,39 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+
+
+ Copyright (c) 2004, 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.
+
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides interfaces supporting remote monitoring for instrumented
+HotSpot Java Virtual Machines.
+</p>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2004, 2014, 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.rmi.*;
+import java.util.HashMap;
+
+/**
+ * Concrete implementation of the MonitoredHost interface for the
+ * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class MonitoredHostProvider extends MonitoredHost {
+ private static final String serverName = "/JStatRemoteHost";
+ private static final int DEFAULT_POLLING_INTERVAL = 1000;
+
+ private ArrayList<HostListener> listeners;
+ private NotifierTask task;
+ private HashSet<Integer> activeVms;
+ private RemoteVmManager vmManager;
+ private RemoteHost remoteHost;
+ private Timer timer;
+
+ /**
+ * Create a MonitoredHostProvider instance using the given HostIdentifier.
+ *
+ * @param hostId the host identifier for this MonitoredHost
+ * @throws MonitorException Thrown on any error encountered while
+ * communicating with the remote host.
+ */
+ public MonitoredHostProvider(HostIdentifier hostId)
+ throws MonitorException {
+ this.hostId = hostId;
+ this.listeners = new ArrayList<HostListener>();
+ this.interval = DEFAULT_POLLING_INTERVAL;
+ this.activeVms = new HashSet<Integer>();
+
+ String rmiName;
+ String sn = serverName;
+ String path = hostId.getPath();
+
+ if ((path != null) && (path.length() > 0)) {
+ sn = path;
+ }
+
+ if (hostId.getPort() != -1) {
+ rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
+ } else {
+ rmiName = "rmi://" + hostId.getHost() + sn;
+ }
+
+ try {
+ remoteHost = (RemoteHost)Naming.lookup(rmiName);
+
+ } catch (RemoteException e) {
+ /*
+ * rmi registry not available
+ *
+ * Access control exceptions, where the rmi server refuses a
+ * connection based on policy file configuration, come through
+ * here on the client side. Unfortunately, the RemoteException
+ * doesn't contain enough information to determine the true cause
+ * of the exception. So, we have to output a rather generic message.
+ */
+ String message = "RMI Registry not available at "
+ + hostId.getHost();
+
+ if (hostId.getPort() == -1) {
+ message = message + ":"
+ + java.rmi.registry.Registry.REGISTRY_PORT;
+ } else {
+ message = message + ":" + hostId.getPort();
+ }
+
+ if (e.getMessage() != null) {
+ throw new MonitorException(message + "\n" + e.getMessage(), e);
+ } else {
+ throw new MonitorException(message, e);
+ }
+
+ } catch (NotBoundException e) {
+ // no server with given name
+ String message = e.getMessage();
+ if (message == null) message = rmiName;
+ throw new MonitorException("RMI Server " + message
+ + " not available", e);
+ } catch (MalformedURLException e) {
+ // this is a programming problem
+ e.printStackTrace();
+ throw new IllegalArgumentException("Malformed URL: " + rmiName);
+ }
+ this.vmManager = new RemoteVmManager(remoteHost);
+ this.timer = new Timer(true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MonitoredVm getMonitoredVm(VmIdentifier vmid)
+ throws MonitorException {
+ return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
+ throws MonitorException {
+ VmIdentifier nvmid = null;
+ try {
+ nvmid = hostId.resolve(vmid);
+ RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
+ vmid.getMode());
+ RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
+ interval);
+ rmvm.attach();
+ return rmvm;
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Remote Exception attaching to "
+ + nvmid.toString(), e);
+ } catch (URISyntaxException e) {
+ /*
+ * the VmIdentifier is expected to be a valid and should resolve
+ * easonably against the host identifier. A URISyntaxException
+ * here is most likely a programming error.
+ */
+ throw new IllegalArgumentException("Malformed URI: "
+ + vmid.toString(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void detach(MonitoredVm vm) throws MonitorException {
+ RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
+ rmvm.detach();
+ try {
+ remoteHost.detachVm(rmvm.getRemoteVm());
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Remote Exception detaching from "
+ + vm.getVmIdentifier().toString(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addHostListener(HostListener listener) {
+ synchronized(listeners) {
+ listeners.add(listener);
+ if (task == null) {
+ task = new NotifierTask();
+ timer.schedule(task, 0, interval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeHostListener(HostListener listener) {
+ /*
+ * XXX: if a disconnect method is added, make sure it calls
+ * this method to unregister this object from the watcher. otherwise,
+ * an unused MonitoredHostProvider instance may go uncollected.
+ */
+ synchronized(listeners) {
+ listeners.remove(listener);
+ if (listeners.isEmpty() && (task != null)) {
+ task.cancel();
+ task = null;
+ }
+ }
+ }
+
+ public void setInterval(int newInterval) {
+ synchronized(listeners) {
+ if (newInterval == interval) {
+ return;
+ }
+
+ int oldInterval = interval;
+ super.setInterval(newInterval);
+
+ if (task != null) {
+ task.cancel();
+ NotifierTask oldTask = task;
+ task = new NotifierTask();
+ CountedTimerTaskUtils.reschedule(timer, oldTask, task,
+ oldInterval, newInterval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<Integer> activeVms() throws MonitorException {
+ return vmManager.activeVms();
+ }
+
+ /**
+ * Fire VmStatusChangeEvent events to HostListener objects
+ *
+ * @param active Set of Integer objects containing the local
+ * Vm Identifiers of the active JVMs
+ * @param started Set of Integer objects containing the local
+ * Vm Identifiers of new JVMs started since last
+ * interval.
+ * @param terminated Set of Integer objects containing the local
+ * Vm Identifiers of terminated JVMs since last
+ * interval.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
+ Set<Integer> terminated) {
+ ArrayList<HostListener> registered = null;
+ VmStatusChangeEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ HostListener l = i.next();
+ if (ev == null) {
+ ev = new VmStatusChangeEvent(this, active, started, terminated);
+ }
+ l.vmStatusChanged(ev);
+ }
+ }
+
+ /**
+ * Fire hostDisconnectEvent events.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireDisconnectedEvents() {
+ ArrayList<HostListener> registered = null;
+ HostEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ HostListener l = i.next();
+ if (ev == null) {
+ ev = new HostEvent(this);
+ }
+ l.disconnected(ev);
+ }
+ }
+
+ /**
+ * class to poll the remote machine and generate local event notifications.
+ */
+ private class NotifierTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+
+ // save the last set of active JVMs
+ Set<Integer> lastActiveVms = activeVms;
+
+ try {
+ // get the current set of active JVMs
+ activeVms = (HashSet<Integer>)vmManager.activeVms();
+
+ } catch (MonitorException e) {
+ // XXX: use logging api
+ System.err.println("MonitoredHostProvider: polling task "
+ + "caught MonitorException:");
+ e.printStackTrace();
+
+ // mark the HostManager as errored and notify listeners
+ setLastException(e);
+ fireDisconnectedEvents();
+ }
+
+ if (activeVms.isEmpty()) {
+ return;
+ }
+
+ Set<Integer> startedVms = new HashSet<>();
+ Set<Integer> terminatedVms = new HashSet<>();
+
+ for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
+ Integer vmid = i.next();
+ if (!lastActiveVms.contains(vmid)) {
+ // a new file has been detected, add to set
+ startedVms.add(vmid);
+ }
+ }
+
+ for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
+ /* empty */ ) {
+ Integer o = i.next();
+ if (!activeVms.contains(o)) {
+ // JVM has terminated, remove it from the active list
+ terminatedVms.add(o);
+ }
+ }
+
+ if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
+ fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.HostIdentifier;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredHostService;
+
+public final class MonitoredHostRmiService implements MonitoredHostService {
+
+ @Override
+ public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
+ return new MonitoredHostProvider(hostId);
+ }
+
+ @Override
+ public String getScheme() {
+ return "rmi";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004, 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import java.nio.ByteBuffer;
+
+/**
+ * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
+ * protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class is responsible for acquiring the instrumentation buffer
+ * data for a remote target HotSpot Java Virtual Machine.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class PerfDataBuffer extends AbstractPerfDataBuffer {
+
+ private RemoteVm rvm;
+
+ /**
+ * Create a PerfDataBuffer instance for accessing the specified
+ * instrumentation buffer.
+ *
+ * @param rvm the proxy to the remote MonitredVm object
+ * @param lvmid the local Java Virtual Machine Identifier of the
+ * remote target.
+ *
+ * @throws MonitorException
+ */
+ public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
+
+ this.rvm = rvm;
+ try {
+ ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
+ sample(buffer);
+ createPerfDataBuffer(buffer, lvmid);
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Could not read data for remote JVM "
+ + lvmid, e);
+ }
+ }
+
+ /**
+ * Get a copy of the remote instrumentation buffer.
+ *<p>
+ * The data in the remote instrumentation buffer is copied into
+ * the local byte buffer.
+ *
+ * @param buffer the buffer to receive the copy of the remote
+ * instrumentation buffer.
+ * @throws RemoteException Thrown on any communications errors with
+ * the remote system.
+ */
+ public void sample(ByteBuffer buffer) throws RemoteException {
+ assert buffer != null;
+ assert rvm != null;
+ synchronized(buffer) {
+ buffer.clear();
+ buffer.put(rvm.getBytes());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2004, 2014, 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.rmi.*;
+
+/**
+ * Concrete implementation of the AbstractMonitoredVm class for the
+ * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class provides the ability to acquire to the instrumentation buffer
+ * of a live, remote target Java Virtual Machine through an RMI server.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteMonitoredVm extends AbstractMonitoredVm {
+
+ private ArrayList<VmListener> listeners;
+ private NotifierTask notifierTask;
+ private SamplerTask samplerTask;
+ private Timer timer;
+
+ private RemoteVm rvm;
+ private ByteBuffer updateBuffer;
+
+ /**
+ * Create a RemoteMonitoredVm instance.
+ *
+ * @param rvm the proxy to the remote MonitoredVm instance.
+ * @param vmid the vm identifier specifying the remot target JVM
+ * @param timer the timer used to run polling tasks
+ * @param interval the sampling interval
+ */
+ public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
+ Timer timer, int interval)
+ throws MonitorException {
+ super(vmid, interval);
+ this.rvm = rvm;
+ pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
+ this.listeners = new ArrayList<VmListener>();
+ this.timer = timer;
+ }
+
+ /**
+ * Method to attach to the remote MonitoredVm.
+ */
+ public void attach() throws MonitorException {
+ updateBuffer = pdb.getByteBuffer().duplicate();
+
+ // if continuous sampling is requested, register with the sampler thread
+ if (interval > 0) {
+ samplerTask = new SamplerTask();
+ timer.schedule(samplerTask, 0, interval);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void detach() {
+ try {
+ if (interval > 0) {
+ if (samplerTask != null) {
+ samplerTask.cancel();
+ samplerTask = null;
+ }
+ if (notifierTask != null) {
+ notifierTask.cancel();
+ notifierTask = null;
+ }
+ sample();
+ }
+ } catch (RemoteException e) {
+ // XXX: - use logging api? throw an exception instead?
+ System.err.println("Could not read data for remote JVM " + vmid);
+ e.printStackTrace();
+
+ } finally {
+ super.detach();
+ }
+ }
+
+ /**
+ * Get a copy of the remote instrumentation buffer.
+ *<p>
+ * The data in the remote instrumentation buffer is copied into
+ * a local byte buffer.
+ *
+ * @throws RemoteException Thrown on any communications errors with
+ * the remote system.
+ */
+ public void sample() throws RemoteException {
+ assert updateBuffer != null;
+ ((PerfDataBuffer)pdb).sample(updateBuffer);
+ }
+
+ /**
+ * Get the proxy to the remote MonitoredVm.
+ *
+ * @return RemoteVm - the proxy to the remote MonitoredVm.
+ */
+ public RemoteVm getRemoteVm() {
+ return rvm;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addVmListener(VmListener l) {
+ synchronized(listeners) {
+ listeners.add(l);
+ if (notifierTask == null) {
+ notifierTask = new NotifierTask();
+ timer.schedule(notifierTask, 0, interval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeVmListener(VmListener l) {
+ synchronized(listeners) {
+ listeners.remove(l);
+ if (listeners.isEmpty() && (notifierTask != null)) {
+ notifierTask.cancel();
+ notifierTask = null;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setInterval(int newInterval) {
+ synchronized(listeners) {
+ if (newInterval == interval) {
+ return;
+ }
+
+ int oldInterval = interval;
+ super.setInterval(newInterval);
+
+ if (samplerTask != null) {
+ samplerTask.cancel();
+ SamplerTask oldSamplerTask = samplerTask;
+ samplerTask = new SamplerTask();
+ CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
+ samplerTask, oldInterval,
+ newInterval);
+ }
+ if (notifierTask != null) {
+ notifierTask.cancel();
+ NotifierTask oldNotifierTask = notifierTask;
+ notifierTask = new NotifierTask();
+ CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
+ notifierTask, oldInterval,
+ newInterval);
+ }
+ }
+ }
+
+ /**
+ * Fire MonitoredVmStructureChanged events.
+ *
+ * @param inserted List of Monitor objects inserted.
+ * @param removed List of Monitor objects removed.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
+ ArrayList<VmListener> registered = null;
+ MonitorStatusChangeEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ VmListener l = i.next();
+ if (ev == null) {
+ ev = new MonitorStatusChangeEvent(this, inserted, removed);
+ }
+ l.monitorStatusChanged(ev);
+ }
+ }
+
+ /**
+ * Fire MonitoredVmStructureChanged events.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireMonitorsUpdatedEvents() {
+ ArrayList<VmListener> registered = null;
+ VmEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ VmListener l = i.next();
+ if (ev == null) {
+ ev = new VmEvent(this);
+ }
+ l.monitorsUpdated(ev);
+ }
+ }
+
+ /*
+ * Timer Tasks. There are two separate timer tasks here. The SamplerTask
+ * is active whenever we are attached to the remote JVM with a periodic
+ * sampling interval > 0. The NotifierTask is only active if a VmListener
+ * has registered with this RemoteMonitoredVm instance. Also, in the future
+ * we may want to run these tasks at different intervals. Currently,
+ * they run at the same interval and some significant work may
+ * need to be done to complete the separation of these two intervals.
+ */
+
+ /**
+ * Class to periodically check the state of the defined monitors
+ * for the remote MonitoredVm instance and to notify listeners of
+ * any detected changes.
+ */
+ private class NotifierTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+ try {
+ MonitorStatus status = getMonitorStatus();
+
+ List<Monitor> inserted = status.getInserted();
+ List<Monitor> removed = status.getRemoved();
+
+ if (!inserted.isEmpty() || !removed.isEmpty()) {
+ fireMonitorStatusChangedEvents(inserted, removed);
+ }
+ } catch (MonitorException e) {
+ // XXX: use logging api? fire disconnect events? mark errored?
+ // fireDisconnectedEvents();
+ System.err.println("Exception updating monitors for "
+ + getVmIdentifier());
+ e.printStackTrace();
+ // XXX: should we cancle the notifierTask here?
+ // this.cancel();
+ }
+ }
+ }
+
+ /**
+ * Class to periodically sample the remote instrumentation byte buffer
+ * and refresh the local copy. Registered listeners are notified of
+ * the completion of a sampling event.
+ */
+ private class SamplerTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+ try {
+ sample();
+ fireMonitorsUpdatedEvents();
+
+ } catch (RemoteException e) {
+ // XXX: use logging api, mark vm as errored.
+ System.err.println("Exception taking sample for "
+ + getVmIdentifier());
+ e.printStackTrace();
+ this.cancel();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2004, 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.jvmstat.perfdata.monitor.protocol.rmi;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Class for managing the RemoteMonitoredVm instances on a remote system.
+ * <p>
+ * This class is responsible for the mechanism that detects the active
+ * HotSpot Java Virtual Machines on the remote host and possibly for a
+ * specific user. The ability to detect all possible HotSpot Java Virtual
+ * Machines on the remote host may be limited by the permissions of the
+ * principal running the RMI server application on the remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmManager {
+
+ private RemoteHost remoteHost;
+ private String user;
+
+ /**
+ * Creates a RemoteVmManager instance for the remote system.
+ * <p>
+ * Manages RemoteMonitordVm instances for which the principal
+ * running the remote server has appropriate permissions.
+ *
+ * @param remoteHost the remote proxy object to the RMI server on
+ * the remote system.
+ */
+ public RemoteVmManager(RemoteHost remoteHost) {
+ this(remoteHost, null);
+ }
+
+ /**
+ * Creates a RemoteVmManager instance for the given user.
+ * <p>
+ * Manages RemoteMonitoredVm instances for all remote Java Virtual
+ * machines owned by the specified user on the remote system. The
+ * RMI server on the remote system must have the appropriate permissions
+ * to access the named users Java Virtual Machines.
+ *
+ * @param remoteHost the remote proxy object to the RMI server on
+ * the remote system.
+ * @param user the name of the user
+ */
+ public RemoteVmManager(RemoteHost remoteHost, String user) {
+ this.user = user;
+ this.remoteHost = remoteHost;
+ }
+
+ /**
+ * Return the current set of monitorable Java Virtual Machines.
+ * <p>
+ * The set returned by this method depends on the user name passed
+ * to the constructor. If no user name was specified, then this
+ * method will return all candidate JVMs on the system. Otherwise,
+ * only the JVMs for the given user will be returned. This assumes
+ * that the RMI server process has the appropriate permissions to
+ * access the target set of JVMs.
+ *
+ * @return Set - the Set of monitorable Java Virtual Machines
+ */
+ public Set<Integer> activeVms() throws MonitorException {
+ int[] active = null;
+
+ try {
+ active = remoteHost.activeVms();
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Error communicating with remote host: "
+ + e.getMessage(), e);
+ }
+
+ Set<Integer> activeSet = new HashSet<Integer>(active.length);
+
+ for (int i = 0; i < active.length; i++) {
+ activeSet.add(active[i]);
+ }
+
+ return activeSet;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,47 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+
+
+ Copyright (c) 2004, 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.
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides the implementation classes for the <em>rmi:</em> protocol for
+the HotSpot PerfData instrumentation buffer monitoring implementation.
+</p>
+<p>
+The <em>rmi:</em> protocol is the default protocol for the PerfData
+implementation when a hostname is specified as part of a HostIdentifier
+or VMIdentifier. It communicates with an RMI server on the remote machine
+that provides functions to get a list of available Java Virtual Machines
+and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
+The RMI server may or may not use the PerfData implementation on the
+remote host to acquire this information. The <em>jstatd</em> server
+provides a PerfData implementation of the RMI server.
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2004, 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.tools.jstatd;
+
+import java.rmi.*;
+import java.rmi.server.*;
+import java.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.net.MalformedURLException;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Application providing remote access to the jvmstat instrumentation
+ * exported by local Java Virtual Machine processes. Remote access is
+ * provided through an RMI interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class Jstatd {
+
+ private static Registry registry;
+ private static int port = -1;
+ private static boolean startRegistry = true;
+
+ private static void printUsage() {
+ System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
+ }
+
+ static void bind(String name, RemoteHostImpl remoteHost)
+ throws RemoteException, MalformedURLException, Exception {
+
+ try {
+ Naming.rebind(name, remoteHost);
+ } catch (java.rmi.ConnectException e) {
+ /*
+ * either the registry is not running or we cannot contact it.
+ * start an internal registry if requested.
+ */
+ if (startRegistry && registry == null) {
+ int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
+ registry = LocateRegistry.createRegistry(localport);
+ bind(name, remoteHost);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation") // Use of RMISecurityManager
+ public static void main(String[] args) {
+ String rminame = null;
+ int argc = 0;
+
+ for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
+ String arg = args[argc];
+
+ if (arg.compareTo("-nr") == 0) {
+ startRegistry = false;
+ } else if (arg.startsWith("-p")) {
+ if (arg.compareTo("-p") != 0) {
+ port = Integer.parseInt(arg.substring(2));
+ } else {
+ argc++;
+ if (argc >= args.length) {
+ printUsage();
+ System.exit(1);
+ }
+ port = Integer.parseInt(args[argc]);
+ }
+ } else if (arg.startsWith("-n")) {
+ if (arg.compareTo("-n") != 0) {
+ rminame = arg.substring(2);
+ } else {
+ argc++;
+ if (argc >= args.length) {
+ printUsage();
+ System.exit(1);
+ }
+ rminame = args[argc];
+ }
+ } else {
+ printUsage();
+ System.exit(1);
+ }
+ }
+
+ if (argc < args.length) {
+ printUsage();
+ System.exit(1);
+ }
+
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ StringBuilder name = new StringBuilder();
+
+ if (port >= 0) {
+ name.append("//:").append(port);
+ }
+
+ if (rminame == null) {
+ rminame = "JStatRemoteHost";
+ }
+
+ name.append("/").append(rminame);
+
+ try {
+ // use 1.5.0 dynamically generated subs.
+ System.setProperty("java.rmi.server.ignoreSubClasses", "true");
+ RemoteHostImpl remoteHost = new RemoteHostImpl();
+ RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
+ remoteHost, 0);
+ bind(name.toString(), remoteHost);
+ System.out.println("jstatd started (bound to " + name.toString() + ")");
+ System.out.flush();
+ } catch (MalformedURLException e) {
+ if (rminame != null) {
+ System.out.println("Bad RMI server name: " + rminame);
+ } else {
+ System.out.println("Bad RMI URL: " + name);
+ }
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (java.rmi.ConnectException e) {
+ // could not attach to or create a registry
+ System.out.println("Could not contact RMI registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (RemoteException e) {
+ System.out.println("Could not bind " + name + " to RMI Registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (Exception e) {
+ System.out.println("Could not create remote object");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, 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.tools.jstatd;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+import java.rmi.*;
+import java.rmi.server.*;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteHost interface for the HotSpot
+ * PerfData <em>rmi:</em> protocol.
+ * <p>
+ * This class provides remote access to the instrumentation exported
+ * by HotSpot Java Virtual Machines through the PerfData shared memory
+ * interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteHostImpl implements RemoteHost, HostListener {
+
+ private MonitoredHost monitoredHost;
+ private Set<Integer> activeVms;
+
+ public RemoteHostImpl() throws MonitorException {
+ try {
+ monitoredHost = MonitoredHost.getMonitoredHost("localhost");
+ } catch (URISyntaxException e) { }
+
+ activeVms = monitoredHost.activeVms();
+ monitoredHost.addHostListener(this);
+ }
+
+ public RemoteVm attachVm(int lvmid, String mode)
+ throws RemoteException, MonitorException {
+ Integer v = lvmid;
+ RemoteVm stub = null;
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("local://").append(lvmid).append("@localhost");
+ if (mode != null) {
+ sb.append("?mode=").append(mode);
+ }
+
+ String vmidStr = sb.toString();
+
+ try {
+ VmIdentifier vmid = new VmIdentifier(vmidStr);
+ MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
+ RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
+ stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
+ }
+ catch (URISyntaxException e) {
+ throw new RuntimeException("Malformed VmIdentifier URI: "
+ + vmidStr, e);
+ }
+ return stub;
+ }
+
+ public void detachVm(RemoteVm rvm) throws RemoteException {
+ rvm.detach();
+ }
+
+ public int[] activeVms() throws MonitorException {
+ Object[] vms = null;
+ int[] vmids = null;
+
+ vms = monitoredHost.activeVms().toArray();
+ vmids = new int[vms.length];
+
+ for (int i = 0; i < vmids.length; i++) {
+ vmids[i] = ((Integer)vms[i]).intValue();
+ }
+ return vmids;
+ }
+
+ public void vmStatusChanged(VmStatusChangeEvent ev) {
+ synchronized(this.activeVms) {
+ activeVms.retainAll(ev.getActive());
+ }
+ }
+
+ public void disconnected(HostEvent ev) {
+ // we only monitor the local host, so this event shouldn't occur.
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2004, 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.tools.jstatd;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
+ * shared memory implementation of the jvmstat monitoring APIs. This class
+ * providing remote access to the instrumentation exported by a local HotSpot
+ * Java Virtual Machine. The instrumentation buffer is shipped in whole to
+ * the remote machine, which is responsible for parsing and provide access
+ * to the contained data.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmImpl implements RemoteVm {
+
+ private BufferedMonitoredVm mvm;
+
+ RemoteVmImpl(BufferedMonitoredVm mvm) {
+ this.mvm = mvm;
+ }
+
+ public byte[] getBytes() {
+ return mvm.getBytes();
+ }
+
+ public int getCapacity() {
+ return mvm.getCapacity();
+ }
+
+ public void detach() {
+ mvm.detach();
+ }
+
+ public int getLocalVmId() {
+ return mvm.getVmIdentifier().getLocalVmId();
+ }
+}
--- a/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService Mon Nov 30 13:27:19 2015 -0800
@@ -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
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004, 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.jvmstat.monitor.remote;
-
-import sun.jvmstat.monitor.*;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.io.IOException;
-
-/**
- * Remote Interface for discovering and attaching to remote
- * monitorable Java Virtual Machines.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteHost extends Remote {
-
- /**
- * Remote method to attach to a remote HotSpot Java Virtual Machine
- * identified by <code>vmid</code>.
- *
- * @param vmid The identifier for the target virtual machine.
- * @return RemoteVm - A remote object for accessing the remote Java
- * Virtual Machine.
- *
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- *
- */
- RemoteVm attachVm(int vmid, String mode) throws RemoteException,
- MonitorException;
-
- /**
- * Remote method to detach from a remote HotSpot Java Virtual Machine
- * identified by <code>vmid</code>.
- *
- * @param rvm The remote object for the target Java Virtual
- * Machine.
- *
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- */
- void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
-
- /**
- * Get a list of Local Virtual Machine Identifiers for the active
- * Java Virtual Machine the remote system. A Local Virtual Machine
- * Identifier is also known as an <em>lvmid</em>.
- *
- * @return int[] - A array of <em>lvmid</em>s.
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- */
- int[] activeVms() throws RemoteException, MonitorException;
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004, 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.jvmstat.monitor.remote;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Interface for accessing the instrumentation exported by a
- * Java Virtual Machine running on a remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteVm extends Remote {
-
- /**
- * Interface to get the bytes associated with the instrumentation
- * for the remote Java Virtual Machine.
- *
- * @return byte[] - a byte array containing the current bytes
- * for the instrumentation exported by the
- * remote Java Virtual Machine.
- * @throws RemoteException Thrown on any communication error
- */
- byte[] getBytes() throws RemoteException;
-
- /**
- * Interface to get the size of the instrumentation buffer
- * for the target Java Virtual Machine.
- *
- * @return int - the size of the instrumentation buffer for the
- * remote Java Virtual Machine.
- * @throws RemoteException Thrown on any communication error
- */
- int getCapacity() throws RemoteException;
-
- /**
- * Interface to return the Local Virtual Machine Identifier for
- * the remote Java Virtual Machine. The Local Virtual Machine
- * Identifier is also know as the <em>lvmid</em>.
- *
- * @throws RemoteException Thrown on any communication error
- */
- int getLocalVmId() throws RemoteException;
-
- /**
- * Interface to detach from the remote Java Virtual Machine.
- *
- * @throws RemoteException Thrown on any communication error
- */
- void detach() throws RemoteException;
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/package.html Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
-
-
- Copyright (c) 2004, 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.
-
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides interfaces supporting remote monitoring for instrumented
-HotSpot Java Virtual Machines.
-</p>
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
/**
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.util.*;
-import java.net.*;
-import java.io.*;
-import java.rmi.*;
-import java.util.HashMap;
-
-/**
- * Concrete implementation of the MonitoredHost interface for the
- * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class MonitoredHostProvider extends MonitoredHost {
- private static final String serverName = "/JStatRemoteHost";
- private static final int DEFAULT_POLLING_INTERVAL = 1000;
-
- private ArrayList<HostListener> listeners;
- private NotifierTask task;
- private HashSet<Integer> activeVms;
- private RemoteVmManager vmManager;
- private RemoteHost remoteHost;
- private Timer timer;
-
- /**
- * Create a MonitoredHostProvider instance using the given HostIdentifier.
- *
- * @param hostId the host identifier for this MonitoredHost
- * @throws MonitorException Thrown on any error encountered while
- * communicating with the remote host.
- */
- public MonitoredHostProvider(HostIdentifier hostId)
- throws MonitorException {
- this.hostId = hostId;
- this.listeners = new ArrayList<HostListener>();
- this.interval = DEFAULT_POLLING_INTERVAL;
- this.activeVms = new HashSet<Integer>();
-
- String rmiName;
- String sn = serverName;
- String path = hostId.getPath();
-
- if ((path != null) && (path.length() > 0)) {
- sn = path;
- }
-
- if (hostId.getPort() != -1) {
- rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
- } else {
- rmiName = "rmi://" + hostId.getHost() + sn;
- }
-
- try {
- remoteHost = (RemoteHost)Naming.lookup(rmiName);
-
- } catch (RemoteException e) {
- /*
- * rmi registry not available
- *
- * Access control exceptions, where the rmi server refuses a
- * connection based on policy file configuration, come through
- * here on the client side. Unfortunately, the RemoteException
- * doesn't contain enough information to determine the true cause
- * of the exception. So, we have to output a rather generic message.
- */
- String message = "RMI Registry not available at "
- + hostId.getHost();
-
- if (hostId.getPort() == -1) {
- message = message + ":"
- + java.rmi.registry.Registry.REGISTRY_PORT;
- } else {
- message = message + ":" + hostId.getPort();
- }
-
- if (e.getMessage() != null) {
- throw new MonitorException(message + "\n" + e.getMessage(), e);
- } else {
- throw new MonitorException(message, e);
- }
-
- } catch (NotBoundException e) {
- // no server with given name
- String message = e.getMessage();
- if (message == null) message = rmiName;
- throw new MonitorException("RMI Server " + message
- + " not available", e);
- } catch (MalformedURLException e) {
- // this is a programming problem
- e.printStackTrace();
- throw new IllegalArgumentException("Malformed URL: " + rmiName);
- }
- this.vmManager = new RemoteVmManager(remoteHost);
- this.timer = new Timer(true);
- }
-
- /**
- * {@inheritDoc}
- */
- public MonitoredVm getMonitoredVm(VmIdentifier vmid)
- throws MonitorException {
- return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
- }
-
- /**
- * {@inheritDoc}
- */
- public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
- throws MonitorException {
- VmIdentifier nvmid = null;
- try {
- nvmid = hostId.resolve(vmid);
- RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
- vmid.getMode());
- RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
- interval);
- rmvm.attach();
- return rmvm;
-
- } catch (RemoteException e) {
- throw new MonitorException("Remote Exception attaching to "
- + nvmid.toString(), e);
- } catch (URISyntaxException e) {
- /*
- * the VmIdentifier is expected to be a valid and should resolve
- * easonably against the host identifier. A URISyntaxException
- * here is most likely a programming error.
- */
- throw new IllegalArgumentException("Malformed URI: "
- + vmid.toString(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach(MonitoredVm vm) throws MonitorException {
- RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
- rmvm.detach();
- try {
- remoteHost.detachVm(rmvm.getRemoteVm());
-
- } catch (RemoteException e) {
- throw new MonitorException("Remote Exception detaching from "
- + vm.getVmIdentifier().toString(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void addHostListener(HostListener listener) {
- synchronized(listeners) {
- listeners.add(listener);
- if (task == null) {
- task = new NotifierTask();
- timer.schedule(task, 0, interval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeHostListener(HostListener listener) {
- /*
- * XXX: if a disconnect method is added, make sure it calls
- * this method to unregister this object from the watcher. otherwise,
- * an unused MonitoredHostProvider instance may go uncollected.
- */
- synchronized(listeners) {
- listeners.remove(listener);
- if (listeners.isEmpty() && (task != null)) {
- task.cancel();
- task = null;
- }
- }
- }
-
- public void setInterval(int newInterval) {
- synchronized(listeners) {
- if (newInterval == interval) {
- return;
- }
-
- int oldInterval = interval;
- super.setInterval(newInterval);
-
- if (task != null) {
- task.cancel();
- NotifierTask oldTask = task;
- task = new NotifierTask();
- CountedTimerTaskUtils.reschedule(timer, oldTask, task,
- oldInterval, newInterval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Set<Integer> activeVms() throws MonitorException {
- return vmManager.activeVms();
- }
-
- /**
- * Fire VmStatusChangeEvent events to HostListener objects
- *
- * @param active Set of Integer objects containing the local
- * Vm Identifiers of the active JVMs
- * @param started Set of Integer objects containing the local
- * Vm Identifiers of new JVMs started since last
- * interval.
- * @param terminated Set of Integer objects containing the local
- * Vm Identifiers of terminated JVMs since last
- * interval.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
- Set<Integer> terminated) {
- ArrayList<HostListener> registered = null;
- VmStatusChangeEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- HostListener l = i.next();
- if (ev == null) {
- ev = new VmStatusChangeEvent(this, active, started, terminated);
- }
- l.vmStatusChanged(ev);
- }
- }
-
- /**
- * Fire hostDisconnectEvent events.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireDisconnectedEvents() {
- ArrayList<HostListener> registered = null;
- HostEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- HostListener l = i.next();
- if (ev == null) {
- ev = new HostEvent(this);
- }
- l.disconnected(ev);
- }
- }
-
- /**
- * class to poll the remote machine and generate local event notifications.
- */
- private class NotifierTask extends CountedTimerTask {
- public void run() {
- super.run();
-
- // save the last set of active JVMs
- Set<Integer> lastActiveVms = activeVms;
-
- try {
- // get the current set of active JVMs
- activeVms = (HashSet<Integer>)vmManager.activeVms();
-
- } catch (MonitorException e) {
- // XXX: use logging api
- System.err.println("MonitoredHostProvider: polling task "
- + "caught MonitorException:");
- e.printStackTrace();
-
- // mark the HostManager as errored and notify listeners
- setLastException(e);
- fireDisconnectedEvents();
- }
-
- if (activeVms.isEmpty()) {
- return;
- }
-
- Set<Integer> startedVms = new HashSet<>();
- Set<Integer> terminatedVms = new HashSet<>();
-
- for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
- Integer vmid = i.next();
- if (!lastActiveVms.contains(vmid)) {
- // a new file has been detected, add to set
- startedVms.add(vmid);
- }
- }
-
- for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
- /* empty */ ) {
- Integer o = i.next();
- if (!activeVms.contains(o)) {
- // JVM has terminated, remove it from the active list
- terminatedVms.add(o);
- }
- }
-
- if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
- fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
- }
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2014, 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.HostIdentifier;
-import sun.jvmstat.monitor.MonitorException;
-import sun.jvmstat.monitor.MonitoredHost;
-import sun.jvmstat.monitor.MonitoredHostService;
-
-public final class MonitoredHostRmiService implements MonitoredHostService {
-
- @Override
- public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
- return new MonitoredHostProvider(hostId);
- }
-
- @Override
- public String getScheme() {
- return "rmi";
- }
-
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004, 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import java.nio.ByteBuffer;
-
-/**
- * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
- * protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class is responsible for acquiring the instrumentation buffer
- * data for a remote target HotSpot Java Virtual Machine.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class PerfDataBuffer extends AbstractPerfDataBuffer {
-
- private RemoteVm rvm;
-
- /**
- * Create a PerfDataBuffer instance for accessing the specified
- * instrumentation buffer.
- *
- * @param rvm the proxy to the remote MonitredVm object
- * @param lvmid the local Java Virtual Machine Identifier of the
- * remote target.
- *
- * @throws MonitorException
- */
- public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
-
- this.rvm = rvm;
- try {
- ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
- sample(buffer);
- createPerfDataBuffer(buffer, lvmid);
-
- } catch (RemoteException e) {
- throw new MonitorException("Could not read data for remote JVM "
- + lvmid, e);
- }
- }
-
- /**
- * Get a copy of the remote instrumentation buffer.
- *<p>
- * The data in the remote instrumentation buffer is copied into
- * the local byte buffer.
- *
- * @param buffer the buffer to receive the copy of the remote
- * instrumentation buffer.
- * @throws RemoteException Thrown on any communications errors with
- * the remote system.
- */
- public void sample(ByteBuffer buffer) throws RemoteException {
- assert buffer != null;
- assert rvm != null;
- synchronized(buffer) {
- buffer.clear();
- buffer.put(rvm.getBytes());
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.rmi.*;
-
-/**
- * Concrete implementation of the AbstractMonitoredVm class for the
- * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class provides the ability to acquire to the instrumentation buffer
- * of a live, remote target Java Virtual Machine through an RMI server.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteMonitoredVm extends AbstractMonitoredVm {
-
- private ArrayList<VmListener> listeners;
- private NotifierTask notifierTask;
- private SamplerTask samplerTask;
- private Timer timer;
-
- private RemoteVm rvm;
- private ByteBuffer updateBuffer;
-
- /**
- * Create a RemoteMonitoredVm instance.
- *
- * @param rvm the proxy to the remote MonitoredVm instance.
- * @param vmid the vm identifier specifying the remot target JVM
- * @param timer the timer used to run polling tasks
- * @param interval the sampling interval
- */
- public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
- Timer timer, int interval)
- throws MonitorException {
- super(vmid, interval);
- this.rvm = rvm;
- pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
- this.listeners = new ArrayList<VmListener>();
- this.timer = timer;
- }
-
- /**
- * Method to attach to the remote MonitoredVm.
- */
- public void attach() throws MonitorException {
- updateBuffer = pdb.getByteBuffer().duplicate();
-
- // if continuous sampling is requested, register with the sampler thread
- if (interval > 0) {
- samplerTask = new SamplerTask();
- timer.schedule(samplerTask, 0, interval);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach() {
- try {
- if (interval > 0) {
- if (samplerTask != null) {
- samplerTask.cancel();
- samplerTask = null;
- }
- if (notifierTask != null) {
- notifierTask.cancel();
- notifierTask = null;
- }
- sample();
- }
- } catch (RemoteException e) {
- // XXX: - use logging api? throw an exception instead?
- System.err.println("Could not read data for remote JVM " + vmid);
- e.printStackTrace();
-
- } finally {
- super.detach();
- }
- }
-
- /**
- * Get a copy of the remote instrumentation buffer.
- *<p>
- * The data in the remote instrumentation buffer is copied into
- * a local byte buffer.
- *
- * @throws RemoteException Thrown on any communications errors with
- * the remote system.
- */
- public void sample() throws RemoteException {
- assert updateBuffer != null;
- ((PerfDataBuffer)pdb).sample(updateBuffer);
- }
-
- /**
- * Get the proxy to the remote MonitoredVm.
- *
- * @return RemoteVm - the proxy to the remote MonitoredVm.
- */
- public RemoteVm getRemoteVm() {
- return rvm;
- }
-
- /**
- * {@inheritDoc}
- */
- public void addVmListener(VmListener l) {
- synchronized(listeners) {
- listeners.add(l);
- if (notifierTask == null) {
- notifierTask = new NotifierTask();
- timer.schedule(notifierTask, 0, interval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeVmListener(VmListener l) {
- synchronized(listeners) {
- listeners.remove(l);
- if (listeners.isEmpty() && (notifierTask != null)) {
- notifierTask.cancel();
- notifierTask = null;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void setInterval(int newInterval) {
- synchronized(listeners) {
- if (newInterval == interval) {
- return;
- }
-
- int oldInterval = interval;
- super.setInterval(newInterval);
-
- if (samplerTask != null) {
- samplerTask.cancel();
- SamplerTask oldSamplerTask = samplerTask;
- samplerTask = new SamplerTask();
- CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
- samplerTask, oldInterval,
- newInterval);
- }
- if (notifierTask != null) {
- notifierTask.cancel();
- NotifierTask oldNotifierTask = notifierTask;
- notifierTask = new NotifierTask();
- CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
- notifierTask, oldInterval,
- newInterval);
- }
- }
- }
-
- /**
- * Fire MonitoredVmStructureChanged events.
- *
- * @param inserted List of Monitor objects inserted.
- * @param removed List of Monitor objects removed.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
- ArrayList<VmListener> registered = null;
- MonitorStatusChangeEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- VmListener l = i.next();
- if (ev == null) {
- ev = new MonitorStatusChangeEvent(this, inserted, removed);
- }
- l.monitorStatusChanged(ev);
- }
- }
-
- /**
- * Fire MonitoredVmStructureChanged events.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireMonitorsUpdatedEvents() {
- ArrayList<VmListener> registered = null;
- VmEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- VmListener l = i.next();
- if (ev == null) {
- ev = new VmEvent(this);
- }
- l.monitorsUpdated(ev);
- }
- }
-
- /*
- * Timer Tasks. There are two separate timer tasks here. The SamplerTask
- * is active whenever we are attached to the remote JVM with a periodic
- * sampling interval > 0. The NotifierTask is only active if a VmListener
- * has registered with this RemoteMonitoredVm instance. Also, in the future
- * we may want to run these tasks at different intervals. Currently,
- * they run at the same interval and some significant work may
- * need to be done to complete the separation of these two intervals.
- */
-
- /**
- * Class to periodically check the state of the defined monitors
- * for the remote MonitoredVm instance and to notify listeners of
- * any detected changes.
- */
- private class NotifierTask extends CountedTimerTask {
- public void run() {
- super.run();
- try {
- MonitorStatus status = getMonitorStatus();
-
- List<Monitor> inserted = status.getInserted();
- List<Monitor> removed = status.getRemoved();
-
- if (!inserted.isEmpty() || !removed.isEmpty()) {
- fireMonitorStatusChangedEvents(inserted, removed);
- }
- } catch (MonitorException e) {
- // XXX: use logging api? fire disconnect events? mark errored?
- // fireDisconnectedEvents();
- System.err.println("Exception updating monitors for "
- + getVmIdentifier());
- e.printStackTrace();
- // XXX: should we cancle the notifierTask here?
- // this.cancel();
- }
- }
- }
-
- /**
- * Class to periodically sample the remote instrumentation byte buffer
- * and refresh the local copy. Registered listeners are notified of
- * the completion of a sampling event.
- */
- private class SamplerTask extends CountedTimerTask {
- public void run() {
- super.run();
- try {
- sample();
- fireMonitorsUpdatedEvents();
-
- } catch (RemoteException e) {
- // XXX: use logging api, mark vm as errored.
- System.err.println("Exception taking sample for "
- + getVmIdentifier());
- e.printStackTrace();
- this.cancel();
- }
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2004, 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.jvmstat.perfdata.monitor.protocol.rmi;
-
-import java.util.*;
-import java.util.regex.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Class for managing the RemoteMonitoredVm instances on a remote system.
- * <p>
- * This class is responsible for the mechanism that detects the active
- * HotSpot Java Virtual Machines on the remote host and possibly for a
- * specific user. The ability to detect all possible HotSpot Java Virtual
- * Machines on the remote host may be limited by the permissions of the
- * principal running the RMI server application on the remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmManager {
-
- private RemoteHost remoteHost;
- private String user;
-
- /**
- * Creates a RemoteVmManager instance for the remote system.
- * <p>
- * Manages RemoteMonitordVm instances for which the principal
- * running the remote server has appropriate permissions.
- *
- * @param remoteHost the remote proxy object to the RMI server on
- * the remote system.
- */
- public RemoteVmManager(RemoteHost remoteHost) {
- this(remoteHost, null);
- }
-
- /**
- * Creates a RemoteVmManager instance for the given user.
- * <p>
- * Manages RemoteMonitoredVm instances for all remote Java Virtual
- * machines owned by the specified user on the remote system. The
- * RMI server on the remote system must have the appropriate permissions
- * to access the named users Java Virtual Machines.
- *
- * @param remoteHost the remote proxy object to the RMI server on
- * the remote system.
- * @param user the name of the user
- */
- public RemoteVmManager(RemoteHost remoteHost, String user) {
- this.user = user;
- this.remoteHost = remoteHost;
- }
-
- /**
- * Return the current set of monitorable Java Virtual Machines.
- * <p>
- * The set returned by this method depends on the user name passed
- * to the constructor. If no user name was specified, then this
- * method will return all candidate JVMs on the system. Otherwise,
- * only the JVMs for the given user will be returned. This assumes
- * that the RMI server process has the appropriate permissions to
- * access the target set of JVMs.
- *
- * @return Set - the Set of monitorable Java Virtual Machines
- */
- public Set<Integer> activeVms() throws MonitorException {
- int[] active = null;
-
- try {
- active = remoteHost.activeVms();
-
- } catch (RemoteException e) {
- throw new MonitorException("Error communicating with remote host: "
- + e.getMessage(), e);
- }
-
- Set<Integer> activeSet = new HashSet<Integer>(active.length);
-
- for (int i = 0; i < active.length; i++) {
- activeSet.add(active[i]);
- }
-
- return activeSet;
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
-
-
- Copyright (c) 2004, 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.
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides the implementation classes for the <em>rmi:</em> protocol for
-the HotSpot PerfData instrumentation buffer monitoring implementation.
-</p>
-<p>
-The <em>rmi:</em> protocol is the default protocol for the PerfData
-implementation when a hostname is specified as part of a HostIdentifier
-or VMIdentifier. It communicates with an RMI server on the remote machine
-that provides functions to get a list of available Java Virtual Machines
-and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
-The RMI server may or may not use the PerfData implementation on the
-remote host to acquire this information. The <em>jstatd</em> server
-provides a PerfData implementation of the RMI server.
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2004, 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.tools.jstatd;
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.registry.Registry;
-import java.rmi.registry.LocateRegistry;
-import java.net.MalformedURLException;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Application providing remote access to the jvmstat instrumentation
- * exported by local Java Virtual Machine processes. Remote access is
- * provided through an RMI interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class Jstatd {
-
- private static Registry registry;
- private static int port = -1;
- private static boolean startRegistry = true;
-
- private static void printUsage() {
- System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
- }
-
- static void bind(String name, RemoteHostImpl remoteHost)
- throws RemoteException, MalformedURLException, Exception {
-
- try {
- Naming.rebind(name, remoteHost);
- } catch (java.rmi.ConnectException e) {
- /*
- * either the registry is not running or we cannot contact it.
- * start an internal registry if requested.
- */
- if (startRegistry && registry == null) {
- int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
- registry = LocateRegistry.createRegistry(localport);
- bind(name, remoteHost);
- } else {
- throw e;
- }
- }
- }
-
- @SuppressWarnings("deprecation") // Use of RMISecurityManager
- public static void main(String[] args) {
- String rminame = null;
- int argc = 0;
-
- for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
- String arg = args[argc];
-
- if (arg.compareTo("-nr") == 0) {
- startRegistry = false;
- } else if (arg.startsWith("-p")) {
- if (arg.compareTo("-p") != 0) {
- port = Integer.parseInt(arg.substring(2));
- } else {
- argc++;
- if (argc >= args.length) {
- printUsage();
- System.exit(1);
- }
- port = Integer.parseInt(args[argc]);
- }
- } else if (arg.startsWith("-n")) {
- if (arg.compareTo("-n") != 0) {
- rminame = arg.substring(2);
- } else {
- argc++;
- if (argc >= args.length) {
- printUsage();
- System.exit(1);
- }
- rminame = args[argc];
- }
- } else {
- printUsage();
- System.exit(1);
- }
- }
-
- if (argc < args.length) {
- printUsage();
- System.exit(1);
- }
-
- if (System.getSecurityManager() == null) {
- System.setSecurityManager(new RMISecurityManager());
- }
-
- StringBuilder name = new StringBuilder();
-
- if (port >= 0) {
- name.append("//:").append(port);
- }
-
- if (rminame == null) {
- rminame = "JStatRemoteHost";
- }
-
- name.append("/").append(rminame);
-
- try {
- // use 1.5.0 dynamically generated subs.
- System.setProperty("java.rmi.server.ignoreSubClasses", "true");
- RemoteHostImpl remoteHost = new RemoteHostImpl();
- RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
- remoteHost, 0);
- bind(name.toString(), remoteHost);
- System.out.println("jstatd started (bound to " + name.toString() + ")");
- System.out.flush();
- } catch (MalformedURLException e) {
- if (rminame != null) {
- System.out.println("Bad RMI server name: " + rminame);
- } else {
- System.out.println("Bad RMI URL: " + name);
- }
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (java.rmi.ConnectException e) {
- // could not attach to or create a registry
- System.out.println("Could not contact RMI registry");
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (RemoteException e) {
- System.out.println("Could not bind " + name + " to RMI Registry");
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (Exception e) {
- System.out.println("Could not create remote object");
- e.printStackTrace(System.out);
- System.exit(1);
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteHostImpl.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2004, 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.tools.jstatd;
-
-import java.util.*;
-import java.nio.*;
-import java.io.*;
-import java.net.*;
-import java.rmi.*;
-import java.rmi.server.*;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteHost interface for the HotSpot
- * PerfData <em>rmi:</em> protocol.
- * <p>
- * This class provides remote access to the instrumentation exported
- * by HotSpot Java Virtual Machines through the PerfData shared memory
- * interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteHostImpl implements RemoteHost, HostListener {
-
- private MonitoredHost monitoredHost;
- private Set<Integer> activeVms;
-
- public RemoteHostImpl() throws MonitorException {
- try {
- monitoredHost = MonitoredHost.getMonitoredHost("localhost");
- } catch (URISyntaxException e) { }
-
- activeVms = monitoredHost.activeVms();
- monitoredHost.addHostListener(this);
- }
-
- public RemoteVm attachVm(int lvmid, String mode)
- throws RemoteException, MonitorException {
- Integer v = lvmid;
- RemoteVm stub = null;
- StringBuilder sb = new StringBuilder();
-
- sb.append("local://").append(lvmid).append("@localhost");
- if (mode != null) {
- sb.append("?mode=").append(mode);
- }
-
- String vmidStr = sb.toString();
-
- try {
- VmIdentifier vmid = new VmIdentifier(vmidStr);
- MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
- RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
- stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
- }
- catch (URISyntaxException e) {
- throw new RuntimeException("Malformed VmIdentifier URI: "
- + vmidStr, e);
- }
- return stub;
- }
-
- public void detachVm(RemoteVm rvm) throws RemoteException {
- rvm.detach();
- }
-
- public int[] activeVms() throws MonitorException {
- Object[] vms = null;
- int[] vmids = null;
-
- vms = monitoredHost.activeVms().toArray();
- vmids = new int[vms.length];
-
- for (int i = 0; i < vmids.length; i++) {
- vmids[i] = ((Integer)vms[i]).intValue();
- }
- return vmids;
- }
-
- public void vmStatusChanged(VmStatusChangeEvent ev) {
- synchronized(this.activeVms) {
- activeVms.retainAll(ev.getActive());
- }
- }
-
- public void disconnected(HostEvent ev) {
- // we only monitor the local host, so this event shouldn't occur.
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteVmImpl.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2004, 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.tools.jstatd;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
- * shared memory implementation of the jvmstat monitoring APIs. This class
- * providing remote access to the instrumentation exported by a local HotSpot
- * Java Virtual Machine. The instrumentation buffer is shipped in whole to
- * the remote machine, which is responsible for parsing and provide access
- * to the contained data.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmImpl implements RemoteVm {
-
- private BufferedMonitoredVm mvm;
-
- RemoteVmImpl(BufferedMonitoredVm mvm) {
- this.mvm = mvm;
- }
-
- public byte[] getBytes() {
- return mvm.getBytes();
- }
-
- public int getCapacity() {
- return mvm.getCapacity();
- }
-
- public void detach() {
- mvm.detach();
- }
-
- public int getLocalVmId() {
- return mvm.getVmIdentifier().getLocalVmId();
- }
-}
--- a/jdk/test/com/sun/jdi/DoubleAgentTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/com/sun/jdi/DoubleAgentTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -31,7 +31,7 @@
*
* @library /lib/testlibrary
* @modules java.management
- * @build jdk.testlibarary.*
+ * @build jdk.testlibrary.*
* @build DoubleAgentTest Exit0
* @run driver DoubleAgentTest
*/
--- a/jdk/test/com/sun/jdi/SuspendNoFlagTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/com/sun/jdi/SuspendNoFlagTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -29,7 +29,7 @@
* @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
*/
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java Mon Nov 30 13:27:19 2015 -0800
@@ -41,9 +41,9 @@
* @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 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/ToString.java Mon Nov 30 13:27:19 2015 -0800
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Long/ToString.java Mon Nov 30 13:27:19 2015 -0800
@@ -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);
+ }
+ }
+}
--- a/jdk/test/java/lang/invoke/T8139885.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/lang/invoke/T8139885.java Mon Nov 30 13:27:19 2015 -0800
@@ -34,6 +34,7 @@
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;
@@ -413,6 +414,18 @@
}
@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);
assertEquals(SpreadCollect.MT_collector1, collector.type());
--- a/jdk/test/java/sql/testng/test/sql/StatementTests.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/sql/testng/test/sql/StatementTests.java Mon Nov 30 13:27:19 2015 -0800
@@ -24,6 +24,7 @@
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 @@
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 @@
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
- public void test01() {
+ public void test01() throws SQLException {
stmt.enquoteLiteral(null);
}
@@ -90,6 +102,24 @@
}
/*
+ * 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
* a single quote will be converted into two single quotes in the literal.
@@ -114,6 +144,10 @@
@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 @@
*/
@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},};
+ }
+
}
--- a/jdk/test/java/util/Collections/CheckedMapBash.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/Collections/CheckedMapBash.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
}
@Test(dataProvider = "Supplier<Map<Integer,Integer>>")
- public static void testCheckeMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
+ public static void testCheckedMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
Map m = supplier.get();
for (int i=0; i<mapSize; i++)
if (m.put(new Integer(i), new Integer(2*i)) != null)
- fail("put returns a non-null value erroenously.");
+ fail("put returns a non-null value erroneously.");
for (int i=0; i<2*mapSize; i++)
if (m.containsValue(new Integer(i)) != (i%2==0))
fail("contains value "+i);
if (m.put(nil, nil) == null)
- fail("put returns a null value erroenously.");
+ fail("put returns a null value erroneously.");
Map m2 = supplier.get(); m2.putAll(m);
if (!m.equals(m2))
fail("Clone not equal to original. (1)");
@@ -147,7 +147,7 @@
ArrayList<Object[]> 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 static Collection<Object[]> 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);
}
}
--- a/jdk/test/java/util/Collections/CheckedSetBash.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/Collections/CheckedSetBash.java Mon Nov 30 13:27:19 2015 -0800
@@ -146,25 +146,26 @@
ArrayList<Object[]> 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<Object[]> 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);
}
}
--- a/jdk/test/java/util/Collections/EmptyCollectionSerialization.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/Collections/EmptyCollectionSerialization.java Mon Nov 30 13:27:19 2015 -0800
@@ -58,7 +58,7 @@
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 static Collection<Object[]> 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);
}
}
--- a/jdk/test/java/util/Locale/LocaleEnhanceTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/Locale/LocaleEnhanceTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -1180,8 +1180,11 @@
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;
}
--- a/jdk/test/java/util/ResourceBundle/Test4300693.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/ResourceBundle/Test4300693.java Mon Nov 30 13:27:19 2015 -0800
@@ -22,7 +22,6 @@
*/
/*
@test
- @ignore 6876961
@summary test that ResourceBundle.getBundle can be called recursively
@build Test4300693RB
@run main Test4300693
--- a/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -202,9 +202,9 @@
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);
--- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -85,7 +85,7 @@
@Test
public class SpliteratorTraversingAndSplittingTest {
- private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
+ private static final List<Integer> 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});
--- a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
+ final int maxPairs = (args.length > 0) ? Integer.parseInt(args[0]) : 5;
- if (args.length > 0)
- maxPairs = Integer.parseInt(args[0]);
-
- print = true;
-
+ 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<BlockingQueue<Integer>> queues = new ArrayList<>();
+ queues.add(new ArrayBlockingQueue<Integer>(100));
+ queues.add(new LinkedBlockingQueue<Integer>(100));
+ queues.add(new LinkedBlockingDeque<Integer>(100));
+ queues.add(new SynchronousQueue<Integer>());
+ // unbounded queue implementations are prone to OOME:
+ // PriorityBlockingQueue, LinkedTransferQueue
+ for (BlockingQueue<Integer> 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<Integer> 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<Integer> 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<Integer> 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");
+ }
+
+ for (int i = 1; i < npairs; i++) {
+ assertCancelled(prods[i]);
+ assertCancelled(cons[i]);
}
- Object p0 = prods[0].get();
- Object c0 = cons[0].get();
+ 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");
+ }
- 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");
+ 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) {}
+ }
+
+ class Producer implements Callable<Integer> {
+ public Integer call() throws Exception {
+ barrier.await();
+ 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();
}
- }
- 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");
+ return sum;
}
}
- static void oneTest(int pairs, int iters) throws Exception {
-
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
- oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8);
-
- /* unbounded queue implementations are prone to OOME
- oneRun(new PriorityBlockingQueue<Integer>(iters / 2 * pairs), pairs, iters / 4);
- oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
- */
- }
-
- abstract static class Stage implements Callable<Integer> {
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- final int iters;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
- }
- }
-
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
+ class Consumer implements Callable<Integer> {
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 {
+ 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);
- }
- }
-
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
- 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;
- }
- return new Integer(s);
+ return sum;
}
}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
checkInterrupted0(fs, immediateExecutor);
checkInterrupted0(fs, delayedExecutor);
stpe.shutdown();
- check(stpe.awaitTermination(10, SECONDS));
+ check(stpe.awaitTermination(10L, SECONDS));
}
static void testQueue(final BlockingQueue<Object> q) {
--- a/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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]);
+ final int maxProducers = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
- 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 <= maxProducers; i += (i+1) >>> 1) {
+ // 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<Integer>(100), i, 300);
+ run(new LinkedBlockingQueue<Integer>(100), i, 700);
+ run(new LinkedBlockingDeque<Integer>(100), i , 500);
+ run(new LinkedTransferQueue<Integer>(), i, 1000);
+ run(new PriorityBlockingQueue<Integer>(), i, 1000);
+ run(new SynchronousQueue<Integer>(), i, 500);
+ run(new SynchronousQueue<Integer>(true), i, 200);
+ run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
+ }
- for (int i = 1; i <= maxProducers; i += (i+1) >>> 1) {
- System.out.println("----------------------------------------");
- System.out.println("Producers:" + i);
- oneTest(i, iters);
- Thread.sleep(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<Integer>(CAPACITY), producers, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), producers, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), producers, iters);
- oneRun(new LinkedTransferQueue<Integer>(), producers, iters);
+ pool = null;
+ }
- // Don't run PBQ since can legitimately run out of memory
- // if (print)
- // System.out.print("PriorityBlockingQueue ");
- // oneRun(new PriorityBlockingQueue<Integer>(), producers, iters);
-
- oneRun(new SynchronousQueue<Integer>(), producers, iters);
- if (print)
- System.out.println("fair implementations:");
- oneRun(new SynchronousQueue<Integer>(true), producers, iters);
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), producers, iters);
+ static void run(BlockingQueue<Integer> queue, int nproducers, int iters) throws Exception {
+ new MultipleProducersSingleConsumerLoops(queue, nproducers, iters).run();
}
- abstract static class Stage implements Runnable {
- final int iters;
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
- }
+ final BlockingQueue<Integer> 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;
+
+ MultipleProducersSingleConsumerLoops(BlockingQueue<Integer> queue, int nproducers, int iters) {
+ this.queue = queue;
+ this.nproducers = nproducers;
+ this.iters = iters;
+ this.barrier = new CyclicBarrier(nproducers + 2, timer);
}
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
+ void run() throws Exception {
+ for (int i = 0; i < nproducers; i++)
+ pool.execute(new Producer());
+ pool.execute(new Consumer());
+ barrier.await();
+ barrier.await();
+ 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);
+ }
- public void run() {
+ abstract class CheckedRunnable implements Runnable {
+ abstract void realRun() throws Throwable;
+ public final 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;
+ realRun();
+ } catch (Throwable t) {
+ fail = t;
+ t.printStackTrace();
+ throw new AssertionError(t);
}
}
}
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
+ 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();
}
-
- 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<Integer> 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));
+ 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();
}
- pool.execute(new Consumer(q, barrier, iters * nproducers));
- barrier.await();
- barrier.await();
- long time = timer.getTime();
- checkSum();
- if (print)
- System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nproducers)) + " ns per transfer");
}
-
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
failed++;
for (StackTraceElement e : thread.getStackTrace())
System.err.println(e);
- // Kludge alert
- thread.stop();
thread.join(timeoutMillis);
}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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<Integer>(100), i, 500);
+ run(new LinkedBlockingQueue<Integer>(100), i, 1000);
+ run(new LinkedBlockingDeque<Integer>(100), i, 1000);
+ run(new LinkedTransferQueue<Integer>(), i, 1000);
+ run(new PriorityBlockingQueue<Integer>(), i, 1000);
+ run(new SynchronousQueue<Integer>(), i, 400);
+ run(new SynchronousQueue<Integer>(true), i, 300);
+ run(new ArrayBlockingQueue<Integer>(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<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
- oneRun(new PriorityBlockingQueue<Integer>(), pairs, iters);
- oneRun(new SynchronousQueue<Integer>(), pairs, iters);
+ static void run(BlockingQueue<Integer> queue, int pairs, int iters) throws Exception {
+ new ProducerConsumerLoops(queue, pairs, iters).run();
+ }
- if (print)
- System.out.println("fair implementations:");
+ final BlockingQueue<Integer> 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;
- oneRun(new SynchronousQueue<Integer>(true), pairs, iters);
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), pairs, iters);
+ ProducerConsumerLoops(BlockingQueue<Integer> queue, int pairs, int iters) {
+ this.queue = queue;
+ this.pairs = pairs;
+ this.iters = iters;
+ this.barrier = new CyclicBarrier(2 * pairs + 1, timer);
}
- abstract static class Stage implements Runnable {
- final int iters;
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
+ void run() throws Exception {
+ for (int i = 0; i < pairs; i++) {
+ pool.execute(new Producer());
+ pool.execute(new Consumer());
}
+ barrier.await();
+ barrier.await();
+ 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);
}
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
- public void run() {
+ abstract class CheckedRunnable implements Runnable {
+ abstract void realRun() throws Throwable;
+ public final 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;
+ realRun();
+ } catch (Throwable t) {
+ fail = t;
+ t.printStackTrace();
+ throw new AssertionError(t);
}
}
}
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
+ 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();
}
-
- 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<Integer> 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));
+ 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();
}
- barrier.await();
- barrier.await();
- long time = timer.getTime();
- checkSum();
- if (print)
- System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * npairs)) + " ns per transfer");
}
-
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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]);
+ final int maxConsumers = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
- 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 <= 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<Integer>(100), i, 1000);
+ run(new LinkedBlockingQueue<Integer>(100), i, 1000);
+ run(new LinkedBlockingDeque<Integer>(100), i, 1000);
+ run(new LinkedTransferQueue<Integer>(), i, 700);
+ run(new PriorityBlockingQueue<Integer>(), i, 1000);
+ run(new SynchronousQueue<Integer>(), i, 300);
+ run(new SynchronousQueue<Integer>(true), i, 200);
+ run(new ArrayBlockingQueue<Integer>(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<Integer>(CAPACITY), consumers, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), consumers, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), consumers, iters);
- oneRun(new LinkedTransferQueue<Integer>(), consumers, iters);
- oneRun(new PriorityBlockingQueue<Integer>(), consumers, iters);
- oneRun(new SynchronousQueue<Integer>(), consumers, iters);
- if (print)
- System.out.println("fair implementations:");
- oneRun(new SynchronousQueue<Integer>(true), consumers, iters);
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), consumers, iters);
+ static void run(BlockingQueue<Integer> queue, int consumers, int iters) throws Exception {
+ new SingleProducerMultipleConsumerLoops(queue, consumers, iters).run();
+ }
+
+ final BlockingQueue<Integer> queue;
+ final int consumers;
+ final int iters;
+ final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
+ final CyclicBarrier barrier;
+ Throwable fail;
+
+ SingleProducerMultipleConsumerLoops(BlockingQueue<Integer> queue, int consumers, int iters) {
+ this.queue = queue;
+ this.consumers = consumers;
+ this.iters = iters;
+ this.barrier = new CyclicBarrier(consumers + 2, timer);
}
- abstract static class Stage implements Runnable {
- final int iters;
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- volatile int result;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
+ 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);
}
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
- public void run() {
+ abstract class CheckedRunnable implements Runnable {
+ abstract void realRun() throws Throwable;
+ public final 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;
+ realRun();
+ } catch (Throwable t) {
+ fail = t;
+ t.printStackTrace();
+ throw new AssertionError(t);
}
}
}
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
+ class Producer extends CheckedRunnable {
+ volatile int result;
+ void realRun() throws Throwable {
+ barrier.await();
+ for (int i = 0; i < iters * consumers; i++) {
+ queue.put(new Integer(i));
+ }
+ barrier.await();
+ result = 432;
}
-
- 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<Integer> 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));
+ 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;
}
- barrier.await();
- barrier.await();
- long time = timer.getTime();
- if (print)
- System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nconsumers)) + " ns per transfer");
}
-
}
--- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
test(executor);
} finally {
executor.shutdown();
- executor.awaitTermination(30, SECONDS);
+ executor.awaitTermination(30L, SECONDS);
}
}
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
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 @@
}
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 @@
// 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 @@
static class Runner implements Runnable {
final Map<Integer,Integer> map;
final Integer[] key;
- final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
final CyclicBarrier barrier;
+ final SplittableRandom rnd;
int position;
int total;
- Runner(Map<Integer,Integer> map, Integer[] key, CyclicBarrier barrier) {
+ Runner(Map<Integer,Integer> 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;
--- a/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
oneRun(i, items, q);
}
pool.shutdown();
- check(pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS));
+ check(pool.awaitTermination(60L, SECONDS));
}
class Stage implements Callable<Integer> {
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Mon Nov 30 13:27:19 2015 -0800
@@ -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();
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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;
--- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java Mon Nov 30 13:27:19 2015 -0800
@@ -26,6 +26,7 @@
* @bug 8011645
* @summary CopyOnWriteArrayList.COWSubList.subList does not validate range properly
*/
+
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
--- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/CountDownLatch/Basic.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/CountDownLatch/Basic.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/DelayQueue/Iterate.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/DelayQueue/Iterate.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/DelayQueue/Stress.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/DelayQueue/Stress.java Mon Nov 30 13:27:19 2015 -0800
@@ -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
--- a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
oneRun(i, iters);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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<Integer> ecs =
@@ -66,7 +71,7 @@
Thread.sleep(100);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/ExecutorService/Invoke.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ExecutorService/Invoke.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
--- a/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java Mon Nov 30 13:27:19 2015 -0800
@@ -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<Integer> real;
@@ -44,7 +52,7 @@
final Random rnd = new Random();
@SuppressWarnings("serial")
- Throwable[] throwables = {
+ final Throwable[] throwables = {
new Exception() {},
new RuntimeException() {},
new Error() {}
--- a/jdk/test/java/util/concurrent/Executors/Throws.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Executors/Throws.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
// 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.
--- a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
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 @@
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();
--- a/jdk/test/java/util/concurrent/FutureTask/Customized.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/Customized.java Mon Nov 30 13:27:19 2015 -0800
@@ -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);
--- a/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
failed++;
for (StackTraceElement e : thread.getStackTrace())
System.err.println(e);
- // Kludge alert
- thread.stop();
thread.join(timeoutMillis);
}
}
--- a/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/FutureTask/Throw.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/FutureTask/Throw.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/Phaser/Basic.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Phaser/Basic.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
//----------------------------------------------------------------
// 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 void remove() {throw new UnsupportedOperationException();}};
}
+ 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 @@
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 @@
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 @@
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 @@
LinkedList<Arriver> arriverList = new LinkedList<Arriver>();
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 @@
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<Arriver> 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 @@
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();
--- a/jdk/test/java/util/concurrent/Phaser/FickleRegister.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Phaser/FickleRegister.java Mon Nov 30 13:27:19 2015 -0800
@@ -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);
--- a/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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); }
}
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Mon Nov 30 13:27:19 2015 -0800
@@ -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() {
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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\")",
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java Mon Nov 30 13:27:19 2015 -0800
@@ -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
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java Mon Nov 30 13:27:19 2015 -0800
@@ -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) {
--- a/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java Mon Nov 30 13:27:19 2015 -0800
@@ -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,
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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); }
}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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");
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
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);
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java Mon Nov 30 13:27:19 2015 -0800
@@ -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) {
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java Mon Nov 30 13:27:19 2015 -0800
@@ -30,9 +30,18 @@
// based on a test kindly provided by Holger Hoffstaette <holger@wizards.de>
-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
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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(
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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); }
}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 ---------------------------
--- a/jdk/test/java/util/concurrent/TimeUnit/Basic.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/TimeUnit/Basic.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
// 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),
};
}
--- a/jdk/test/java/util/concurrent/atomic/Lazy.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/atomic/Lazy.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
--- a/jdk/test/java/util/concurrent/atomic/Serial.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/atomic/Serial.java Mon Nov 30 13:27:19 2015 -0800
@@ -44,7 +44,6 @@
* Basic test to exercise the j.u.c.atomic classes that use serialization
* proxies.
*/
-
public class Serial {
public static void main(String[] args) {
--- a/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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);
+ final int maxThreads = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
+ int iters = 3000;
- 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;
-
+ 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 @@
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 @@
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 @@
}
return sum;
}
-
}
private static class FairReentrantReadWriteLockLoop extends LockLoop {
@@ -407,6 +373,5 @@
}
return sum;
}
-
}
}
--- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
} 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 {
--- a/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/locks/Lock/Mutex.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/Mutex.java Mon Nov 30 13:27:19 2015 -0800
@@ -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.
--- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Mon Nov 30 13:27:19 2015 -0800
@@ -40,7 +40,7 @@
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 @@
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 @@
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
--- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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.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 @@
private final AtomicReferenceArray<Thread> threads;
private final CountDownLatch done;
+ private final SplittableRandom rnd;
- Parker(AtomicReferenceArray<Thread> threads, CountDownLatch done) {
- this.threads = threads;
- this.done = done;
+ Parker(AtomicReferenceArray<Thread> 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 @@
private final AtomicReferenceArray<Thread> threads;
private final CountDownLatch done;
+ private final SplittableRandom rnd;
- Unparker(AtomicReferenceArray<Thread> threads, CountDownLatch done) {
- this.threads = threads;
- this.done = done;
+ Unparker(AtomicReferenceArray<Thread> 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 static void main(String[] args) throws Exception {
+ final SplittableRandom rnd = new SplittableRandom();
final ExecutorService pool = Executors.newCachedThreadPool();
final AtomicReferenceArray<Thread> 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 @@
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;
- }
- }
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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;
-
- print = true;
+ final int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5;
+ final int reps = 1; // increase for stress testing
- 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 @@
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 @@
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 @@
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 @@
barrier.await();
result += sum;
}
- catch (Exception ex) {
- ex.printStackTrace();
- return;
+ catch (Throwable ex) {
+ fail = ex;
+ throw new RuntimeException(ex);
}
}
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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];
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
}
}
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();
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
}
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);
}
}
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 {
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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,
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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;
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
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 @@
Map<Integer, Integer> map = (Map<Integer,Integer>)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 @@
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 @@
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<Integer,Integer> map;
final Integer[] key;
- final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
final CyclicBarrier barrier;
+ final SplittableRandom rnd;
int position;
int total;
- Runner(Map<Integer,Integer> map, Integer[] key, CyclicBarrier barrier) {
+ Runner(Map<Integer,Integer> 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;
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Mon Nov 30 13:27:19 2015 -0800
@@ -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
--- a/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 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 @@
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 @@
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 @@
}
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<Writer> writers = writerIterator(sl, gate);
Iterator<Reader> 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<nThreads; j++)
wThreads[j] = writers.next();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
wThreads[j].start();
Reader reader = readers.next(); reader.start();
toTheStartingGate(gate);
reader.join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
wThreads[j].join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
checkResult(wThreads[j], null);
checkResult(reader, null);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // Multiple readers single writer
+ System.out.print("Multiple readers single writer: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
- Phaser gate = new Phaser(102);
+ int nThreads = 10;
+ Phaser gate = new Phaser(nThreads + 2);
Iterator<Writer> writers = writerIterator(sl, gate);
Iterator<Reader> 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<nThreads; j++)
rThreads[j] = readers.next();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
rThreads[j].start();
Writer writer = writers.next(); writer.start();
toTheStartingGate(gate);
writer.join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
rThreads[j].join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
checkResult(rThreads[j], null);
checkResult(writer, null);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // thread interrupted
+ System.out.print("thread interrupted: ");
//----------------------------------------------------------------
try {
+ // We test interrupting both before and after trying to acquire
boolean view = false;
StampedLock sl = new StampedLock();
for (long timeout : new long[] { -1L, 30L, -1L, 30L }) {
- long stamp = sl.writeLock();
+ long stamp;
+ Thread.State state;
+
+ stamp = sl.writeLock();
try {
Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
r.start();
- // allow r to block
- Thread.sleep(2000);
r.interrupt();
r.join();
checkResult(r, InterruptedException.class);
} finally {
sl.unlockWrite(stamp);
}
+
+ stamp = sl.writeLock();
+ try {
+ Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
+ r.start();
+ waitForThreadToBlock(r);
+ r.interrupt();
+ r.join();
+ checkResult(r, InterruptedException.class);
+ } finally {
+ sl.unlockWrite(stamp);
+ }
+
stamp = sl.readLock();
try {
Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
w.start();
- // allow w to block
- Thread.sleep(2000);
w.interrupt();
w.join();
checkResult(w, InterruptedException.class);
} finally {
sl.unlockRead(stamp);
}
+
+ stamp = sl.readLock();
+ try {
+ Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
+ w.start();
+ waitForThreadToBlock(w);
+ w.interrupt();
+ w.join();
+ checkResult(w, InterruptedException.class);
+ } finally {
+ sl.unlockRead(stamp);
+ }
+
check(!sl.isReadLocked());
check(!sl.isWriteLocked());
check(!sl.tryUnlockRead());
@@ -457,22 +513,23 @@
view = true;
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // timeout
+ System.out.print("timeout: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
for (long timeout : new long[] { 0L, 5L }) {
long stamp = sl.writeLock();
try {
- check(sl.tryReadLock(timeout, SECONDS) == 0L);
+ check(sl.tryReadLock(timeout, MILLISECONDS) == 0L);
} finally {
sl.unlockWrite(stamp);
}
stamp = sl.readLock();
try {
- check(sl.tryWriteLock(timeout, SECONDS) == 0L);
+ check(sl.tryWriteLock(timeout, MILLISECONDS) == 0L);
} finally {
sl.unlockRead(stamp);
}
@@ -483,9 +540,10 @@
check(sl.tryOptimisticRead() != 0L);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // optimistic read
+ System.out.print("optimistic read: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
@@ -510,9 +568,10 @@
check(sl.validate(stamp) == false);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // convert
+ System.out.print("convert: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
@@ -527,12 +586,12 @@
check(sl.validate(stamp));
check(sl.isReadLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
check((stamp = sl.tryConvertToWriteLock(stamp)) != 0L);
check(sl.validate(stamp));
check(!sl.isReadLocked());
check(sl.isWriteLocked());
- check(sl.tryReadLock(1L, SECONDS) == 0L);
+ check(sl.tryReadLock(1L, MILLISECONDS) == 0L);
if (i != 0) {
sl.unlockWrite(stamp);
continue;
@@ -543,7 +602,7 @@
check(sl.isReadLocked());
check(!sl.isWriteLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
check((stamp = sl.tryConvertToOptimisticRead(stamp)) != 0L);
check(sl.validate(stamp));
check(!sl.isReadLocked());
@@ -551,9 +610,10 @@
check(sl.validate(stamp));
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // views
+ System.out.print("views: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
@@ -566,7 +626,7 @@
check(sl.isReadLocked());
check(!sl.isWriteLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
} finally {
rl.unlock();
}
@@ -578,7 +638,7 @@
check(!sl.isReadLocked());
check(sl.isWriteLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
} finally {
wl.unlock();
}
@@ -590,6 +650,7 @@
wl = rwl.writeLock();
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
}
//--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java Mon Nov 30 13:27:19 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -128,7 +128,7 @@
int instanceCount = 0;
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine
- .attach(Integer.toString(ProcessTools.getProcessId()));
+ .attach(Long.toString(ProcessTools.getProcessId()));
try {
try (InputStream heapHistoStream = vm.heapHisto("-live");
BufferedReader in = new BufferedReader(new InputStreamReader(heapHistoStream))) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/SAAJFactoryTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+import javax.xml.soap.MessageFactory;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+
+/*
+ * @test
+ * @bug 8131334
+ * @summary SAAJ Plugability Layer: using java.util.ServiceLoader
+ *
+ * There are unsafe scenarios not to be run within jdk build (relying on global jdk confguration)
+ *
+ * unsafe; not running:
+ *
+ * run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario1 javax.xml.soap.MessageFactory=saaj.factory.Valid -
+ * run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario3 javax.xml.soap.MessageFactory=non.existing.FactoryClass -
+ * run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario4 javax.xml.soap.MessageFactory=saaj.factory.Invalid -
+ * run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Valid3 SAAJFactoryTest saaj.factory.Valid3 -
+ * scenario13 javax.xml.soap.MessageFactory=saaj.factory.Valid saaj.factory.Valid2
+ * run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario14 javax.xml.soap.MessageFactory=saaj.factory.Valid saaj.factory.Valid2 -
+ *
+ * @build saaj.factory.*
+ *
+ * @run main/othervm SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl -
+ * scenario2 - -
+ * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Valid SAAJFactoryTest saaj.factory.Valid -
+ * scenario5 - -
+ * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.NonExisting SAAJFactoryTest
+ * - javax.xml.soap.SOAPException
+ * scenario6 - -
+ * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Invalid SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario7 - -
+ * @run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario8 - saaj.factory.Valid
+ * @run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario9 - saaj.factory.Valid
+ * @run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario10 - saaj.factory.NonExisting
+ * @run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario11 - saaj.factory.Invalid
+ * @run main/othervm SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl -
+ * scenario12 - -
+ * @run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario15 - saaj.factory.Valid
+ */
+public class SAAJFactoryTest {
+
+ // scenario name - just for logging
+ static String scenario;
+
+ // configuration to be created by the test
+ static Path providersDir = Paths.get(System.getProperty("test.classes"), "META-INF", "services");
+ static Path providersFile = providersDir.resolve("javax.xml.soap.MessageFactory");
+
+ // configuration to be created by the test
+ static Path jdkDir = Paths.get(System.getProperty("java.home"), "conf");
+ static Path jdkFile = jdkDir.resolve("jaxm.properties");
+
+ // java policy file for testing w/security manager
+ static String policy = System.getProperty("test.src", ".") + File.separator + "test.policy";
+
+
+ protected MessageFactory factory() throws Throwable {
+ try {
+ MessageFactory factory = MessageFactory.newInstance();
+ System.out.println(" TEST: factory class = [" + factory.getClass().getName() + "]\n");
+ return factory;
+ } catch (Throwable t) {
+ System.out.println(" TEST: Throwable [" + t.getClass().getName() + "] thrown.\n");
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ protected void test(String[] args) {
+ if (args.length < 5) throw new IllegalArgumentException("Incorrect test setup. Required 5 arguments: \n" +
+ " 1. expected factory class (if any)\n" +
+ " 2. expected \n" +
+ " 3. scenario name\n" +
+ " 4. jdk/conf configured provider class name\n" +
+ " 5. service loader provider class name");
+
+ scenario = args[2]; // scenario name
+ prepare(args[3], args[4]); // jdk/conf class, service loader class
+
+ try {
+ MessageFactory factory = factory();
+ assertTrue(factory != null, "No factory found.");
+ String className = factory.getClass().getName();
+ assertTrue(args[0].equals(className), "Incorrect factory: [" + className +
+ "], Expected: [" + args[0] + "]");
+
+ } catch (Throwable throwable) {
+ String expectedExceptionClass = args[1];
+ String throwableClass = throwable.getClass().getName();
+ boolean correctException = throwableClass.equals(expectedExceptionClass);
+ if (!correctException) {
+ throwable.printStackTrace();
+ }
+ assertTrue(correctException, "Got unexpected exception: [" +
+ throwableClass + "], expected: [" + expectedExceptionClass + "]");
+ } finally {
+ cleanResource(providersFile);
+ cleanResource(providersDir);
+
+ // unsafe; not running:
+ // cleanResource(jdkFile);
+ }
+ }
+
+ private void cleanResource(Path resource) {
+ try {
+ Files.deleteIfExists(resource);
+ } catch (IOException ignored) {
+ ignored.printStackTrace();
+ }
+ }
+
+ private void prepare(String propertiesClassName, String providerClassName) {
+
+ try {
+ log("providerClassName = " + providerClassName);
+ log("propertiesClassName = " + propertiesClassName);
+
+ setupFile(providersFile, providersDir, providerClassName);
+
+ // unsafe; not running:
+ //setupFile(jdkFile, jdkDir, propertiesClassName);
+
+ log(" SETUP OK.");
+
+ } catch (IOException e) {
+ log(" SETUP FAILED.");
+ e.printStackTrace();
+ }
+ }
+
+ private void setupFile(Path file, Path dir, String value) throws IOException {
+ cleanResource(file);
+ if (!"-".equals(value)) {
+ log("writing configuration [" + value + "] into file [" + file.toAbsolutePath() + "]");
+ Files.createDirectories(dir);
+ Files.write(
+ file,
+ value.getBytes(),
+ StandardOpenOption.CREATE);
+ }
+ }
+
+ private static void assertTrue(boolean condition, String msg) {
+ if (!condition) {
+ log(" FAILED - ERROR: " + msg);
+ throw new RuntimeException("[" + scenario + "] " + msg);
+ } else {
+ log(" PASSED.");
+ }
+ }
+
+ private static void log(String msg) {
+ System.out.println("[" + scenario + "] " + msg);
+ }
+
+
+ public static void main(String[] args) {
+ // no security manager
+ new SAAJFactoryTest().test(args);
+
+ System.out.println("Policy file: " + policy);
+ System.setProperty("java.security.policy", policy);
+
+ System.out.println("Install security manager...");
+ System.setSecurityManager(new SecurityManager());
+
+ // security manager enabled
+ new SAAJFactoryTest().test(args);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Invalid.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package saaj.factory;
+
+/**
+ * Invalid implementation class for tests
+ * - doesn't contain required static methods
+ */
+public class Invalid {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Valid.java Mon Nov 30 13:27:19 2015 -0800
@@ -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.
+ *
+ * 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 saaj.factory;
+
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Valid implementation class for tests
+ * - several implementations necessary to test different configuration approaches
+ */
+public class Valid extends MessageFactory {
+ @Override
+ public SOAPMessage createMessage() throws SOAPException {
+ return null;
+ }
+
+ @Override
+ public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Valid2.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package saaj.factory;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * (Another) Valid implementation class for tests
+ * - several implementations necessary to test different configuration approaches
+ */
+public class Valid2 extends MessageFactory {
+ @Override
+ public SOAPMessage createMessage() throws SOAPException {
+ return null;
+ }
+
+ @Override
+ public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Valid3.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package saaj.factory;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * (Another) Valid implementation class for tests
+ * - several implementations necessary to test different configuration approaches
+ */
+public class Valid3 extends MessageFactory {
+ @Override
+ public SOAPMessage createMessage() throws SOAPException {
+ return null;
+ }
+
+ @Override
+ public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/test.policy Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,7 @@
+grant {
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "${test.classes}${/}-", "read, write, delete";
+
+ // unsafe; not running:
+ //permission java.io.FilePermission "${java.home}${/}-", "read, write, delete";
+};
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/InputArguments.java Sun Nov 29 11:00:05 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2013, 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.
- */
-
-package jdk.testlibrary;
-
-import java.lang.management.RuntimeMXBean;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-/**
- * This class provides access to the input arguments to the VM.
- */
-public class InputArguments {
- private static final List<String> args;
-
- static {
- RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
- args = runtimeMxBean.getInputArguments();
- }
-
- /**
- * Returns true if {@code arg} is an input argument to the VM.
- *
- * This is useful for checking boolean flags such as -XX:+UseSerialGC or
- * -XX:-UsePerfData.
- *
- * @param arg The name of the argument.
- * @return {@code true} if the given argument is an input argument,
- * otherwise {@code false}.
- */
- public static boolean contains(String arg) {
- return args.contains(arg);
- }
-
- /**
- * Returns true if {@code prefix} is the start of an input argument to the
- * VM.
- *
- * This is useful for checking if flags describing a quantity, such as
- * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
- * To check if the flag -XX:MaxMetaspaceSize is set, use
- * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
- *
- * @param prefix The start of the argument.
- * @return {@code true} if the given argument is the start of an input
- * argument, otherwise {@code false}.
- */
- public static boolean containsPrefix(String prefix) {
- for (String arg : args) {
- if (arg.startsWith(prefix)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get the string containing input arguments passed to the VM
- */
- public static String getInputArguments() {
- StringBuilder result = new StringBuilder();
- for (String arg : args)
- result.append(arg).append(' ');
-
- return result.toString();
- }
-
-}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java Mon Nov 30 13:27:19 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -99,7 +99,7 @@
}
}
if (requestToCurrentProcess) {
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
}
if (jcmdArgs != null) {
for (String toolArg : jcmdArgs) {
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Mon Nov 30 13:27:19 2015 -0800
@@ -27,8 +27,6 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -253,11 +251,8 @@
*
* @return Process id
*/
- public static int getProcessId() throws Exception {
- RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
- int pid = Integer.parseInt(runtime.getName().split("@")[0]);
-
- return pid;
+ public static long getProcessId() {
+ return ProcessHandle.current().getPid();
}
/**
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java Mon Nov 30 13:27:19 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -23,9 +23,6 @@
package jdk.testlibrary;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
import java.util.concurrent.TimeoutException;
/**
@@ -204,46 +201,4 @@
}
return null;
}
-
- /**
- * Waits until {@link TestThread} is in the certain {@link State}
- * and blocking on {@code object}.
- *
- * @param state The thread state
- * @param object The object to block on
- */
- public void waitUntilBlockingOnObject(Thread.State state, Object object) {
- String want = object == null ? null : object.getClass().getName() + '@'
- + Integer.toHexString(System.identityHashCode(object));
- ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
- while (isAlive()) {
- ThreadInfo ti = tmx.getThreadInfo(getId());
- if (ti.getThreadState() == state
- && (want == null || want.equals(ti.getLockName()))) {
- return;
- }
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- }
- }
- }
-
- /**
- * Waits until {@link TestThread} is in native.
- */
- public void waitUntilInNative() {
- ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
- while (isAlive()) {
- ThreadInfo ti = tmx.getThreadInfo(getId());
- if (ti.isInNative()) {
- return;
- }
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- }
- }
- }
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/management/InputArguments.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+package jdk.testlibrary.management;
+
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+
+/**
+ * This class provides access to the input arguments to the VM.
+ */
+public class InputArguments {
+ private static final List<String> args;
+
+ static {
+ RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+ args = runtimeMxBean.getInputArguments();
+ }
+
+ /**
+ * Returns true if {@code arg} is an input argument to the VM.
+ *
+ * This is useful for checking boolean flags such as -XX:+UseSerialGC or
+ * -XX:-UsePerfData.
+ *
+ * @param arg The name of the argument.
+ * @return {@code true} if the given argument is an input argument,
+ * otherwise {@code false}.
+ */
+ public static boolean contains(String arg) {
+ return args.contains(arg);
+ }
+
+ /**
+ * Returns true if {@code prefix} is the start of an input argument to the
+ * VM.
+ *
+ * This is useful for checking if flags describing a quantity, such as
+ * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
+ * To check if the flag -XX:MaxMetaspaceSize is set, use
+ * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
+ *
+ * @param prefix The start of the argument.
+ * @return {@code true} if the given argument is the start of an input
+ * argument, otherwise {@code false}.
+ */
+ public static boolean hasArgStartingWith(String prefix) {
+ for (String arg : args) {
+ if (arg.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get the string containing input arguments passed to the VM
+ */
+ public static String getInputArguments() {
+ StringBuilder result = new StringBuilder();
+ for (String arg : args)
+ result.append(arg).append(' ');
+
+ return result.toString();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/management/ThreadMXBeanTool.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package jdk.testlibrary.management;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * A few utility methods to use ThreadMXBean.
+ */
+public final class ThreadMXBeanTool {
+
+ /**
+ * Waits until {@link Thread} is in the certain {@link State}
+ * and blocking on {@code object}.
+ *
+ * @param state The thread state
+ * @param object The object to block on
+ */
+ public static void waitUntilBlockingOnObject(Thread thread, Thread.State state, Object object)
+ throws InterruptedException {
+ String want = object == null ? null : object.getClass().getName() + '@'
+ + Integer.toHexString(System.identityHashCode(object));
+ ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+ while (thread.isAlive()) {
+ ThreadInfo ti = tmx.getThreadInfo(thread.getId());
+ if (ti.getThreadState() == state
+ && (want == null || want.equals(ti.getLockName()))) {
+ return;
+ }
+ Thread.sleep(1);
+ }
+ }
+
+ /**
+ * Waits until {@link Thread} is in native.
+ */
+ public static void waitUntilInNative(Thread thread) throws InterruptedException {
+ ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+ while (thread.isAlive()) {
+ ThreadInfo ti = tmx.getThreadInfo(thread.getId());
+ if (ti.isInNative()) {
+ return;
+ }
+ Thread.sleep(1);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/CastError.java Mon Nov 30 13:27:19 2015 -0800
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+
+/**
+ * @test
+ * @bug 8143913
+ * @requires os.family == "windows"
+ * @summary MSCAPI keystore should accept Certificate[] in setEntry()
+ */
+
+public class CastError {
+ public static void main(String[] args) throws Exception {
+ KeyStore ks = KeyStore.getInstance(
+ new File(System.getProperty("test.src"),
+ "../tools/jarsigner/JarSigning.keystore"),
+ "bbbbbb".toCharArray());
+
+ PrivateKey pk = (PrivateKey) ks.getKey("c", "bbbbbb".toCharArray());
+ Certificate cert = ks.getCertificate("c");
+
+ ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+
+ ks.setKeyEntry("8143913", pk, null, new Certificate[]{cert});
+ ks.deleteEntry("8143913");
+ }
+}
--- a/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java Mon Nov 30 13:27:19 2015 -0800
@@ -25,6 +25,7 @@
* @test
* @bug 8048357
* @summary PKCS8 Standards Conformance Tests
+ * @requires (os.family != "solaris")
* @modules java.base/sun.security.pkcs
* java.base/sun.security.util
* java.base/sun.security.provider
@@ -33,6 +34,11 @@
* @compile -XDignore.symbol.file PKCS8Test.java
* @run main PKCS8Test
*/
+
+/*
+ * Skip Solaris since the DSAPrivateKeys returned by
+ * SunPKCS11 Provider are not subclasses of PKCS8Key
+ */
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
@@ -43,7 +49,6 @@
import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import sun.security.x509.AlgorithmId;
-
import static java.lang.System.out;
public class PKCS8Test {
@@ -191,7 +196,14 @@
public static void main(String[] args)
throws IOException, InvalidKeyException {
- byte[] encodedKey = getEncodedKey();
+ BigInteger p = BigInteger.valueOf(1);
+ BigInteger q = BigInteger.valueOf(2);
+ BigInteger g = BigInteger.valueOf(3);
+ BigInteger x = BigInteger.valueOf(4);
+
+ DSAPrivateKey priv = new DSAPrivateKey(p, q, g, x);
+
+ byte[] encodedKey = priv.getEncoded();
byte[] expectedBytes = new byte[EXPECTED.length];
for (int i = 0; i < EXPECTED.length; i++) {
expectedBytes[i] = (byte) EXPECTED[i];
@@ -203,6 +215,7 @@
}
PKCS8Key decodedKey = PKCS8Key.parse(new DerValue(encodedKey));
+
String alg = decodedKey.getAlgorithm();
AlgorithmId algId = decodedKey.getAlgorithmId();
out.println("Algorithm :" + alg);
@@ -265,30 +278,10 @@
+ EXCEPTION_MESSAGE + " get: " + e.getMessage());
}
}
-
- }
-
- // get a byte array from somewhere
- static byte[] getEncodedKey() throws InvalidKeyException {
- BigInteger p = BigInteger.valueOf(1);
- BigInteger q = BigInteger.valueOf(2);
- BigInteger g = BigInteger.valueOf(3);
- BigInteger x = BigInteger.valueOf(4);
-
- DSAPrivateKey priv = new DSAPrivateKey(p, q, g, x);
- return priv.getEncoded();
}
static void dumpByteArray(String nm, byte[] bytes) throws IOException {
out.println(nm + " length: " + bytes.length);
hexDump.encodeBuffer(bytes, out);
}
-
- static String toString(PKCS8Key key) {
- StringBuilder builder = new StringBuilder(key.getAlgorithm());
- builder.append('\n').append("parameters:")
- .append(key.getAlgorithmId().toString());
- return builder.toString();
- }
-
}
--- a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Mon Nov 30 13:27:19 2015 -0800
@@ -71,7 +71,7 @@
output.shouldHaveExitValue(0);
output.shouldNotContain("Exception");
- output.shouldContain(Integer.toString(ProcessTools.getProcessId()) + ":");
+ output.shouldContain(Long.toString(ProcessTools.getProcessId()) + ":");
matchJcmdCommands(output);
output.shouldContain("For more information about a specific command use 'help <command>'.");
}
--- a/jdk/test/sun/tools/jinfo/JInfoHelper.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/sun/tools/jinfo/JInfoHelper.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 @@
}
}
if (toPid) {
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
}
ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
--- a/jdk/test/sun/tools/jmap/BasicJMapTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/sun/tools/jmap/BasicJMapTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -42,9 +42,9 @@
* @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 @@
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(",", ""));
--- a/jdk/test/sun/tools/jps/JpsBase.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/sun/tools/jps/JpsBase.java Mon Nov 30 13:27:19 2015 -0800
@@ -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 static void main(String[] args) throws Exception {
- int pid = ProcessTools.getProcessId();
+ long pid = ProcessTools.getProcessId();
List<List<JpsHelper.JpsArg>> combinations = JpsHelper.JpsArg.generateCombinations();
for (List<JpsHelper.JpsArg> combination : combinations) {
@@ -76,7 +76,7 @@
// 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
--- a/jdk/test/sun/tools/jstack/BasicJStackTest.java Sun Nov 29 11:00:05 2015 -0800
+++ b/jdk/test/sun/tools/jstack/BasicJStackTest.java Mon Nov 30 13:27:19 2015 -0800
@@ -63,7 +63,7 @@
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(",", ""));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/MultiRelease.java Mon Nov 30 13:27:19 2015 -0800
@@ -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<TestCase> 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<String> 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<String> 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<String> 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<String> 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<String> 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());
+ }
+ }
+}