# HG changeset patch # User dsamersoff # Date 1396702505 25200 # Node ID ac74f81a5157c3fbced27cb240f5ca7029e1193c # Parent 18e9943475b34431af2a1dad1ad7c34c676038ae# Parent 42d397967053da743d5d45756eeb43eeb8865205 Merge diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -2811,18 +2811,13 @@ os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN; } -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities // Threads on Linux are all with same priority. The Solaris style // os::yield_all() with nanosleep(1ms) is not necessary. sched_yield(); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support @@ -3079,7 +3074,7 @@ for (int n = 0; !osthread->sr.is_suspended(); n++) { for (int i = 0; i < RANDOMLY_LARGE_INTEGER2 && !osthread->sr.is_suspended(); i++) { - os::yield_all(i); + os::yield_all(); } // timeout, try to cancel the request @@ -3113,7 +3108,7 @@ if (sr_notify(osthread) == 0) { for (int n = 0; n < RANDOMLY_LARGE_INTEGER && !osthread->sr.is_running(); n++) { for (int i = 0; i < 100 && !osthread->sr.is_running(); i++) { - os::yield_all(i); + os::yield_all(); } } } else { diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -917,9 +917,20 @@ ////////////////////////////////////////////////////////////////////////////// // thread local storage +// Restore the thread pointer if the destructor is called. This is in case +// someone from JNI code sets up a destructor with pthread_key_create to run +// detachCurrentThread on thread death. Unless we restore the thread pointer we +// will hang or crash. When detachCurrentThread is called the key will be set +// to null and we will not be called again. If detachCurrentThread is never +// called we could loop forever depending on the pthread implementation. +static void restore_thread_pointer(void* p) { + Thread* thread = (Thread*) p; + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +} + int os::allocate_thread_local_storage() { pthread_key_t key; - int rslt = pthread_key_create(&key, NULL); + int rslt = pthread_key_create(&key, restore_thread_pointer); assert(rslt == 0, "cannot allocate thread local storage"); return (int)key; } @@ -2551,18 +2562,13 @@ os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities // Threads on Bsd are all with same priority. The Solaris style // os::yield_all() with nanosleep(1ms) is not necessary. sched_yield(); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -1032,9 +1032,20 @@ ////////////////////////////////////////////////////////////////////////////// // thread local storage +// Restore the thread pointer if the destructor is called. This is in case +// someone from JNI code sets up a destructor with pthread_key_create to run +// detachCurrentThread on thread death. Unless we restore the thread pointer we +// will hang or crash. When detachCurrentThread is called the key will be set +// to null and we will not be called again. If detachCurrentThread is never +// called we could loop forever depending on the pthread implementation. +static void restore_thread_pointer(void* p) { + Thread* thread = (Thread*) p; + os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); +} + int os::allocate_thread_local_storage() { pthread_key_t key; - int rslt = pthread_key_create(&key, NULL); + int rslt = pthread_key_create(&key, restore_thread_pointer); assert(rslt == 0, "cannot allocate thread local storage"); return (int)key; } @@ -3781,18 +3792,13 @@ os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities // Threads on Linux are all with same priority. The Solaris style // os::yield_all() with nanosleep(1ms) is not necessary. sched_yield(); } -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - //////////////////////////////////////////////////////////////////////////////// // thread priority support diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/solaris/vm/osThread_solaris.cpp --- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -49,16 +49,6 @@ // copied from synchronizer.cpp -void OSThread::handle_spinlock_contention(int tries) { - if (NoYieldsInMicrolock) return; - - if (tries > 10) { - os::yield_all(tries); // Yield to threads of any priority - } else if (tries > 5) { - os::yield(); // Yield to threads of same or higher priority - } -} - void OSThread::SR_handler(Thread* thread, ucontext_t* uc) { os::Solaris::SR_handler(thread, uc); } diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/solaris/vm/osThread_solaris.hpp --- a/hotspot/src/os/solaris/vm/osThread_solaris.hpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/solaris/vm/osThread_solaris.hpp Sat Apr 05 05:55:05 2014 -0700 @@ -82,8 +82,6 @@ void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; } static void SR_handler(Thread* thread, ucontext_t* uc); - static void handle_spinlock_contention(int tries); // Used for thread local eden locking - // *************************************************************** // Platform dependent initialization and cleanup // *************************************************************** diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -969,9 +969,6 @@ return true; } -// _T2_libthread is true if we believe we are running with the newer -// SunSoft lwp/libthread.so (2.8 patch, 2.9 default) -bool os::Solaris::_T2_libthread = false; bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { // Allocate the OSThread object @@ -1056,71 +1053,10 @@ thread->set_osthread(osthread); // Create the Solaris thread - // explicit THR_BOUND for T2_libthread case in case - // that assumption is not accurate, but our alternate signal stack - // handling is based on it which must have bound threads thread_t tid = 0; - long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED - | ((UseBoundThreads || os::Solaris::T2_libthread() || - (thr_type == vm_thread) || - (thr_type == cgc_thread) || - (thr_type == pgc_thread) || - (thr_type == compiler_thread && BackgroundCompilation)) ? - THR_BOUND : 0); + long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED; int status; - // 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs. - // - // On multiprocessors systems, libthread sometimes under-provisions our - // process with LWPs. On a 30-way systems, for instance, we could have - // 50 user-level threads in ready state and only 2 or 3 LWPs assigned - // to our process. This can result in under utilization of PEs. - // I suspect the problem is related to libthread's LWP - // pool management and to the kernel's SIGBLOCKING "last LWP parked" - // upcall policy. - // - // The following code is palliative -- it attempts to ensure that our - // process has sufficient LWPs to take advantage of multiple PEs. - // Proper long-term cures include using user-level threads bound to LWPs - // (THR_BOUND) or using LWP-based synchronization. Note that there is a - // slight timing window with respect to sampling _os_thread_count, but - // the race is benign. Also, we should periodically recompute - // _processors_online as the min of SC_NPROCESSORS_ONLN and the - // the number of PEs in our partition. You might be tempted to use - // THR_NEW_LWP here, but I'd recommend against it as that could - // result in undesirable growth of the libthread's LWP pool. - // The fix below isn't sufficient; for instance, it doesn't take into count - // LWPs parked on IO. It does, however, help certain CPU-bound benchmarks. - // - // Some pathologies this scheme doesn't handle: - // * Threads can block, releasing the LWPs. The LWPs can age out. - // When a large number of threads become ready again there aren't - // enough LWPs available to service them. This can occur when the - // number of ready threads oscillates. - // * LWPs/Threads park on IO, thus taking the LWP out of circulation. - // - // Finally, we should call thr_setconcurrency() periodically to refresh - // the LWP pool and thwart the LWP age-out mechanism. - // The "+3" term provides a little slop -- we want to slightly overprovision. - - if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) { - if (!(flags & THR_BOUND)) { - thr_setconcurrency (os::Solaris::_os_thread_count); // avoid starvation - } - } - // Although this doesn't hurt, we should warn of undefined behavior - // when using unbound T1 threads with schedctl(). This should never - // happen, as the compiler and VM threads are always created bound - DEBUG_ONLY( - if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) && - (!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) && - ((thr_type == vm_thread) || (thr_type == cgc_thread) || - (thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) { - warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound"); - } - ); - - // Mark that we don't have an lwp or thread id yet. // In case we attempt to set the priority before the thread starts. osthread->set_lwp_id(-1); @@ -1145,13 +1081,6 @@ // Remember that we created this thread so we can set priority on it osthread->set_vm_created(); - // Set the default thread priority. If using bound threads, setting - // lwp priority will be delayed until thread start. - set_native_priority(thread, - DefaultThreadPriority == -1 ? - java_to_os_priority[NormPriority] : - DefaultThreadPriority); - // Initial thread state is INITIALIZED, not SUSPENDED osthread->set_state(INITIALIZED); @@ -1333,39 +1262,8 @@ jt->set_stack_size(stack_size); } - // 5/22/01: Right now alternate signal stacks do not handle - // throwing stack overflow exceptions, see bug 4463178 - // Until a fix is found for this, T2 will NOT imply alternate signal - // stacks. - // If using T2 libthread threads, install an alternate signal stack. - // Because alternate stacks associate with LWPs on Solaris, - // see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads - // we prefer to explicitly stack bang. - // If not using T2 libthread, but using UseBoundThreads any threads - // (primordial thread, jni_attachCurrentThread) we do not create, - // probably are not bound, therefore they can not have an alternate - // signal stack. Since our stack banging code is generated and - // is shared across threads, all threads must be bound to allow - // using alternate signal stacks. The alternative is to interpose - // on _lwp_create to associate an alt sig stack with each LWP, - // and this could be a problem when the JVM is embedded. - // We would prefer to use alternate signal stacks with T2 - // Since there is currently no accurate way to detect T2 - // we do not. Assuming T2 when running T1 causes sig 11s or assertions - // on installing alternate signal stacks - - - // 05/09/03: removed alternate signal stack support for Solaris - // The alternate signal stack mechanism is no longer needed to - // handle stack overflow. This is now handled by allocating - // guard pages (red zone) and stackbanging. - // Initially the alternate signal stack mechanism was removed because - // it did not work with T1 llibthread. Alternate - // signal stacks MUST have all threads bound to lwps. Applications - // can create their own threads and attach them without their being - // bound under T1. This is frequently the case for the primordial thread. - // If we were ever to reenable this mechanism we would need to - // use the dynamic check for T2 libthread. + // With the T2 libthread (T1 is no longer supported) threads are always bound + // and we use stackbanging in all cases. os::Solaris::init_thread_fpu_state(); std::set_terminate(_handle_uncaught_cxx_exception); @@ -2092,12 +1990,7 @@ } void os::Solaris::print_libversion_info(outputStream* st) { - if (os::Solaris::T2_libthread()) { - st->print(" (T2 libthread)"); - } - else { - st->print(" (T1 libthread)"); - } + st->print(" (T2 libthread)"); st->cr(); } @@ -3323,41 +3216,10 @@ os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; } - -// On Solaris we found that yield_all doesn't always yield to all other threads. -// There have been cases where there is a thread ready to execute but it doesn't -// get an lwp as the VM thread continues to spin with sleeps of 1 millisecond. -// The 1 millisecond wait doesn't seem long enough for the kernel to issue a -// SIGWAITING signal which will cause a new lwp to be created. So we count the -// number of times yield_all is called in the one loop and increase the sleep -// time after 8 attempts. If this fails too we increase the concurrency level -// so that the starving thread would get an lwp - -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities - if (attempts == 0) { - os::sleep(Thread::current(), 1, false); - } else { - int iterations = attempts % 30; - if (iterations == 0 && !os::Solaris::T2_libthread()) { - // thr_setconcurrency and _getconcurrency make sense only under T1. - int noofLWPS = thr_getconcurrency(); - if (noofLWPS < (Threads::number_of_threads() + 2)) { - thr_setconcurrency(thr_getconcurrency() + 1); - } - } else if (iterations < 25) { - os::sleep(Thread::current(), 1, false); - } else { - os::sleep(Thread::current(), 10, false); - } - } -} - -// Called from the tight loops to possibly influence time-sharing heuristics -void os::loop_breaker(int attempts) { - os::yield_all(attempts); -} - + os::sleep(Thread::current(), 1, false); +} // Interface for setting lwp priorities. If we are using T2 libthread, // which forces the use of BoundThreads or we manually set UseBoundThreads, @@ -3365,6 +3227,9 @@ // function is meaningless in this mode so we must adjust the real lwp's priority // The routines below implement the getting and setting of lwp priorities. // +// Note: T2 is now the only supported libthread. UseBoundThreads flag is +// being deprecated and all threads are now BoundThreads +// // Note: There are three priority scales used on Solaris. Java priotities // which range from 1 to 10, libthread "thr_setprio" scale which range // from 0 to 127, and the current scheduling class of the process we @@ -3437,29 +3302,19 @@ if (!UseThreadPriorities) return 0; - // We are using Bound threads, we need to determine our priority ranges - if (os::Solaris::T2_libthread() || UseBoundThreads) { - // If ThreadPriorityPolicy is 1, switch tables - if (ThreadPriorityPolicy == 1) { - for (i = 0 ; i < CriticalPriority+1; i++) - os::java_to_os_priority[i] = prio_policy1[i]; - } - if (UseCriticalJavaThreadPriority) { - // MaxPriority always maps to the FX scheduling class and criticalPrio. - // See set_native_priority() and set_lwp_class_and_priority(). - // Save original MaxPriority mapping in case attempt to - // use critical priority fails. - java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority]; - // Set negative to distinguish from other priorities - os::java_to_os_priority[MaxPriority] = -criticalPrio; - } - } - // Not using Bound Threads, set to ThreadPolicy 1 - else { - for ( i = 0 ; i < CriticalPriority+1; i++ ) { + // If ThreadPriorityPolicy is 1, switch tables + if (ThreadPriorityPolicy == 1) { + for (i = 0 ; i < CriticalPriority+1; i++) os::java_to_os_priority[i] = prio_policy1[i]; - } - return 0; + } + if (UseCriticalJavaThreadPriority) { + // MaxPriority always maps to the FX scheduling class and criticalPrio. + // See set_native_priority() and set_lwp_class_and_priority(). + // Save original MaxPriority mapping in case attempt to + // use critical priority fails. + java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority]; + // Set negative to distinguish from other priorities + os::java_to_os_priority[MaxPriority] = -criticalPrio; } // Get IDs for a set of well-known scheduling classes. @@ -3583,10 +3438,6 @@ // set_lwp_class_and_priority -// -// Set the class and priority of the lwp. This call should only -// be made when using bound threads (T2 threads are bound by default). -// int set_lwp_class_and_priority(int ThreadID, int lwpid, int newPrio, int new_class, bool scale) { int rslt; @@ -3812,23 +3663,20 @@ status = thr_setprio(thread->osthread()->thread_id(), newpri); } - if (os::Solaris::T2_libthread() || - (UseBoundThreads && osthread->is_vm_created())) { - int lwp_status = - set_lwp_class_and_priority(osthread->thread_id(), - osthread->lwp_id(), - newpri, - fxcritical ? fxLimits.schedPolicy : myClass, - !fxcritical); - if (lwp_status != 0 && fxcritical) { - // Try again, this time without changing the scheduling class - newpri = java_MaxPriority_to_os_priority; - lwp_status = set_lwp_class_and_priority(osthread->thread_id(), - osthread->lwp_id(), - newpri, myClass, false); - } - status |= lwp_status; - } + int lwp_status = + set_lwp_class_and_priority(osthread->thread_id(), + osthread->lwp_id(), + newpri, + fxcritical ? fxLimits.schedPolicy : myClass, + !fxcritical); + if (lwp_status != 0 && fxcritical) { + // Try again, this time without changing the scheduling class + newpri = java_MaxPriority_to_os_priority; + lwp_status = set_lwp_class_and_priority(osthread->thread_id(), + osthread->lwp_id(), + newpri, myClass, false); + } + status |= lwp_status; return (status == 0) ? OS_OK : OS_ERR; } @@ -4495,13 +4343,6 @@ } } -// (Static) wrappers for the new libthread API -int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate; -int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate; -int_fnP_thread_t_i os::Solaris::_thr_setmutator; -int_fnP_thread_t os::Solaris::_thr_suspend_mutator; -int_fnP_thread_t os::Solaris::_thr_continue_mutator; - // (Static) wrapper for getisax(2) call. os::Solaris::getisax_func_t os::Solaris::_getisax = 0; @@ -4536,78 +4377,9 @@ return addr; } - - -// isT2_libthread() -// -// Routine to determine if we are currently using the new T2 libthread. -// -// We determine if we are using T2 by reading /proc/self/lstatus and -// looking for a thread with the ASLWP bit set. If we find this status -// bit set, we must assume that we are NOT using T2. The T2 team -// has approved this algorithm. -// -// We need to determine if we are running with the new T2 libthread -// since setting native thread priorities is handled differently -// when using this library. All threads created using T2 are bound -// threads. Calling thr_setprio is meaningless in this case. -// -bool isT2_libthread() { - static prheader_t * lwpArray = NULL; - static int lwpSize = 0; - static int lwpFile = -1; - lwpstatus_t * that; - char lwpName [128]; - bool isT2 = false; - -#define ADR(x) ((uintptr_t)(x)) -#define LWPINDEX(ary,ix) ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1)))) - - lwpFile = ::open("/proc/self/lstatus", O_RDONLY, 0); - if (lwpFile < 0) { - if (ThreadPriorityVerbose) warning ("Couldn't open /proc/self/lstatus\n"); - return false; - } - lwpSize = 16*1024; - for (;;) { - ::lseek64 (lwpFile, 0, SEEK_SET); - lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize, mtInternal); - if (::read(lwpFile, lwpArray, lwpSize) < 0) { - if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n"); - break; - } - if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) { - // We got a good snapshot - now iterate over the list. - int aslwpcount = 0; - for (int i = 0; i < lwpArray->pr_nent; i++ ) { - that = LWPINDEX(lwpArray,i); - if (that->pr_flags & PR_ASLWP) { - aslwpcount++; - } - } - if (aslwpcount == 0) isT2 = true; - break; - } - lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize; - FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal); // retry. - } - - FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal); - ::close (lwpFile); - if (ThreadPriorityVerbose) { - if (isT2) tty->print_cr("We are running with a T2 libthread\n"); - else tty->print_cr("We are not running with a T2 libthread\n"); - } - return isT2; -} - - void os::Solaris::libthread_init() { address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators"); - // Determine if we are running with the new T2 libthread - os::Solaris::set_T2_libthread(isT2_libthread()); - lwp_priocntl_init(); // RTLD_DEFAULT was not defined on some early versions of 5.5.1 @@ -4618,22 +4390,6 @@ guarantee(func != NULL, "libthread.so is too old."); } - // Initialize the new libthread getstate API wrappers - func = resolve_symbol("thr_getstate"); - os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func)); - - func = resolve_symbol("thr_setstate"); - os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func)); - - func = resolve_symbol("thr_setmutator"); - os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func)); - - func = resolve_symbol("thr_suspend_mutator"); - os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func)); - - func = resolve_symbol("thr_continue_mutator"); - os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func)); - int size; void (*handler_info_func)(address *, int *); handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo")); @@ -5536,11 +5292,7 @@ } bool os::is_thread_cpu_time_supported() { - if ( os::Solaris::T2_libthread() || UseBoundThreads ) { - return true; - } else { - return false; - } + return true; } // System loadavg support. Returns -1 if load average cannot be obtained. diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/solaris/vm/os_solaris.hpp --- a/hotspot/src/os/solaris/vm/os_solaris.hpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Sat Apr 05 05:55:05 2014 -0700 @@ -41,19 +41,6 @@ #define TRS_LWPID 2 #define TRS_INVALID 3 - // _T2_libthread is true if we believe we are running with the newer - // SunSoft lib/lwp/libthread: default Solaris 9, available Solaris 8 - // which is a lightweight libthread that also supports all T1 - static bool _T2_libthread; - // These refer to new libthread interface functions - // They get intialized if we dynamically detect new libthread - static int_fnP_thread_t_iP_uP_stack_tP_gregset_t _thr_getstate; - static int_fnP_thread_t_i_gregset_t _thr_setstate; - static int_fnP_thread_t_i _thr_setmutator; - static int_fnP_thread_t _thr_suspend_mutator; - static int_fnP_thread_t _thr_continue_mutator; - // libthread_init sets the above, if the new functionality is detected - // initialized to libthread or lwp synchronization primitives depending on UseLWPSychronization static int_fnP_mutex_tP _mutex_lock; static int_fnP_mutex_tP _mutex_trylock; @@ -214,29 +201,6 @@ static struct sigaction *get_chained_signal_action(int sig); static bool chained_handler(int sig, siginfo_t *siginfo, void *context); - // The following allow us to link against both the old and new libthread (2.8) - // and exploit the new libthread functionality if available. - - static bool T2_libthread() { return _T2_libthread; } - static void set_T2_libthread(bool T2_libthread) { _T2_libthread = T2_libthread; } - - static int thr_getstate(thread_t tid, int *flag, unsigned *lwp, stack_t *ss, gregset_t rs) - { return _thr_getstate(tid, flag, lwp, ss, rs); } - static void set_thr_getstate(int_fnP_thread_t_iP_uP_stack_tP_gregset_t func) - { _thr_getstate = func; } - - static int thr_setstate(thread_t tid, int flag, gregset_t rs) { return _thr_setstate(tid, flag, rs); } - static void set_thr_setstate(int_fnP_thread_t_i_gregset_t func) { _thr_setstate = func; } - - static int thr_setmutator(thread_t tid, int enabled) { return _thr_setmutator(tid, enabled); } - static void set_thr_setmutator(int_fnP_thread_t_i func) { _thr_setmutator = func; } - - static int thr_suspend_mutator(thread_t tid) { return _thr_suspend_mutator(tid); } - static void set_thr_suspend_mutator(int_fnP_thread_t func) { _thr_suspend_mutator = func; } - - static int thr_continue_mutator(thread_t tid) { return _thr_continue_mutator(tid); } - static void set_thr_continue_mutator(int_fnP_thread_t func) { _thr_continue_mutator = func; } - // Allows us to switch between lwp and thread -based synchronization static int mutex_lock(mutex_t *mx) { return _mutex_lock(mx); } static int mutex_trylock(mutex_t *mx) { return _mutex_trylock(mx); } diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -3518,7 +3518,7 @@ void os::yield() { os::NakedYield(); } -void os::yield_all(int attempts) { +void os::yield_all() { // Yields to all threads, including threads with lower priorities Sleep(1); } @@ -3864,12 +3864,6 @@ win32::setmode_streams(); init_page_sizes((size_t) win32::vm_page_size()); - // For better scalability on MP systems (must be called after initialize_system_info) -#ifndef PRODUCT - if (is_MP()) { - NoYieldsInMicrolock = true; - } -#endif // This may be overridden later when argument processing is done. FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation, os::win32::is_windows_2003()); diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os/windows/vm/os_windows.inline.hpp --- a/hotspot/src/os/windows/vm/os_windows.inline.hpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp Sat Apr 05 05:55:05 2014 -0700 @@ -52,9 +52,6 @@ return (void*)::GetProcAddress((HMODULE)lib, name); } -// Used to improve time-sharing on some systems -inline void os::loop_breaker(int attempts) {} - inline bool os::obsolete_option(const JavaVMOption *option) { return false; } diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -270,31 +270,6 @@ } } -static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { - char lwpstatusfile[PROCFILE_LENGTH]; - int lwpfd, err; - - if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) - return (err); - if (*flags == TRS_LWPID) { - sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), - *lwp); - if ((lwpfd = ::open(lwpstatusfile, O_RDONLY)) < 0) { - perror("thr_mutator_status: open lwpstatus"); - return (EINVAL); - } - if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != - sizeof (lwpstatus_t)) { - perror("thr_mutator_status: read lwpstatus"); - (void) ::close(lwpfd); - return (EINVAL); - } - (void) ::close(lwpfd); - } - return (0); -} - - bool os::is_allocatable(size_t bytes) { #ifdef _LP64 return true; diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -256,30 +256,6 @@ } } -static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { - char lwpstatusfile[PROCFILE_LENGTH]; - int lwpfd, err; - - if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) - return (err); - if (*flags == TRS_LWPID) { - sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), - *lwp); - if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) { - perror("thr_mutator_status: open lwpstatus"); - return (EINVAL); - } - if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != - sizeof (lwpstatus_t)) { - perror("thr_mutator_status: read lwpstatus"); - (void) close(lwpfd); - return (EINVAL); - } - (void) close(lwpfd); - } - return (0); -} - #ifndef AMD64 // Detecting SSE support by OS diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -307,6 +307,9 @@ JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) }, #endif // PRODUCT { "UseVMInterruptibleIO", JDK_Version::jdk(8), JDK_Version::jdk(9) }, + { "UseBoundThreads", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { NULL, JDK_Version(0), JDK_Version(0) } }; @@ -2078,17 +2081,6 @@ // Note: Needs platform-dependent factoring. bool status = true; - // Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product - // builds so the cost of stack banging can be measured. -#if (defined(PRODUCT) && defined(SOLARIS)) - if (!UseBoundThreads && !UseStackBanging) { - jio_fprintf(defaultStream::error_stream(), - "-UseStackBanging conflicts with -UseBoundThreads\n"); - - status = false; - } -#endif - if (TLABRefillWasteFraction == 0) { jio_fprintf(defaultStream::error_stream(), "TLABRefillWasteFraction should be a denominator, " diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -929,6 +929,10 @@ } void os::print_date_and_time(outputStream *st) { + const int secs_per_day = 86400; + const int secs_per_hour = 3600; + const int secs_per_min = 60; + time_t tloc; (void)time(&tloc); st->print("time: %s", ctime(&tloc)); // ctime adds newline. @@ -937,7 +941,17 @@ // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in // Linux. Must be a bug in glibc ? Workaround is to round "t" to int // before printf. We lost some precision, but who cares? - st->print_cr("elapsed time: %d seconds", (int)t); + int eltime = (int)t; // elapsed time in seconds + + // print elapsed time in a human-readable format: + int eldays = eltime / secs_per_day; + int day_secs = eldays * secs_per_day; + int elhours = (eltime - day_secs) / secs_per_hour; + int hour_secs = elhours * secs_per_hour; + int elmins = (eltime - day_secs - hour_secs) / secs_per_min; + int minute_secs = elmins * secs_per_min; + int elsecs = (eltime - day_secs - hour_secs - minute_secs); + st->print_cr("elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs); } // moved from debug.cpp (used to be find()) but still called from there diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.hpp Sat Apr 05 05:55:05 2014 -0700 @@ -450,8 +450,8 @@ // yield that can be used in lieu of blocking. } ; static YieldResult NakedYield () ; - static void yield_all(int attempts = 0); // Yields to all other threads including lower priority - static void loop_breaker(int attempts); // called from within tight loops to possibly influence time-sharing + static void yield_all(); // Yields to all other threads including lower priority + // (for the default scheduling policy) static OSReturn set_priority(Thread* thread, ThreadPriority priority); static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority); diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/safepoint.cpp --- a/hotspot/src/share/vm/runtime/safepoint.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -319,7 +319,7 @@ if (steps < DeferThrSuspendLoopCount) { os::NakedYield() ; } else { - os::yield_all(steps) ; + os::yield_all() ; // Alternately, the VM thread could transiently depress its scheduling priority or // transiently increase the priority of the tardy mutator(s). } diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -924,12 +924,6 @@ JRT_END #endif // !PRODUCT - -JRT_ENTRY(void, SharedRuntime::yield_all(JavaThread* thread, int attempts)) - os::yield_all(attempts); -JRT_END - - JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) assert(obj->is_oop(), "must be a valid oop"); assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/sharedRuntime.hpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Sat Apr 05 05:55:05 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -253,9 +253,6 @@ // bytecode tracing is only used by the TraceBytecodes static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0; - // Used to back off a spin lock that is under heavy contention - static void yield_all(JavaThread* thread, int attempts = 0); - static oop retrieve_receiver( Symbol* sig, frame caller ); static void register_finalizer(JavaThread* thread, oopDesc* obj); diff -r 18e9943475b3 -r ac74f81a5157 hotspot/src/share/vm/runtime/vmThread.cpp --- a/hotspot/src/share/vm/runtime/vmThread.cpp Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/src/share/vm/runtime/vmThread.cpp Sat Apr 05 05:55:05 2014 -0700 @@ -305,6 +305,9 @@ _terminate_lock->notify(); } + // Thread destructor usually does this. + ThreadLocalStorage::set_thread(NULL); + // Deletion must be done synchronously by the JNI DestroyJavaVM thread // so that the VMThread deletion completes before the main thread frees // up the CodeHeap. diff -r 18e9943475b3 -r ac74f81a5157 hotspot/test/runtime/6626217/Test6626217.sh --- a/hotspot/test/runtime/6626217/Test6626217.sh Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/test/runtime/6626217/Test6626217.sh Sat Apr 05 05:55:05 2014 -0700 @@ -22,7 +22,6 @@ # -# @ignore 8028733 # @test @(#)Test6626217.sh # @bug 6626217 # @summary Loader-constraint table allows arrays instead of only the base-classes diff -r 18e9943475b3 -r ac74f81a5157 hotspot/test/runtime/6888954/vmerrors.sh --- a/hotspot/test/runtime/6888954/vmerrors.sh Fri Apr 04 10:04:44 2014 -0700 +++ b/hotspot/test/runtime/6888954/vmerrors.sh Sat Apr 05 05:55:05 2014 -0700 @@ -85,7 +85,7 @@ [ $i -lt 10 ] && i2=0$i "$TESTJAVA/bin/java" $TESTVMOPTS -XX:+IgnoreUnrecognizedVMOptions \ - -XX:-TransmitErrorReport \ + -XX:-TransmitErrorReport -XX:-CreateMinidumpOnCrash \ -XX:ErrorHandlerTest=${i} -version > ${i2}.out 2>&1 # If ErrorHandlerTest is ignored (product build), stop.