提交 f86c4fa9 编写于 作者: D dholmes

8025198: Intermittent test failure: java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java

Reviewed-by: martin, dholmes
Contributed-by: NTristan Yan <tristan.yan@oracle.com>
上级 35304662
...@@ -154,7 +154,7 @@ define SetupLauncher ...@@ -154,7 +154,7 @@ define SetupLauncher
$(ORIGIN_ARG) \ $(ORIGIN_ARG) \
$$($1_LDFLAGS), \ $$($1_LDFLAGS), \
LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_NAME,$1), \ LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_NAME,$1), \
LDFLAGS_linux := -lpthread \ LDFLAGS_linux := -lpthread -lrt \
$(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \ $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \
LDFLAGS_solaris := $$($1_LDFLAGS_solaris) \ LDFLAGS_solaris := $$($1_LDFLAGS_solaris) \
$(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \ $(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)$(SHARED_LIBRARY_SUFFIX)), \
......
...@@ -414,7 +414,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \ ...@@ -414,7 +414,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \
LDFLAGS_macosx := -framework Cocoa -framework Security -framework ApplicationServices, \ LDFLAGS_macosx := -framework Cocoa -framework Security -framework ApplicationServices, \
LDFLAGS_SUFFIX_solaris := $(LIBZ) $(LIBDL) -lc, \ LDFLAGS_SUFFIX_solaris := $(LIBZ) $(LIBDL) -lc, \
LDFLAGS_SUFFIX_linux := $(LIBZ) $(LIBDL) -lc -lpthread, \ LDFLAGS_SUFFIX_linux := $(LIBZ) $(LIBDL) -lc -lpthread -lrt, \
LDFLAGS_SUFFIX_macosx := $(LIBZ), \ LDFLAGS_SUFFIX_macosx := $(LIBZ), \
LDFLAGS_SUFFIX_windows := \ LDFLAGS_SUFFIX_windows := \
-export:JLI_Launch \ -export:JLI_Launch \
......
...@@ -53,6 +53,8 @@ ...@@ -53,6 +53,8 @@
#include "java.h" #include "java.h"
#include <time.h>
/* /*
* A NOTE TO DEVELOPERS: For performance reasons it is important that * A NOTE TO DEVELOPERS: For performance reasons it is important that
* the program image remain relatively small until after SelectVersion * the program image remain relatively small until after SelectVersion
...@@ -167,6 +169,26 @@ static jlong threadStackSize = 0; /* stack size of the new thread */ ...@@ -167,6 +169,26 @@ static jlong threadStackSize = 0; /* stack size of the new thread */
static jlong maxHeapSize = 0; /* max heap size */ static jlong maxHeapSize = 0; /* max heap size */
static jlong initialHeapSize = 0; /* inital heap size */ static jlong initialHeapSize = 0; /* inital heap size */
static jlong timestamps[256];
static char* descriptors[256];
static int ts_index = 0;
static void stamp(char* info) {
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
timestamps[ts_index] = ((jlong)tp.tv_sec) * (1000 * 1000 * 1000) + tp.tv_nsec;
descriptors[ts_index++] = info;
}
static void report_times() {
printf("[0] %s\n", descriptors[0]);
int i;
for (i = 1; i < ts_index; i++) {
jlong elapsed = timestamps[i] - timestamps[i-1];
printf("[%d] elapsed us: %.3g - Next: %s\n", i, (elapsed/1000.0), descriptors[i]);
}
}
/* /*
* Entry point. * Entry point.
*/ */
...@@ -184,6 +206,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -184,6 +206,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
jint ergo /* ergonomics class policy */ jint ergo /* ergonomics class policy */
) )
{ {
stamp("Entered JLI_Launch");
int mode = LM_UNKNOWN; int mode = LM_UNKNOWN;
char *what = NULL; char *what = NULL;
char *cpath = 0; char *cpath = 0;
...@@ -203,6 +226,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -203,6 +226,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
_wc_enabled = cpwildcard; _wc_enabled = cpwildcard;
_ergo_policy = ergo; _ergo_policy = ergo;
stamp("InitLauncher");
InitLauncher(javaw); InitLauncher(javaw);
DumpState(); DumpState();
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
...@@ -231,8 +255,9 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -231,8 +255,9 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
* (Note: This side effect has been disabled. See comment on * (Note: This side effect has been disabled. See comment on
* bugid 5030265 below.) * bugid 5030265 below.)
*/ */
stamp("SelectVersion");
SelectVersion(argc, argv, &main_class); SelectVersion(argc, argv, &main_class);
stamp("CreateExecutionEnvironment");
CreateExecutionEnvironment(&argc, &argv, CreateExecutionEnvironment(&argc, &argv,
jrepath, sizeof(jrepath), jrepath, sizeof(jrepath),
jvmpath, sizeof(jvmpath), jvmpath, sizeof(jvmpath),
...@@ -244,11 +269,11 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -244,11 +269,11 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
start = CounterGet(); start = CounterGet();
} }
stamp("LoadJavaVM");
if (!LoadJavaVM(jvmpath, &ifn)) { if (!LoadJavaVM(jvmpath, &ifn)) {
return(6); return(6);
} }
stamp("Arg processing");
if (JLI_IsTraceLauncher()) { if (JLI_IsTraceLauncher()) {
end = CounterGet(); end = CounterGet();
} }
...@@ -295,8 +320,10 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -295,8 +320,10 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
/* set the -Dsun.java.launcher.* platform properties */ /* set the -Dsun.java.launcher.* platform properties */
SetJavaLauncherPlatformProps(); SetJavaLauncherPlatformProps();
stamp("JVMInit");
return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret); int res = JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);
stamp("initial thread DONE");
return res;
} }
/* /*
* Always detach the main thread so that it appears to have ended when * Always detach the main thread so that it appears to have ended when
...@@ -348,6 +375,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -348,6 +375,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
int JNICALL int JNICALL
JavaMain(void * _args) JavaMain(void * _args)
{ {
stamp("JavaMain");
JavaMainArgs *args = (JavaMainArgs *)_args; JavaMainArgs *args = (JavaMainArgs *)_args;
int argc = args->argc; int argc = args->argc;
char **argv = args->argv; char **argv = args->argv;
...@@ -363,11 +391,12 @@ JavaMain(void * _args) ...@@ -363,11 +391,12 @@ JavaMain(void * _args)
jobjectArray mainArgs; jobjectArray mainArgs;
int ret = 0; int ret = 0;
jlong start, end; jlong start, end;
stamp("RegisterThread");
RegisterThread(); RegisterThread();
/* Initialize the virtual machine */ /* Initialize the virtual machine */
start = CounterGet(); start = CounterGet();
stamp("InitializeJVM");
if (!InitializeJVM(&vm, &env, &ifn)) { if (!InitializeJVM(&vm, &env, &ifn)) {
JLI_ReportErrorMessage(JVM_ERROR1); JLI_ReportErrorMessage(JVM_ERROR1);
exit(1); exit(1);
...@@ -436,6 +465,7 @@ JavaMain(void * _args) ...@@ -436,6 +465,7 @@ JavaMain(void * _args)
* This method also correctly handles launching existing JavaFX * This method also correctly handles launching existing JavaFX
* applications that may or may not have a Main-Class manifest entry. * applications that may or may not have a Main-Class manifest entry.
*/ */
stamp("LoadMainClass");
mainClass = LoadMainClass(env, mode, what); mainClass = LoadMainClass(env, mode, what);
CHECK_EXCEPTION_NULL_LEAVE(mainClass); CHECK_EXCEPTION_NULL_LEAVE(mainClass);
/* /*
...@@ -444,6 +474,7 @@ JavaMain(void * _args) ...@@ -444,6 +474,7 @@ JavaMain(void * _args)
* applications own main class but rather a helper class. To keep things * applications own main class but rather a helper class. To keep things
* consistent in the UI we need to track and report the application main class. * consistent in the UI we need to track and report the application main class.
*/ */
stamp("GetApplicationClass");
appClass = GetApplicationClass(env); appClass = GetApplicationClass(env);
NULL_CHECK_RETURN_VALUE(appClass, -1); NULL_CHECK_RETURN_VALUE(appClass, -1);
/* /*
...@@ -453,6 +484,7 @@ JavaMain(void * _args) ...@@ -453,6 +484,7 @@ JavaMain(void * _args)
* instead of mainClass as that may be a launcher or helper class instead * instead of mainClass as that may be a launcher or helper class instead
* of the application class. * of the application class.
*/ */
stamp("PostJVMInit");
PostJVMInit(env, appClass, vm); PostJVMInit(env, appClass, vm);
/* /*
* The LoadMainClass not only loads the main class, it will also ensure * The LoadMainClass not only loads the main class, it will also ensure
...@@ -460,17 +492,20 @@ JavaMain(void * _args) ...@@ -460,17 +492,20 @@ JavaMain(void * _args)
* is not required. The main method is invoked here so that extraneous java * is not required. The main method is invoked here so that extraneous java
* stacks are not in the application stack trace. * stacks are not in the application stack trace.
*/ */
stamp("Get main method");
mainID = (*env)->GetStaticMethodID(env, mainClass, "main", mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
"([Ljava/lang/String;)V"); "([Ljava/lang/String;)V");
CHECK_EXCEPTION_NULL_LEAVE(mainID); CHECK_EXCEPTION_NULL_LEAVE(mainID);
stamp("CreateApplicationArgs");
/* Build platform specific argument array */ /* Build platform specific argument array */
mainArgs = CreateApplicationArgs(env, argv, argc); mainArgs = CreateApplicationArgs(env, argv, argc);
CHECK_EXCEPTION_NULL_LEAVE(mainArgs); CHECK_EXCEPTION_NULL_LEAVE(mainArgs);
/* Invoke main method. */ /* Invoke main method. */
stamp("Invoke main method");
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
stamp("main complete");
report_times();
/* /*
* The launcher's exit code (in the absence of calls to * The launcher's exit code (in the absence of calls to
* System.exit) will be non-zero if main threw an exception. * System.exit) will be non-zero if main threw an exception.
...@@ -1875,6 +1910,7 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize, ...@@ -1875,6 +1910,7 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize,
int argc, char **argv, int argc, char **argv,
int mode, char *what, int ret) int mode, char *what, int ret)
{ {
stamp("ContinueInNewThread");
/* /*
* If user doesn't specify stack size, check if VM has a preference. * If user doesn't specify stack size, check if VM has a preference.
...@@ -1900,7 +1936,7 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize, ...@@ -1900,7 +1936,7 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize,
args.mode = mode; args.mode = mode;
args.what = what; args.what = what;
args.ifn = *ifn; args.ifn = *ifn;
stamp("ContinueInNewThread0");
rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args); rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args);
/* If the caller has deemed there is an error we /* If the caller has deemed there is an error we
* simply return that, otherwise we return the value of * simply return that, otherwise we return the value of
......
...@@ -33,6 +33,7 @@ import java.security.*; ...@@ -33,6 +33,7 @@ import java.security.*;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.ReentrantLock;
public class ThrowingTasks { public class ThrowingTasks {
static final Random rnd = new Random(); static final Random rnd = new Random();
...@@ -156,6 +157,7 @@ public class ThrowingTasks { ...@@ -156,6 +157,7 @@ public class ThrowingTasks {
} }
static class CheckingExecutor extends ThreadPoolExecutor { static class CheckingExecutor extends ThreadPoolExecutor {
private final ReentrantLock lock = new ReentrantLock();
CheckingExecutor() { CheckingExecutor() {
super(10, 10, super(10, 10,
1L, TimeUnit.HOURS, 1L, TimeUnit.HOURS,
...@@ -163,10 +165,20 @@ public class ThrowingTasks { ...@@ -163,10 +165,20 @@ public class ThrowingTasks {
tf); tf);
} }
@Override protected void beforeExecute(Thread t, Runnable r) { @Override protected void beforeExecute(Thread t, Runnable r) {
allStarted.countDown(); final boolean lessThanCorePoolSize;
if (allStarted.getCount() < getCorePoolSize()) // Add a lock to sync allStarted.countDown() and
// allStarted.getCount() < getCorePoolSize()
lock.lock();
try {
allStarted.countDown();
lessThanCorePoolSize = allStarted.getCount() < getCorePoolSize();
} finally {
lock.unlock();
}
if (lessThanCorePoolSize) {
try { allContinue.await(); } try { allContinue.await(); }
catch (InterruptedException x) { unexpected(x); } catch (InterruptedException x) { unexpected(x); }
}
beforeExecuteCount.getAndIncrement(); beforeExecuteCount.getAndIncrement();
check(! isTerminated()); check(! isTerminated());
((Flaky)r).beforeExecute.run(); ((Flaky)r).beforeExecute.run();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册