--- old/src/os/linux/vm/os_linux.cpp Tue May 10 22:14:33 2016 +++ new/src/os/linux/vm/os_linux.cpp Tue May 10 22:14:32 2016 @@ -638,7 +638,7 @@ // create new thread // Thread start routine for all newly created threads -static void *java_start(Thread *thread) { +static void *thread_native_entry(Thread *thread) { // Try to randomize the cache line index of hot stack frames. // This helps when threads of the same stack traces evict each other's // cache lines. The threads can be either from the same JVM instance, or @@ -690,6 +690,15 @@ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", os::current_thread_id(), (uintx) pthread_self()); + // If a thread has not deleted itself ("delete this") as part of its + // termination sequence, we have to ensure thread-local-storage is + // cleared before we actually terminate. No threads should ever be + // deleted asynchronously with respect to their termination. + if (Thread::current_or_null_safe() != NULL) { + assert(Thread::current_or_null_safe() == thread, "current thread is wrong"); + thread->clear_thread_current(); + } + return 0; } @@ -753,7 +762,7 @@ { pthread_t tid; - int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); + int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread); char buf[64]; if (ret == 0) { @@ -881,18 +890,21 @@ void os::free_thread(OSThread* osthread) { assert(osthread != NULL, "osthread not set"); - if (Thread::current()->osthread() == osthread) { + // We are told to free resources of the argument thread, + // but we can only really operate on the current thread. + assert(Thread::current()->osthread() == osthread, + "os::free_thread but not current thread"); + #ifdef ASSERT - sigset_t current; - sigemptyset(¤t); - pthread_sigmask(SIG_SETMASK, NULL, ¤t); - assert(!sigismember(¤t, SR_signum), "SR signal should not be blocked!"); + sigset_t current; + sigemptyset(¤t); + pthread_sigmask(SIG_SETMASK, NULL, ¤t); + assert(!sigismember(¤t, SR_signum), "SR signal should not be blocked!"); #endif - // Restore caller's signal mask - sigset_t sigmask = osthread->caller_sigmask(); - pthread_sigmask(SIG_SETMASK, &sigmask, NULL); - } + // Restore caller's signal mask + sigset_t sigmask = osthread->caller_sigmask(); + pthread_sigmask(SIG_SETMASK, &sigmask, NULL); delete osthread; }