src/os/solaris/vm/os_solaris.cpp

Print this page




 999 #endif
1000   if (_starting_thread == NULL) {
1001     _starting_thread = create_os_thread(thread, main_thread);
1002      if (_starting_thread == NULL) {
1003         return false;
1004      }
1005   }
1006 
1007   // The primodial thread is runnable from the start
1008   _starting_thread->set_state(RUNNABLE);
1009 
1010   thread->set_osthread(_starting_thread);
1011 
1012   // initialize signal mask for this thread
1013   // and save the caller's signal mask
1014   os::Solaris::hotspot_sigmask(thread);
1015 
1016   return true;
1017 }
1018 
1019 // _T2_libthread is true if we believe we are running with the newer
1020 // SunSoft lwp/libthread.so (2.8 patch, 2.9 default)
1021 bool os::Solaris::_T2_libthread = false;
1022 
1023 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
1024   // Allocate the OSThread object
1025   OSThread* osthread = new OSThread(NULL, NULL);
1026   if (osthread == NULL) {
1027     return false;
1028   }
1029 
1030   if ( ThreadPriorityVerbose ) {
1031     char *thrtyp;
1032     switch ( thr_type ) {
1033       case vm_thread:
1034         thrtyp = (char *)"vm";
1035         break;
1036       case cgc_thread:
1037         thrtyp = (char *)"cgc";
1038         break;
1039       case pgc_thread:
1040         thrtyp = (char *)"pgc";
1041         break;


1086 
1087   if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) {
1088     // We got lots of threads. Check if we still have some address space left.
1089     // Need to be at least 5Mb of unreserved address space. We do check by
1090     // trying to reserve some.
1091     const size_t VirtualMemoryBangSize = 20*K*K;
1092     char* mem = os::reserve_memory(VirtualMemoryBangSize);
1093     if (mem == NULL) {
1094       delete osthread;
1095       return false;
1096     } else {
1097       // Release the memory again
1098       os::release_memory(mem, VirtualMemoryBangSize);
1099     }
1100   }
1101 
1102   // Setup osthread because the child thread may need it.
1103   thread->set_osthread(osthread);
1104 
1105   // Create the Solaris thread
1106   // explicit THR_BOUND for T2_libthread case in case
1107   // that assumption is not accurate, but our alternate signal stack
1108   // handling is based on it which must have bound threads
1109   thread_t tid = 0;
1110   long     flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED
1111                    | ((UseBoundThreads || os::Solaris::T2_libthread() ||
1112                        (thr_type == vm_thread) ||
1113                        (thr_type == cgc_thread) ||
1114                        (thr_type == pgc_thread) ||
1115                        (thr_type == compiler_thread && BackgroundCompilation)) ?
1116                       THR_BOUND : 0);
1117   int      status;
1118 
1119   // 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs.
1120   //
1121   // On multiprocessors systems, libthread sometimes under-provisions our
1122   // process with LWPs.  On a 30-way systems, for instance, we could have
1123   // 50 user-level threads in ready state and only 2 or 3 LWPs assigned
1124   // to our process.  This can result in under utilization of PEs.
1125   // I suspect the problem is related to libthread's LWP
1126   // pool management and to the kernel's SIGBLOCKING "last LWP parked"
1127   // upcall policy.
1128   //
1129   // The following code is palliative -- it attempts to ensure that our
1130   // process has sufficient LWPs to take advantage of multiple PEs.
1131   // Proper long-term cures include using user-level threads bound to LWPs
1132   // (THR_BOUND) or using LWP-based synchronization.  Note that there is a
1133   // slight timing window with respect to sampling _os_thread_count, but
1134   // the race is benign.  Also, we should periodically recompute
1135   // _processors_online as the min of SC_NPROCESSORS_ONLN and the
1136   // the number of PEs in our partition.  You might be tempted to use
1137   // THR_NEW_LWP here, but I'd recommend against it as that could
1138   // result in undesirable growth of the libthread's LWP pool.
1139   // The fix below isn't sufficient; for instance, it doesn't take into count
1140   // LWPs parked on IO.  It does, however, help certain CPU-bound benchmarks.
1141   //
1142   // Some pathologies this scheme doesn't handle:
1143   // *  Threads can block, releasing the LWPs.  The LWPs can age out.
1144   //    When a large number of threads become ready again there aren't
1145   //    enough LWPs available to service them.  This can occur when the
1146   //    number of ready threads oscillates.
1147   // *  LWPs/Threads park on IO, thus taking the LWP out of circulation.
1148   //
1149   // Finally, we should call thr_setconcurrency() periodically to refresh
1150   // the LWP pool and thwart the LWP age-out mechanism.
1151   // The "+3" term provides a little slop -- we want to slightly overprovision.
1152 
1153   if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) {
1154     if (!(flags & THR_BOUND)) {
1155       thr_setconcurrency (os::Solaris::_os_thread_count);       // avoid starvation
1156     }
1157   }
1158   // Although this doesn't hurt, we should warn of undefined behavior
1159   // when using unbound T1 threads with schedctl().  This should never
1160   // happen, as the compiler and VM threads are always created bound
1161   DEBUG_ONLY(
1162       if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) &&
1163           (!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) &&
1164           ((thr_type == vm_thread) || (thr_type == cgc_thread) ||
1165            (thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) {
1166          warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound");
1167       }
1168   );
1169 
1170 
1171   // Mark that we don't have an lwp or thread id yet.
1172   // In case we attempt to set the priority before the thread starts.
1173   osthread->set_lwp_id(-1);
1174   osthread->set_thread_id(-1);
1175 
1176   status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
1177   if (status != 0) {
1178     if (PrintMiscellaneous && (Verbose || WizardMode)) {
1179       perror("os::create_thread");
1180     }
1181     thread->set_osthread(NULL);
1182     // Need to clean up stuff we've allocated so far
1183     delete osthread;
1184     return false;
1185   }
1186 
1187   Atomic::inc(&os::Solaris::_os_thread_count);
1188 
1189   // Store info on the Solaris thread into the OSThread
1190   osthread->set_thread_id(tid);
1191 
1192   // Remember that we created this thread so we can set priority on it
1193   osthread->set_vm_created();
1194 
1195   // Set the default thread priority.  If using bound threads, setting
1196   // lwp priority will be delayed until thread start.
1197   set_native_priority(thread,
1198                       DefaultThreadPriority == -1 ?
1199                         java_to_os_priority[NormPriority] :
1200                         DefaultThreadPriority);
1201 
1202   // Initial thread state is INITIALIZED, not SUSPENDED
1203   osthread->set_state(INITIALIZED);
1204 
1205   // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
1206   return true;
1207 }
1208 
1209 /* defined for >= Solaris 10. This allows builds on earlier versions
1210  *  of Solaris to take advantage of the newly reserved Solaris JVM signals
1211  *  With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
1212  *  and -XX:+UseAltSigs does nothing since these should have no conflict
1213  */
1214 #if !defined(SIGJVM1)
1215 #define SIGJVM1 39
1216 #define SIGJVM2 40
1217 #endif
1218 
1219 debug_only(static bool signal_sets_initialized = false);
1220 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
1221 int os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL;


1363 
1364     if (stack_size > jt->stack_size()) {
1365       NOT_PRODUCT(
1366         struct rlimit limits;
1367         getrlimit(RLIMIT_STACK, &limits);
1368         size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
1369         assert(size >= jt->stack_size(), "Stack size problem in main thread");
1370       )
1371       tty->print_cr(
1372         "Stack size of %d Kb exceeds current limit of %d Kb.\n"
1373         "(Stack sizes are rounded up to a multiple of the system page size.)\n"
1374         "See limit(1) to increase the stack size limit.",
1375         stack_size / K, jt->stack_size() / K);
1376       vm_exit(1);
1377     }
1378     assert(jt->stack_size() >= stack_size,
1379           "Attempt to map more stack than was allocated");
1380     jt->set_stack_size(stack_size);
1381   }
1382 
1383    // 5/22/01: Right now alternate signal stacks do not handle
1384    // throwing stack overflow exceptions, see bug 4463178
1385    // Until a fix is found for this, T2 will NOT imply alternate signal
1386    // stacks.
1387    // If using T2 libthread threads, install an alternate signal stack.
1388    // Because alternate stacks associate with LWPs on Solaris,
1389    // see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads
1390    // we prefer to explicitly stack bang.
1391    // If not using T2 libthread, but using UseBoundThreads any threads
1392    // (primordial thread, jni_attachCurrentThread) we do not create,
1393    // probably are not bound, therefore they can not have an alternate
1394    // signal stack. Since our stack banging code is generated and
1395    // is shared across threads, all threads must be bound to allow
1396    // using alternate signal stacks.  The alternative is to interpose
1397    // on _lwp_create to associate an alt sig stack with each LWP,
1398    // and this could be a problem when the JVM is embedded.
1399    // We would prefer to use alternate signal stacks with T2
1400    // Since there is currently no accurate way to detect T2
1401    // we do not. Assuming T2 when running T1 causes sig 11s or assertions
1402    // on installing alternate signal stacks
1403 
1404 
1405    // 05/09/03: removed alternate signal stack support for Solaris
1406    // The alternate signal stack mechanism is no longer needed to
1407    // handle stack overflow. This is now handled by allocating
1408    // guard pages (red zone) and stackbanging.
1409    // Initially the alternate signal stack mechanism was removed because
1410    // it did not work with T1 llibthread. Alternate
1411    // signal stacks MUST have all threads bound to lwps. Applications
1412    // can create their own threads and attach them without their being
1413    // bound under T1. This is frequently the case for the primordial thread.
1414    // If we were ever to reenable this mechanism we would need to
1415    // use the dynamic check for T2 libthread.
1416 
1417   os::Solaris::init_thread_fpu_state();
1418   std::set_terminate(_handle_uncaught_cxx_exception);
1419 }
1420 
1421 
1422 
1423 // Free Solaris resources related to the OSThread
1424 void os::free_thread(OSThread* osthread) {
1425   assert(osthread != NULL, "os::free_thread but osthread not set");
1426 
1427 
1428   // We are told to free resources of the argument thread,
1429   // but we can only really operate on the current thread.
1430   // The main thread must take the VMThread down synchronously
1431   // before the main thread exits and frees up CodeHeap
1432   guarantee((Thread::current()->osthread() == osthread
1433      || (osthread == VMThread::vm_thread()->osthread())), "os::free_thread but not current thread");
1434   if (Thread::current()->osthread() == osthread) {
1435     // Restore caller's signal mask
1436     sigset_t sigmask = osthread->caller_sigmask();


2122 
2123   os::Solaris::print_distro_info(st);
2124 
2125   os::Posix::print_uname_info(st);
2126 
2127   os::Solaris::print_libversion_info(st);
2128 
2129   os::Posix::print_rlimit_info(st);
2130 
2131   os::Posix::print_load_average(st);
2132 }
2133 
2134 void os::Solaris::print_distro_info(outputStream* st) {
2135   if (!_print_ascii_file("/etc/release", st)) {
2136       st->print("Solaris");
2137     }
2138     st->cr();
2139 }
2140 
2141 void os::Solaris::print_libversion_info(outputStream* st) {
2142   if (os::Solaris::T2_libthread()) {
2143     st->print("  (T2 libthread)");
2144   }
2145   else {
2146     st->print("  (T1 libthread)");
2147   }
2148   st->cr();
2149 }
2150 
2151 static bool check_addr0(outputStream* st) {
2152   jboolean status = false;
2153   int fd = ::open("/proc/self/map",O_RDONLY);
2154   if (fd >= 0) {
2155     prmap_t p;
2156     while(::read(fd, &p, sizeof(p)) > 0) {
2157       if (p.pr_vaddr == 0x0) {
2158         st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname);
2159         st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname);
2160         st->print("Access:");
2161         st->print("%s",(p.pr_mflags & MA_READ)  ? "r" : "-");
2162         st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-");
2163         st->print("%s",(p.pr_mflags & MA_EXEC)  ? "x" : "-");
2164         st->cr();
2165         status = true;
2166       }
2167     }


3353   else {
3354     return false;
3355   }
3356 }
3357 
3358 // Caveat: Solaris os::yield() causes a thread-state transition whereas
3359 // the linux and win32 implementations do not.  This should be checked.
3360 
3361 void os::yield() {
3362   // Yields to all threads with same or greater priority
3363   os::sleep(Thread::current(), 0, false);
3364 }
3365 
3366 // Note that yield semantics are defined by the scheduling class to which
3367 // the thread currently belongs.  Typically, yield will _not yield to
3368 // other equal or higher priority threads that reside on the dispatch queues
3369 // of other CPUs.
3370 
3371 os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; }
3372 
3373 
3374 // On Solaris we found that yield_all doesn't always yield to all other threads.
3375 // There have been cases where there is a thread ready to execute but it doesn't
3376 // get an lwp as the VM thread continues to spin with sleeps of 1 millisecond.
3377 // The 1 millisecond wait doesn't seem long enough for the kernel to issue a
3378 // SIGWAITING signal which will cause a new lwp to be created. So we count the
3379 // number of times yield_all is called in the one loop and increase the sleep
3380 // time after 8 attempts. If this fails too we increase the concurrency level
3381 // so that the starving thread would get an lwp
3382 
3383 void os::yield_all(int attempts) {
3384   // Yields to all threads, including threads with lower priorities
3385   if (attempts == 0) {
3386     os::sleep(Thread::current(), 1, false);
3387   } else {
3388     int iterations = attempts % 30;
3389     if (iterations == 0 && !os::Solaris::T2_libthread()) {
3390       // thr_setconcurrency and _getconcurrency make sense only under T1.
3391       int noofLWPS = thr_getconcurrency();
3392       if (noofLWPS < (Threads::number_of_threads() + 2)) {
3393         thr_setconcurrency(thr_getconcurrency() + 1);
3394       }
3395     } else if (iterations < 25) {
3396       os::sleep(Thread::current(), 1, false);
3397     } else {
3398       os::sleep(Thread::current(), 10, false);
3399     }
3400   }
3401 }
3402 
3403 // Called from the tight loops to possibly influence time-sharing heuristics
3404 void os::loop_breaker(int attempts) {
3405   os::yield_all(attempts);
3406 }
3407 
3408 
3409 // Interface for setting lwp priorities.  If we are using T2 libthread,
3410 // which forces the use of BoundThreads or we manually set UseBoundThreads,
3411 // all of our threads will be assigned to real lwp's.  Using the thr_setprio
3412 // function is meaningless in this mode so we must adjust the real lwp's priority
3413 // The routines below implement the getting and setting of lwp priorities.
3414 //



3415 // Note: There are three priority scales used on Solaris.  Java priotities
3416 //       which range from 1 to 10, libthread "thr_setprio" scale which range
3417 //       from 0 to 127, and the current scheduling class of the process we
3418 //       are running in.  This is typically from -60 to +60.
3419 //       The setting of the lwp priorities in done after a call to thr_setprio
3420 //       so Java priorities are mapped to libthread priorities and we map from
3421 //       the latter to lwp priorities.  We don't keep priorities stored in
3422 //       Java priorities since some of our worker threads want to set priorities
3423 //       higher than all Java threads.
3424 //
3425 // For related information:
3426 // (1)  man -s 2 priocntl
3427 // (2)  man -s 4 priocntl
3428 // (3)  man dispadmin
3429 // =    librt.so
3430 // =    libthread/common/rtsched.c - thrp_setlwpprio().
3431 // =    ps -cL <pid> ... to validate priority.
3432 // =    sched_get_priority_min and _max
3433 //              pthread_create
3434 //              sched_setparam


3467 static bool priocntl_enable = false;
3468 
3469 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
3470 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
3471 
3472 
3473 // lwp_priocntl_init
3474 //
3475 // Try to determine the priority scale for our process.
3476 //
3477 // Return errno or 0 if OK.
3478 //
3479 static int lwp_priocntl_init () {
3480   int rslt;
3481   pcinfo_t ClassInfo;
3482   pcparms_t ParmInfo;
3483   int i;
3484 
3485   if (!UseThreadPriorities) return 0;
3486 
3487   // We are using Bound threads, we need to determine our priority ranges
3488   if (os::Solaris::T2_libthread() || UseBoundThreads) {
3489     // If ThreadPriorityPolicy is 1, switch tables
3490     if (ThreadPriorityPolicy == 1) {
3491       for (i = 0 ; i < CriticalPriority+1; i++)
3492         os::java_to_os_priority[i] = prio_policy1[i];
3493     }
3494     if (UseCriticalJavaThreadPriority) {
3495       // MaxPriority always maps to the FX scheduling class and criticalPrio.
3496       // See set_native_priority() and set_lwp_class_and_priority().
3497       // Save original MaxPriority mapping in case attempt to
3498       // use critical priority fails.
3499       java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
3500       // Set negative to distinguish from other priorities
3501       os::java_to_os_priority[MaxPriority] = -criticalPrio;
3502     }
3503   }
3504   // Not using Bound Threads, set to ThreadPolicy 1
3505   else {
3506     for ( i = 0 ; i < CriticalPriority+1; i++ ) {
3507       os::java_to_os_priority[i] = prio_policy1[i];
3508     }
3509     return 0;
3510   }
3511 
3512   // Get IDs for a set of well-known scheduling classes.
3513   // TODO-FIXME: GETCLINFO returns the current # of classes in the
3514   // the system.  We should have a loop that iterates over the
3515   // classID values, which are known to be "small" integers.
3516 
3517   strcpy(ClassInfo.pc_clname, "TS");
3518   ClassInfo.pc_cid = -1;
3519   rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3520   if (rslt < 0) return errno;
3521   assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3522   tsLimits.schedPolicy = ClassInfo.pc_cid;
3523   tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3524   tsLimits.minPrio = -tsLimits.maxPrio;
3525 
3526   strcpy(ClassInfo.pc_clname, "IA");
3527   ClassInfo.pc_cid = -1;
3528   rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3529   if (rslt < 0) return errno;
3530   assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");


3613 #define FXPRI(x)        ((fxparms_t *)((x).pc_clparms))
3614 
3615 
3616 // scale_to_lwp_priority
3617 //
3618 // Convert from the libthread "thr_setprio" scale to our current
3619 // lwp scheduling class scale.
3620 //
3621 static
3622 int     scale_to_lwp_priority (int rMin, int rMax, int x)
3623 {
3624   int v;
3625 
3626   if (x == 127) return rMax;            // avoid round-down
3627     v = (((x*(rMax-rMin)))/128)+rMin;
3628   return v;
3629 }
3630 
3631 
3632 // set_lwp_class_and_priority
3633 //
3634 // Set the class and priority of the lwp.  This call should only
3635 // be made when using bound threads (T2 threads are bound by default).
3636 //
3637 int set_lwp_class_and_priority(int ThreadID, int lwpid,
3638                                int newPrio, int new_class, bool scale) {
3639   int rslt;
3640   int Actual, Expected, prv;
3641   pcparms_t ParmInfo;                   // for GET-SET
3642 #ifdef ASSERT
3643   pcparms_t ReadBack;                   // for readback
3644 #endif
3645 
3646   // Set priority via PC_GETPARMS, update, PC_SETPARMS
3647   // Query current values.
3648   // TODO: accelerate this by eliminating the PC_GETPARMS call.
3649   // Cache "pcparms_t" in global ParmCache.
3650   // TODO: elide set-to-same-value
3651 
3652   // If something went wrong on init, don't change priorities.
3653   if ( !priocntl_enable ) {
3654     if (ThreadPriorityVerbose)
3655       tty->print_cr("Trying to set priority but init failed, ignoring");
3656     return EINVAL;


3842   // Save requested priority in case the thread hasn't been started
3843   osthread->set_native_priority(newpri);
3844 
3845   // Check for critical priority request
3846   bool fxcritical = false;
3847   if (newpri == -criticalPrio) {
3848     fxcritical = true;
3849     newpri = criticalPrio;
3850   }
3851 
3852   assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
3853   if (!UseThreadPriorities) return OS_OK;
3854 
3855   int status = 0;
3856 
3857   if (!fxcritical) {
3858     // Use thr_setprio only if we have a priority that thr_setprio understands
3859     status = thr_setprio(thread->osthread()->thread_id(), newpri);
3860   }
3861 
3862   if (os::Solaris::T2_libthread() ||
3863       (UseBoundThreads && osthread->is_vm_created())) {
3864     int lwp_status =
3865       set_lwp_class_and_priority(osthread->thread_id(),
3866                                  osthread->lwp_id(),
3867                                  newpri,
3868                                  fxcritical ? fxLimits.schedPolicy : myClass,
3869                                  !fxcritical);
3870     if (lwp_status != 0 && fxcritical) {
3871       // Try again, this time without changing the scheduling class
3872       newpri = java_MaxPriority_to_os_priority;
3873       lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
3874                                               osthread->lwp_id(),
3875                                               newpri, myClass, false);
3876     }
3877     status |= lwp_status;
3878   }
3879   return (status == 0) ? OS_OK : OS_ERR;
3880 }
3881 
3882 
3883 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
3884   int p;
3885   if ( !UseThreadPriorities ) {
3886     *priority_ptr = NormalPriority;
3887     return OS_OK;
3888   }
3889   int status = thr_getprio(thread->osthread()->thread_id(), &p);
3890   if (status != 0) {
3891     return OS_ERR;
3892   }
3893   *priority_ptr = p;
3894   return OS_OK;
3895 }
3896 
3897 
3898 // Hint to the underlying OS that a task switch would not be good.


4525   "SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT",
4526   "SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU",
4527   "SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW",
4528   "SIGCANCEL", "SIGLOST"
4529 };
4530 
4531 const char* os::exception_name(int exception_code, char* buf, size_t size) {
4532   if (0 < exception_code && exception_code <= SIGRTMAX) {
4533     // signal
4534     if (exception_code < sizeof(signames)/sizeof(const char*)) {
4535        jio_snprintf(buf, size, "%s", signames[exception_code]);
4536     } else {
4537        jio_snprintf(buf, size, "SIG%d", exception_code);
4538     }
4539     return buf;
4540   } else {
4541     return NULL;
4542   }
4543 }
4544 
4545 // (Static) wrappers for the new libthread API
4546 int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate;
4547 int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate;
4548 int_fnP_thread_t_i os::Solaris::_thr_setmutator;
4549 int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
4550 int_fnP_thread_t os::Solaris::_thr_continue_mutator;
4551 
4552 // (Static) wrapper for getisax(2) call.
4553 os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
4554 
4555 // (Static) wrappers for the liblgrp API
4556 os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
4557 os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
4558 os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini;
4559 os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root;
4560 os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children;
4561 os::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources;
4562 os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps;
4563 os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
4564 os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
4565 
4566 // (Static) wrapper for meminfo() call.
4567 os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
4568 
4569 static address resolve_symbol_lazy(const char* name) {
4570   address addr = (address) dlsym(RTLD_DEFAULT, name);
4571   if(addr == NULL) {
4572     // RTLD_DEFAULT was not defined on some early versions of 2.5.1
4573     addr = (address) dlsym(RTLD_NEXT, name);
4574   }
4575   return addr;
4576 }
4577 
4578 static address resolve_symbol(const char* name) {
4579   address addr = resolve_symbol_lazy(name);
4580   if(addr == NULL) {
4581     fatal(dlerror());
4582   }
4583   return addr;
4584 }
4585 
4586 
4587 
4588 // isT2_libthread()
4589 //
4590 // Routine to determine if we are currently using the new T2 libthread.
4591 //
4592 // We determine if we are using T2 by reading /proc/self/lstatus and
4593 // looking for a thread with the ASLWP bit set.  If we find this status
4594 // bit set, we must assume that we are NOT using T2.  The T2 team
4595 // has approved this algorithm.
4596 //
4597 // We need to determine if we are running with the new T2 libthread
4598 // since setting native thread priorities is handled differently
4599 // when using this library.  All threads created using T2 are bound
4600 // threads. Calling thr_setprio is meaningless in this case.
4601 //
4602 bool isT2_libthread() {
4603   static prheader_t * lwpArray = NULL;
4604   static int lwpSize = 0;
4605   static int lwpFile = -1;
4606   lwpstatus_t * that;
4607   char lwpName [128];
4608   bool isT2 = false;
4609 
4610 #define ADR(x)  ((uintptr_t)(x))
4611 #define LWPINDEX(ary,ix)   ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1))))
4612 
4613   lwpFile = ::open("/proc/self/lstatus", O_RDONLY, 0);
4614   if (lwpFile < 0) {
4615       if (ThreadPriorityVerbose) warning ("Couldn't open /proc/self/lstatus\n");
4616       return false;
4617   }
4618   lwpSize = 16*1024;
4619   for (;;) {
4620     ::lseek64 (lwpFile, 0, SEEK_SET);
4621     lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize, mtInternal);
4622     if (::read(lwpFile, lwpArray, lwpSize) < 0) {
4623       if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n");
4624       break;
4625     }
4626     if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) {
4627        // We got a good snapshot - now iterate over the list.
4628       int aslwpcount = 0;
4629       for (int i = 0; i < lwpArray->pr_nent; i++ ) {
4630         that = LWPINDEX(lwpArray,i);
4631         if (that->pr_flags & PR_ASLWP) {
4632           aslwpcount++;
4633         }
4634       }
4635       if (aslwpcount == 0) isT2 = true;
4636       break;
4637     }
4638     lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize;
4639     FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal);  // retry.
4640   }
4641 
4642   FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal);
4643   ::close (lwpFile);
4644   if (ThreadPriorityVerbose) {
4645     if (isT2) tty->print_cr("We are running with a T2 libthread\n");
4646     else tty->print_cr("We are not running with a T2 libthread\n");
4647   }
4648   return isT2;
4649 }
4650 
4651 
4652 void os::Solaris::libthread_init() {
4653   address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators");
4654 
4655   // Determine if we are running with the new T2 libthread
4656   os::Solaris::set_T2_libthread(isT2_libthread());
4657 
4658   lwp_priocntl_init();
4659 
4660   // RTLD_DEFAULT was not defined on some early versions of 5.5.1
4661   if(func == NULL) {
4662     func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators");
4663     // Guarantee that this VM is running on an new enough OS (5.6 or
4664     // later) that it will have a new enough libthread.so.
4665     guarantee(func != NULL, "libthread.so is too old.");
4666   }
4667 
4668   // Initialize the new libthread getstate API wrappers
4669   func = resolve_symbol("thr_getstate");
4670   os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func));
4671 
4672   func = resolve_symbol("thr_setstate");
4673   os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func));
4674 
4675   func = resolve_symbol("thr_setmutator");
4676   os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func));
4677 
4678   func = resolve_symbol("thr_suspend_mutator");
4679   os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
4680 
4681   func = resolve_symbol("thr_continue_mutator");
4682   os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
4683 
4684   int size;
4685   void (*handler_info_func)(address *, int *);
4686   handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo"));
4687   handler_info_func(&handler_start, &size);
4688   handler_end = handler_start + size;
4689 }
4690 
4691 
4692 int_fnP_mutex_tP os::Solaris::_mutex_lock;
4693 int_fnP_mutex_tP os::Solaris::_mutex_trylock;
4694 int_fnP_mutex_tP os::Solaris::_mutex_unlock;
4695 int_fnP_mutex_tP_i_vP os::Solaris::_mutex_init;
4696 int_fnP_mutex_tP os::Solaris::_mutex_destroy;
4697 int os::Solaris::_mutex_scope = USYNC_THREAD;
4698 
4699 int_fnP_cond_tP_mutex_tP_timestruc_tP os::Solaris::_cond_timedwait;
4700 int_fnP_cond_tP_mutex_tP os::Solaris::_cond_wait;
4701 int_fnP_cond_tP os::Solaris::_cond_signal;
4702 int_fnP_cond_tP os::Solaris::_cond_broadcast;
4703 int_fnP_cond_tP_i_vP os::Solaris::_cond_init;


5566   }
5567 
5568   return(lwp_time);
5569 }
5570 
5571 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
5572   info_ptr->max_value = ALL_64_BITS;      // will not wrap in less than 64 bits
5573   info_ptr->may_skip_backward = false;    // elapsed time not wall time
5574   info_ptr->may_skip_forward = false;     // elapsed time not wall time
5575   info_ptr->kind = JVMTI_TIMER_USER_CPU;  // only user time is returned
5576 }
5577 
5578 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
5579   info_ptr->max_value = ALL_64_BITS;      // will not wrap in less than 64 bits
5580   info_ptr->may_skip_backward = false;    // elapsed time not wall time
5581   info_ptr->may_skip_forward = false;     // elapsed time not wall time
5582   info_ptr->kind = JVMTI_TIMER_USER_CPU;  // only user time is returned
5583 }
5584 
5585 bool os::is_thread_cpu_time_supported() {
5586   if ( os::Solaris::T2_libthread() || UseBoundThreads ) {
5587     return true;
5588   } else {
5589     return false;
5590   }
5591 }
5592 
5593 // System loadavg support.  Returns -1 if load average cannot be obtained.
5594 // Return the load average for our processor set if the primitive exists
5595 // (Solaris 9 and later).  Otherwise just return system wide loadavg.
5596 int os::loadavg(double loadavg[], int nelem) {
5597   if (pset_getloadavg_ptr != NULL) {
5598     return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem);
5599   } else {
5600     return ::getloadavg(loadavg, nelem);
5601   }
5602 }
5603 
5604 //---------------------------------------------------------------------------------
5605 
5606 bool os::find(address addr, outputStream* st) {
5607   Dl_info dlinfo;
5608   memset(&dlinfo, 0, sizeof(dlinfo));
5609   if (dladdr(addr, &dlinfo) != 0) {
5610     st->print(PTR_FORMAT ": ", addr);




 999 #endif
1000   if (_starting_thread == NULL) {
1001     _starting_thread = create_os_thread(thread, main_thread);
1002      if (_starting_thread == NULL) {
1003         return false;
1004      }
1005   }
1006 
1007   // The primodial thread is runnable from the start
1008   _starting_thread->set_state(RUNNABLE);
1009 
1010   thread->set_osthread(_starting_thread);
1011 
1012   // initialize signal mask for this thread
1013   // and save the caller's signal mask
1014   os::Solaris::hotspot_sigmask(thread);
1015 
1016   return true;
1017 }
1018 



1019 
1020 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
1021   // Allocate the OSThread object
1022   OSThread* osthread = new OSThread(NULL, NULL);
1023   if (osthread == NULL) {
1024     return false;
1025   }
1026 
1027   if ( ThreadPriorityVerbose ) {
1028     char *thrtyp;
1029     switch ( thr_type ) {
1030       case vm_thread:
1031         thrtyp = (char *)"vm";
1032         break;
1033       case cgc_thread:
1034         thrtyp = (char *)"cgc";
1035         break;
1036       case pgc_thread:
1037         thrtyp = (char *)"pgc";
1038         break;


1083 
1084   if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) {
1085     // We got lots of threads. Check if we still have some address space left.
1086     // Need to be at least 5Mb of unreserved address space. We do check by
1087     // trying to reserve some.
1088     const size_t VirtualMemoryBangSize = 20*K*K;
1089     char* mem = os::reserve_memory(VirtualMemoryBangSize);
1090     if (mem == NULL) {
1091       delete osthread;
1092       return false;
1093     } else {
1094       // Release the memory again
1095       os::release_memory(mem, VirtualMemoryBangSize);
1096     }
1097   }
1098 
1099   // Setup osthread because the child thread may need it.
1100   thread->set_osthread(osthread);
1101 
1102   // Create the Solaris thread



1103   thread_t tid = 0;
1104   long     flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED;






1105   int      status;
1106 




















































1107   // Mark that we don't have an lwp or thread id yet.
1108   // In case we attempt to set the priority before the thread starts.
1109   osthread->set_lwp_id(-1);
1110   osthread->set_thread_id(-1);
1111 
1112   status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
1113   if (status != 0) {
1114     if (PrintMiscellaneous && (Verbose || WizardMode)) {
1115       perror("os::create_thread");
1116     }
1117     thread->set_osthread(NULL);
1118     // Need to clean up stuff we've allocated so far
1119     delete osthread;
1120     return false;
1121   }
1122 
1123   Atomic::inc(&os::Solaris::_os_thread_count);
1124 
1125   // Store info on the Solaris thread into the OSThread
1126   osthread->set_thread_id(tid);
1127 
1128   // Remember that we created this thread so we can set priority on it
1129   osthread->set_vm_created();
1130 







1131   // Initial thread state is INITIALIZED, not SUSPENDED
1132   osthread->set_state(INITIALIZED);
1133 
1134   // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
1135   return true;
1136 }
1137 
1138 /* defined for >= Solaris 10. This allows builds on earlier versions
1139  *  of Solaris to take advantage of the newly reserved Solaris JVM signals
1140  *  With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
1141  *  and -XX:+UseAltSigs does nothing since these should have no conflict
1142  */
1143 #if !defined(SIGJVM1)
1144 #define SIGJVM1 39
1145 #define SIGJVM2 40
1146 #endif
1147 
1148 debug_only(static bool signal_sets_initialized = false);
1149 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
1150 int os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL;


1292 
1293     if (stack_size > jt->stack_size()) {
1294       NOT_PRODUCT(
1295         struct rlimit limits;
1296         getrlimit(RLIMIT_STACK, &limits);
1297         size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
1298         assert(size >= jt->stack_size(), "Stack size problem in main thread");
1299       )
1300       tty->print_cr(
1301         "Stack size of %d Kb exceeds current limit of %d Kb.\n"
1302         "(Stack sizes are rounded up to a multiple of the system page size.)\n"
1303         "See limit(1) to increase the stack size limit.",
1304         stack_size / K, jt->stack_size() / K);
1305       vm_exit(1);
1306     }
1307     assert(jt->stack_size() >= stack_size,
1308           "Attempt to map more stack than was allocated");
1309     jt->set_stack_size(stack_size);
1310   }
1311 
1312   // With the T2 libthread (T1 is no longer supported) threads are always bound
1313   // and we use stackbanging in all cases.


















1314   













1315   os::Solaris::init_thread_fpu_state();
1316   std::set_terminate(_handle_uncaught_cxx_exception);
1317 }
1318 
1319 
1320 
1321 // Free Solaris resources related to the OSThread
1322 void os::free_thread(OSThread* osthread) {
1323   assert(osthread != NULL, "os::free_thread but osthread not set");
1324 
1325 
1326   // We are told to free resources of the argument thread,
1327   // but we can only really operate on the current thread.
1328   // The main thread must take the VMThread down synchronously
1329   // before the main thread exits and frees up CodeHeap
1330   guarantee((Thread::current()->osthread() == osthread
1331      || (osthread == VMThread::vm_thread()->osthread())), "os::free_thread but not current thread");
1332   if (Thread::current()->osthread() == osthread) {
1333     // Restore caller's signal mask
1334     sigset_t sigmask = osthread->caller_sigmask();


2020 
2021   os::Solaris::print_distro_info(st);
2022 
2023   os::Posix::print_uname_info(st);
2024 
2025   os::Solaris::print_libversion_info(st);
2026 
2027   os::Posix::print_rlimit_info(st);
2028 
2029   os::Posix::print_load_average(st);
2030 }
2031 
2032 void os::Solaris::print_distro_info(outputStream* st) {
2033   if (!_print_ascii_file("/etc/release", st)) {
2034       st->print("Solaris");
2035     }
2036     st->cr();
2037 }
2038 
2039 void os::Solaris::print_libversion_info(outputStream* st) {

2040   st->print("  (T2 libthread)");




2041   st->cr();
2042 }
2043 
2044 static bool check_addr0(outputStream* st) {
2045   jboolean status = false;
2046   int fd = ::open("/proc/self/map",O_RDONLY);
2047   if (fd >= 0) {
2048     prmap_t p;
2049     while(::read(fd, &p, sizeof(p)) > 0) {
2050       if (p.pr_vaddr == 0x0) {
2051         st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname);
2052         st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname);
2053         st->print("Access:");
2054         st->print("%s",(p.pr_mflags & MA_READ)  ? "r" : "-");
2055         st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-");
2056         st->print("%s",(p.pr_mflags & MA_EXEC)  ? "x" : "-");
2057         st->cr();
2058         status = true;
2059       }
2060     }


3246   else {
3247     return false;
3248   }
3249 }
3250 
3251 // Caveat: Solaris os::yield() causes a thread-state transition whereas
3252 // the linux and win32 implementations do not.  This should be checked.
3253 
3254 void os::yield() {
3255   // Yields to all threads with same or greater priority
3256   os::sleep(Thread::current(), 0, false);
3257 }
3258 
3259 // Note that yield semantics are defined by the scheduling class to which
3260 // the thread currently belongs.  Typically, yield will _not yield to
3261 // other equal or higher priority threads that reside on the dispatch queues
3262 // of other CPUs.
3263 
3264 os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; }
3265 
3266 void os::yield_all() {










3267   // Yields to all threads, including threads with lower priorities

3268   os::sleep(Thread::current(), 1, false);














3269 }
3270 






3271 // Interface for setting lwp priorities.  If we are using T2 libthread,
3272 // which forces the use of BoundThreads or we manually set UseBoundThreads,
3273 // all of our threads will be assigned to real lwp's.  Using the thr_setprio
3274 // function is meaningless in this mode so we must adjust the real lwp's priority
3275 // The routines below implement the getting and setting of lwp priorities.
3276 //
3277 // Note: T2 is now the only supported libthread. UseBoundThreads flag is
3278 //       being deprecated and all threads are now BoundThreads
3279 //
3280 // Note: There are three priority scales used on Solaris.  Java priotities
3281 //       which range from 1 to 10, libthread "thr_setprio" scale which range
3282 //       from 0 to 127, and the current scheduling class of the process we
3283 //       are running in.  This is typically from -60 to +60.
3284 //       The setting of the lwp priorities in done after a call to thr_setprio
3285 //       so Java priorities are mapped to libthread priorities and we map from
3286 //       the latter to lwp priorities.  We don't keep priorities stored in
3287 //       Java priorities since some of our worker threads want to set priorities
3288 //       higher than all Java threads.
3289 //
3290 // For related information:
3291 // (1)  man -s 2 priocntl
3292 // (2)  man -s 4 priocntl
3293 // (3)  man dispadmin
3294 // =    librt.so
3295 // =    libthread/common/rtsched.c - thrp_setlwpprio().
3296 // =    ps -cL <pid> ... to validate priority.
3297 // =    sched_get_priority_min and _max
3298 //              pthread_create
3299 //              sched_setparam


3332 static bool priocntl_enable = false;
3333 
3334 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
3335 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
3336 
3337 
3338 // lwp_priocntl_init
3339 //
3340 // Try to determine the priority scale for our process.
3341 //
3342 // Return errno or 0 if OK.
3343 //
3344 static int lwp_priocntl_init () {
3345   int rslt;
3346   pcinfo_t ClassInfo;
3347   pcparms_t ParmInfo;
3348   int i;
3349 
3350   if (!UseThreadPriorities) return 0;
3351 


3352   // If ThreadPriorityPolicy is 1, switch tables
3353   if (ThreadPriorityPolicy == 1) {
3354     for (i = 0 ; i < CriticalPriority+1; i++)
3355       os::java_to_os_priority[i] = prio_policy1[i];
3356   }
3357   if (UseCriticalJavaThreadPriority) {
3358     // MaxPriority always maps to the FX scheduling class and criticalPrio.
3359     // See set_native_priority() and set_lwp_class_and_priority().
3360     // Save original MaxPriority mapping in case attempt to
3361     // use critical priority fails.
3362     java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
3363     // Set negative to distinguish from other priorities
3364     os::java_to_os_priority[MaxPriority] = -criticalPrio;
3365   }








3366 
3367   // Get IDs for a set of well-known scheduling classes.
3368   // TODO-FIXME: GETCLINFO returns the current # of classes in the
3369   // the system.  We should have a loop that iterates over the
3370   // classID values, which are known to be "small" integers.
3371 
3372   strcpy(ClassInfo.pc_clname, "TS");
3373   ClassInfo.pc_cid = -1;
3374   rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3375   if (rslt < 0) return errno;
3376   assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3377   tsLimits.schedPolicy = ClassInfo.pc_cid;
3378   tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3379   tsLimits.minPrio = -tsLimits.maxPrio;
3380 
3381   strcpy(ClassInfo.pc_clname, "IA");
3382   ClassInfo.pc_cid = -1;
3383   rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3384   if (rslt < 0) return errno;
3385   assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");


3468 #define FXPRI(x)        ((fxparms_t *)((x).pc_clparms))
3469 
3470 
3471 // scale_to_lwp_priority
3472 //
3473 // Convert from the libthread "thr_setprio" scale to our current
3474 // lwp scheduling class scale.
3475 //
3476 static
3477 int     scale_to_lwp_priority (int rMin, int rMax, int x)
3478 {
3479   int v;
3480 
3481   if (x == 127) return rMax;            // avoid round-down
3482     v = (((x*(rMax-rMin)))/128)+rMin;
3483   return v;
3484 }
3485 
3486 
3487 // set_lwp_class_and_priority




3488 int set_lwp_class_and_priority(int ThreadID, int lwpid,
3489                                int newPrio, int new_class, bool scale) {
3490   int rslt;
3491   int Actual, Expected, prv;
3492   pcparms_t ParmInfo;                   // for GET-SET
3493 #ifdef ASSERT
3494   pcparms_t ReadBack;                   // for readback
3495 #endif
3496 
3497   // Set priority via PC_GETPARMS, update, PC_SETPARMS
3498   // Query current values.
3499   // TODO: accelerate this by eliminating the PC_GETPARMS call.
3500   // Cache "pcparms_t" in global ParmCache.
3501   // TODO: elide set-to-same-value
3502 
3503   // If something went wrong on init, don't change priorities.
3504   if ( !priocntl_enable ) {
3505     if (ThreadPriorityVerbose)
3506       tty->print_cr("Trying to set priority but init failed, ignoring");
3507     return EINVAL;


3693   // Save requested priority in case the thread hasn't been started
3694   osthread->set_native_priority(newpri);
3695 
3696   // Check for critical priority request
3697   bool fxcritical = false;
3698   if (newpri == -criticalPrio) {
3699     fxcritical = true;
3700     newpri = criticalPrio;
3701   }
3702 
3703   assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
3704   if (!UseThreadPriorities) return OS_OK;
3705 
3706   int status = 0;
3707 
3708   if (!fxcritical) {
3709     // Use thr_setprio only if we have a priority that thr_setprio understands
3710     status = thr_setprio(thread->osthread()->thread_id(), newpri);
3711   }
3712 


3713   int lwp_status =
3714           set_lwp_class_and_priority(osthread->thread_id(),
3715           osthread->lwp_id(),
3716           newpri,
3717           fxcritical ? fxLimits.schedPolicy : myClass,
3718           !fxcritical);
3719   if (lwp_status != 0 && fxcritical) {
3720     // Try again, this time without changing the scheduling class
3721     newpri = java_MaxPriority_to_os_priority;
3722     lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
3723             osthread->lwp_id(),
3724             newpri, myClass, false);
3725   }
3726   status |= lwp_status;

3727   return (status == 0) ? OS_OK : OS_ERR;
3728 }
3729 
3730 
3731 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
3732   int p;
3733   if ( !UseThreadPriorities ) {
3734     *priority_ptr = NormalPriority;
3735     return OS_OK;
3736   }
3737   int status = thr_getprio(thread->osthread()->thread_id(), &p);
3738   if (status != 0) {
3739     return OS_ERR;
3740   }
3741   *priority_ptr = p;
3742   return OS_OK;
3743 }
3744 
3745 
3746 // Hint to the underlying OS that a task switch would not be good.


4373   "SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT",
4374   "SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU",
4375   "SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW",
4376   "SIGCANCEL", "SIGLOST"
4377 };
4378 
4379 const char* os::exception_name(int exception_code, char* buf, size_t size) {
4380   if (0 < exception_code && exception_code <= SIGRTMAX) {
4381     // signal
4382     if (exception_code < sizeof(signames)/sizeof(const char*)) {
4383        jio_snprintf(buf, size, "%s", signames[exception_code]);
4384     } else {
4385        jio_snprintf(buf, size, "SIG%d", exception_code);
4386     }
4387     return buf;
4388   } else {
4389     return NULL;
4390   }
4391 }
4392 







4393 // (Static) wrapper for getisax(2) call.
4394 os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
4395 
4396 // (Static) wrappers for the liblgrp API
4397 os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
4398 os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
4399 os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini;
4400 os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root;
4401 os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children;
4402 os::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources;
4403 os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps;
4404 os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
4405 os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
4406 
4407 // (Static) wrapper for meminfo() call.
4408 os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
4409 
4410 static address resolve_symbol_lazy(const char* name) {
4411   address addr = (address) dlsym(RTLD_DEFAULT, name);
4412   if(addr == NULL) {
4413     // RTLD_DEFAULT was not defined on some early versions of 2.5.1
4414     addr = (address) dlsym(RTLD_NEXT, name);
4415   }
4416   return addr;
4417 }
4418 
4419 static address resolve_symbol(const char* name) {
4420   address addr = resolve_symbol_lazy(name);
4421   if(addr == NULL) {
4422     fatal(dlerror());
4423   }
4424   return addr;
4425 }
4426 


































































4427 void os::Solaris::libthread_init() {
4428   address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators");
4429 



4430   lwp_priocntl_init();
4431 
4432   // RTLD_DEFAULT was not defined on some early versions of 5.5.1
4433   if(func == NULL) {
4434     func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators");
4435     // Guarantee that this VM is running on an new enough OS (5.6 or
4436     // later) that it will have a new enough libthread.so.
4437     guarantee(func != NULL, "libthread.so is too old.");
4438   }
4439 
















4440   int size;
4441   void (*handler_info_func)(address *, int *);
4442   handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo"));
4443   handler_info_func(&handler_start, &size);
4444   handler_end = handler_start + size;
4445 }
4446 
4447 
4448 int_fnP_mutex_tP os::Solaris::_mutex_lock;
4449 int_fnP_mutex_tP os::Solaris::_mutex_trylock;
4450 int_fnP_mutex_tP os::Solaris::_mutex_unlock;
4451 int_fnP_mutex_tP_i_vP os::Solaris::_mutex_init;
4452 int_fnP_mutex_tP os::Solaris::_mutex_destroy;
4453 int os::Solaris::_mutex_scope = USYNC_THREAD;
4454 
4455 int_fnP_cond_tP_mutex_tP_timestruc_tP os::Solaris::_cond_timedwait;
4456 int_fnP_cond_tP_mutex_tP os::Solaris::_cond_wait;
4457 int_fnP_cond_tP os::Solaris::_cond_signal;
4458 int_fnP_cond_tP os::Solaris::_cond_broadcast;
4459 int_fnP_cond_tP_i_vP os::Solaris::_cond_init;


5322   }
5323 
5324   return(lwp_time);
5325 }
5326 
5327 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
5328   info_ptr->max_value = ALL_64_BITS;      // will not wrap in less than 64 bits
5329   info_ptr->may_skip_backward = false;    // elapsed time not wall time
5330   info_ptr->may_skip_forward = false;     // elapsed time not wall time
5331   info_ptr->kind = JVMTI_TIMER_USER_CPU;  // only user time is returned
5332 }
5333 
5334 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
5335   info_ptr->max_value = ALL_64_BITS;      // will not wrap in less than 64 bits
5336   info_ptr->may_skip_backward = false;    // elapsed time not wall time
5337   info_ptr->may_skip_forward = false;     // elapsed time not wall time
5338   info_ptr->kind = JVMTI_TIMER_USER_CPU;  // only user time is returned
5339 }
5340 
5341 bool os::is_thread_cpu_time_supported() {

5342   return true;



5343 }
5344 
5345 // System loadavg support.  Returns -1 if load average cannot be obtained.
5346 // Return the load average for our processor set if the primitive exists
5347 // (Solaris 9 and later).  Otherwise just return system wide loadavg.
5348 int os::loadavg(double loadavg[], int nelem) {
5349   if (pset_getloadavg_ptr != NULL) {
5350     return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem);
5351   } else {
5352     return ::getloadavg(loadavg, nelem);
5353   }
5354 }
5355 
5356 //---------------------------------------------------------------------------------
5357 
5358 bool os::find(address addr, outputStream* st) {
5359   Dl_info dlinfo;
5360   memset(&dlinfo, 0, sizeof(dlinfo));
5361   if (dladdr(addr, &dlinfo) != 0) {
5362     st->print(PTR_FORMAT ": ", addr);