mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
8268773: Improvements related to: Failed to start thread - pthread_create failed (EAGAIN)
Reviewed-by: stuefe, iklam
This commit is contained in:
parent
ea77ef8348
commit
e35005d5ce
8 changed files with 75 additions and 29 deletions
|
@ -814,19 +814,24 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||||
ret = pthread_attr_setguardsize(&attr, 0);
|
ret = pthread_attr_setguardsize(&attr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResourceMark rm;
|
||||||
pthread_t tid = 0;
|
pthread_t tid = 0;
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
int limit = 3;
|
||||||
|
do {
|
||||||
|
ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
||||||
|
} while (ret == EAGAIN && limit-- > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
|
log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
|
||||||
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
||||||
} else {
|
} else {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
log_warning(os, thread)("Failed to start thread - pthread_create failed (%d=%s) for attributes: %s.",
|
log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%d=%s) for attributes: %s.",
|
||||||
ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
thread->name(), ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
||||||
// Log some OS information which might explain why creating the thread failed.
|
// Log some OS information which might explain why creating the thread failed.
|
||||||
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
||||||
LogStream st(Log(os, thread)::info());
|
LogStream st(Log(os, thread)::info());
|
||||||
|
|
|
@ -631,16 +631,22 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||||
ThreadState state;
|
ThreadState state;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
ResourceMark rm;
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
int ret = 0;
|
||||||
|
int limit = 3;
|
||||||
|
do {
|
||||||
|
ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
||||||
|
} while (ret == EAGAIN && limit-- > 0);
|
||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
|
log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
|
||||||
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
||||||
} else {
|
} else {
|
||||||
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
|
log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%s) for attributes: %s.",
|
||||||
os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
thread->name(), os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
||||||
// Log some OS information which might explain why creating the thread failed.
|
// Log some OS information which might explain why creating the thread failed.
|
||||||
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
||||||
LogStream st(Log(os, thread)::info());
|
LogStream st(Log(os, thread)::info());
|
||||||
|
|
|
@ -863,16 +863,21 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||||
ThreadState state;
|
ThreadState state;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
ResourceMark rm;
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
int ret = 0;
|
||||||
|
int limit = 3;
|
||||||
|
do {
|
||||||
|
ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
|
||||||
|
} while (ret == EAGAIN && limit-- > 0);
|
||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
|
log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
|
||||||
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
||||||
} else {
|
} else {
|
||||||
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
|
log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%s) for attributes: %s.",
|
||||||
os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
thread->name(), os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
|
||||||
// Log some OS information which might explain why creating the thread failed.
|
// Log some OS information which might explain why creating the thread failed.
|
||||||
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
||||||
LogStream st(Log(os, thread)::info());
|
LogStream st(Log(os, thread)::info());
|
||||||
|
|
|
@ -743,21 +743,27 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||||
// flag appears to work with _beginthredex() as well.
|
// flag appears to work with _beginthredex() as well.
|
||||||
|
|
||||||
const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;
|
const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;
|
||||||
HANDLE thread_handle =
|
HANDLE thread_handle;
|
||||||
(HANDLE)_beginthreadex(NULL,
|
int limit = 3;
|
||||||
(unsigned)stack_size,
|
do {
|
||||||
(unsigned (__stdcall *)(void*)) thread_native_entry,
|
thread_handle =
|
||||||
thread,
|
(HANDLE)_beginthreadex(NULL,
|
||||||
initflag,
|
(unsigned)stack_size,
|
||||||
&thread_id);
|
(unsigned (__stdcall *)(void*)) thread_native_entry,
|
||||||
|
thread,
|
||||||
|
initflag,
|
||||||
|
&thread_id);
|
||||||
|
} while (thread_handle == NULL && errno == EAGAIN && limit-- > 0);
|
||||||
|
|
||||||
|
ResourceMark rm;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
if (thread_handle != NULL) {
|
if (thread_handle != NULL) {
|
||||||
log_info(os, thread)("Thread started (tid: %u, attributes: %s)",
|
log_info(os, thread)("Thread \"%s\" started (tid: %u, attributes: %s)",
|
||||||
thread_id, describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
|
thread->name(), thread_id,
|
||||||
|
describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
|
||||||
} else {
|
} else {
|
||||||
log_warning(os, thread)("Failed to start thread - _beginthreadex failed (%s) for attributes: %s.",
|
log_warning(os, thread)("Failed to start thread \"%s\" - _beginthreadex failed (%s) for attributes: %s.",
|
||||||
os::errno_name(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
|
thread->name(), os::errno_name(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
|
||||||
// Log some OS information which might explain why creating the thread failed.
|
// Log some OS information which might explain why creating the thread failed.
|
||||||
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());
|
||||||
LogStream st(Log(os, thread)::info());
|
LogStream st(Log(os, thread)::info());
|
||||||
|
|
|
@ -2909,6 +2909,9 @@ JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
|
||||||
assert(native_thread != NULL, "Starting null thread?");
|
assert(native_thread != NULL, "Starting null thread?");
|
||||||
|
|
||||||
if (native_thread->osthread() == NULL) {
|
if (native_thread->osthread() == NULL) {
|
||||||
|
ResourceMark rm(thread);
|
||||||
|
log_warning(os, thread)("Failed to start the native thread for java.lang.Thread \"%s\"",
|
||||||
|
JavaThread::name_for(JNIHandles::resolve_non_null(jthread)));
|
||||||
// No one should hold a reference to the 'native_thread'.
|
// No one should hold a reference to the 'native_thread'.
|
||||||
native_thread->smr_delete();
|
native_thread->smr_delete();
|
||||||
if (JvmtiExport::should_post_resource_exhausted()) {
|
if (JvmtiExport::should_post_resource_exhausted()) {
|
||||||
|
|
|
@ -446,6 +446,13 @@ bool Thread::is_JavaThread_protected(const JavaThread* p) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the target hasn't been started yet then it is trivially
|
||||||
|
// "protected". We assume the caller is the thread that will do
|
||||||
|
// the starting.
|
||||||
|
if (p->osthread() == NULL || p->osthread()->get_state() <= INITIALIZED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Now make the simple checks based on who the caller is:
|
// Now make the simple checks based on who the caller is:
|
||||||
Thread* current_thread = Thread::current();
|
Thread* current_thread = Thread::current();
|
||||||
if (current_thread == p || Threads_lock->owner() == current_thread) {
|
if (current_thread == p || Threads_lock->owner() == current_thread) {
|
||||||
|
@ -2146,7 +2153,7 @@ const char* JavaThread::name() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a non-NULL representation of this thread's name, or a suitable
|
// Returns a non-NULL representation of this thread's name, or a suitable
|
||||||
// descriptive string if there is no set name
|
// descriptive string if there is no set name.
|
||||||
const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
|
const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
|
||||||
const char* name_str;
|
const char* name_str;
|
||||||
oop thread_obj = threadObj();
|
oop thread_obj = threadObj();
|
||||||
|
@ -2170,6 +2177,19 @@ const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
|
||||||
return name_str;
|
return name_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to extract the name from the thread oop for logging.
|
||||||
|
const char* JavaThread::name_for(oop thread_obj) {
|
||||||
|
assert(thread_obj != NULL, "precondition");
|
||||||
|
oop name = java_lang_Thread::name(thread_obj);
|
||||||
|
const char* name_str;
|
||||||
|
if (name != NULL) {
|
||||||
|
name_str = java_lang_String::as_utf8_string(name);
|
||||||
|
} else {
|
||||||
|
name_str = "<un-named>";
|
||||||
|
}
|
||||||
|
return name_str;
|
||||||
|
}
|
||||||
|
|
||||||
void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
|
void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
|
||||||
|
|
||||||
assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
|
assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
|
||||||
|
|
|
@ -1379,6 +1379,7 @@ class JavaThread: public Thread {
|
||||||
// Misc. operations
|
// Misc. operations
|
||||||
const char* name() const;
|
const char* name() const;
|
||||||
const char* type_name() const { return "JavaThread"; }
|
const char* type_name() const { return "JavaThread"; }
|
||||||
|
static const char* name_for(oop thread_obj);
|
||||||
|
|
||||||
void print_on(outputStream* st, bool print_extended_info) const;
|
void print_on(outputStream* st, bool print_extended_info) const;
|
||||||
void print_on(outputStream* st) const { print_on(st, false); }
|
void print_on(outputStream* st) const { print_on(st, false); }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016 SAP SE and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016 SAP SE and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -41,7 +41,7 @@ import jdk.test.lib.process.ProcessTools;
|
||||||
public class ThreadLoggingTest {
|
public class ThreadLoggingTest {
|
||||||
|
|
||||||
static void analyzeOutputForInfoLevel(OutputAnalyzer output) throws Exception {
|
static void analyzeOutputForInfoLevel(OutputAnalyzer output) throws Exception {
|
||||||
output.shouldContain("Thread started");
|
output.shouldMatch("Thread .* started");
|
||||||
output.shouldContain("Thread is alive");
|
output.shouldContain("Thread is alive");
|
||||||
output.shouldContain("Thread finished");
|
output.shouldContain("Thread finished");
|
||||||
output.shouldHaveExitValue(0);
|
output.shouldHaveExitValue(0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue