src/os/solaris/vm/os_solaris.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-rt-fx60 Sdiff src/os/solaris/vm

src/os/solaris/vm/os_solaris.cpp

Print this page




  97 # include <sys/mman.h>
  98 # include <sys/processor.h>
  99 # include <sys/procset.h>
 100 # include <sys/pset.h>
 101 # include <sys/resource.h>
 102 # include <sys/shm.h>
 103 # include <sys/socket.h>
 104 # include <sys/stat.h>
 105 # include <sys/systeminfo.h>
 106 # include <sys/time.h>
 107 # include <sys/times.h>
 108 # include <sys/types.h>
 109 # include <sys/wait.h>
 110 # include <sys/utsname.h>
 111 # include <thread.h>
 112 # include <unistd.h>
 113 # include <sys/priocntl.h>
 114 # include <sys/rtpriocntl.h>
 115 # include <sys/tspriocntl.h>
 116 # include <sys/iapriocntl.h>

 117 # include <sys/loadavg.h>
 118 # include <string.h>
 119 # include <stdio.h>
 120 
 121 # define _STRUCTURED_PROC 1  //  this gets us the new structured proc interfaces of 5.6 & later
 122 # include <sys/procfs.h>     //  see comment in <sys/procfs.h>
 123 
 124 #define MAX_PATH (2 * K)
 125 
 126 // for timer info max values which include all bits
 127 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 128 
 129 #ifdef _GNU_SOURCE
 130 // See bug #6514594
 131 extern "C" int madvise(caddr_t, size_t, int);
 132 extern "C"  int memcntl(caddr_t addr, size_t len, int cmd, caddr_t  arg,
 133      int attr, int mask);
 134 #endif //_GNU_SOURCE
 135 
 136 /*


1031   // processors with hyperthreading technology.
1032   static int counter = 0;
1033   int pid = os::current_process_id();
1034   alloca(((pid ^ counter++) & 7) * 128);
1035 
1036   int prio;
1037   Thread* thread = (Thread*)thread_addr;
1038   OSThread* osthr = thread->osthread();
1039 
1040   osthr->set_lwp_id( _lwp_self() );  // Store lwp in case we are bound
1041   thread->_schedctl = (void *) schedctl_init () ;
1042 
1043   if (UseNUMA) {
1044     int lgrp_id = os::numa_get_group_id();
1045     if (lgrp_id != -1) {
1046       thread->set_lgrp_id(lgrp_id);
1047     }
1048   }
1049 
1050   // If the creator called set priority before we started,
1051   // we need to call set priority now that we have an lwp.
1052   // Get the priority from libthread and set the priority
1053   // for the new Solaris lwp.






1054   if ( osthr->thread_id() != -1 ) {
1055     if ( UseThreadPriorities ) {
1056       thr_getprio(osthr->thread_id(), &prio);
1057       if (ThreadPriorityVerbose) {
1058         tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT ", setting priority: %d\n",
1059                       osthr->thread_id(), osthr->lwp_id(), prio );

1060       }
1061       os::set_native_priority(thread, prio);
1062     }
1063   } else if (ThreadPriorityVerbose) {
1064     warning("Can't set priority in _start routine, thread id hasn't been set\n");
1065   }
1066 
1067   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
1068 
1069   // initialize signal mask for this thread
1070   os::Solaris::hotspot_sigmask(thread);
1071 
1072   thread->run();
1073 
1074   // One less thread is executing
1075   // When the VMThread gets here, the main thread may have already exited
1076   // which frees the CodeHeap containing the Atomic::dec code
1077   if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
1078     Atomic::dec(&os::Solaris::_os_thread_count);
1079   }


1336 
1337   status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
1338   if (status != 0) {
1339     if (PrintMiscellaneous && (Verbose || WizardMode)) {
1340       perror("os::create_thread");
1341     }
1342     thread->set_osthread(NULL);
1343     // Need to clean up stuff we've allocated so far
1344     delete osthread;
1345     return false;
1346   }
1347 
1348   Atomic::inc(&os::Solaris::_os_thread_count);
1349 
1350   // Store info on the Solaris thread into the OSThread
1351   osthread->set_thread_id(tid);
1352 
1353   // Remember that we created this thread so we can set priority on it
1354   osthread->set_vm_created();
1355 
1356   // Set the default thread priority otherwise use NormalPriority
1357 
1358   if ( UseThreadPriorities ) {
1359      thr_setprio(tid, (DefaultThreadPriority == -1) ?
1360                         java_to_os_priority[NormPriority] :
1361                         DefaultThreadPriority);
1362   }
1363 
1364   // Initial thread state is INITIALIZED, not SUSPENDED
1365   osthread->set_state(INITIALIZED);
1366 
1367   // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
1368   return true;
1369 }
1370 
1371 /* defined for >= Solaris 10. This allows builds on earlier versions
1372  *  of Solaris to take advantage of the newly reserved Solaris JVM signals
1373  *  With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
1374  *  and -XX:+UseAltSigs does nothing since these should have no conflict
1375  */
1376 #if !defined(SIGJVM1)
1377 #define SIGJVM1 39
1378 #define SIGJVM2 40
1379 #endif
1380 
1381 debug_only(static bool signal_sets_initialized = false);
1382 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;


3711 // +    We assume that all threads in the process belong to the same
3712 //              scheduling class.   IE. an homogenous process.
3713 // +    Must be root or in IA group to change change "interactive" attribute.
3714 //              Priocntl() will fail silently.  The only indication of failure is when
3715 //              we read-back the value and notice that it hasn't changed.
3716 // +    Interactive threads enter the runq at the head, non-interactive at the tail.
3717 // +    For RT, change timeslice as well.  Invariant:
3718 //              constant "priority integral"
3719 //              Konst == TimeSlice * (60-Priority)
3720 //              Given a priority, compute appropriate timeslice.
3721 // +    Higher numerical values have higher priority.
3722 
3723 // sched class attributes
3724 typedef struct {
3725         int   schedPolicy;              // classID
3726         int   maxPrio;
3727         int   minPrio;
3728 } SchedInfo;
3729 
3730 
3731 static SchedInfo tsLimits, iaLimits, rtLimits;
3732 
3733 #ifdef ASSERT
3734 static int  ReadBackValidate = 1;
3735 #endif
3736 static int  myClass     = 0;
3737 static int  myMin       = 0;
3738 static int  myMax       = 0;
3739 static int  myCur       = 0;
3740 static bool priocntl_enable = false;
3741 


3742 
3743 // Call the version of priocntl suitable for all supported versions
3744 // of Solaris. We need to call through this wrapper so that we can
3745 // build on Solaris 9 and run on Solaris 8, 9 and 10.
3746 //
3747 // This code should be removed if we ever stop supporting Solaris 8
3748 // and earlier releases.
3749 
3750 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3751 typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3752 static priocntl_type priocntl_ptr = priocntl_stub;
3753 
3754 // Stub to set the value of the real pointer, and then call the real
3755 // function.
3756 
3757 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) {
3758   // Try Solaris 8- name only.
3759   priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl");
3760   guarantee(tmp != NULL, "priocntl function not found.");
3761   priocntl_ptr = tmp;


3769 //
3770 // Return errno or 0 if OK.
3771 //
3772 static
3773 int     lwp_priocntl_init ()
3774 {
3775   int rslt;
3776   pcinfo_t ClassInfo;
3777   pcparms_t ParmInfo;
3778   int i;
3779 
3780   if (!UseThreadPriorities) return 0;
3781 
3782   // We are using Bound threads, we need to determine our priority ranges
3783   if (os::Solaris::T2_libthread() || UseBoundThreads) {
3784     // If ThreadPriorityPolicy is 1, switch tables
3785     if (ThreadPriorityPolicy == 1) {
3786       for (i = 0 ; i < MaxPriority+1; i++)
3787         os::java_to_os_priority[i] = prio_policy1[i];
3788     }








3789   }

3790   // Not using Bound Threads, set to ThreadPolicy 1
3791   else {
3792     for ( i = 0 ; i < MaxPriority+1; i++ ) {
3793       os::java_to_os_priority[i] = prio_policy1[i];
3794     }
3795     return 0;
3796   }
3797 
3798 
3799   // Get IDs for a set of well-known scheduling classes.
3800   // TODO-FIXME: GETCLINFO returns the current # of classes in the
3801   // the system.  We should have a loop that iterates over the
3802   // classID values, which are known to be "small" integers.
3803 
3804   strcpy(ClassInfo.pc_clname, "TS");
3805   ClassInfo.pc_cid = -1;
3806   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3807   if (rslt < 0) return errno;
3808   assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3809   tsLimits.schedPolicy = ClassInfo.pc_cid;
3810   tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3811   tsLimits.minPrio = -tsLimits.maxPrio;
3812 
3813   strcpy(ClassInfo.pc_clname, "IA");
3814   ClassInfo.pc_cid = -1;
3815   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3816   if (rslt < 0) return errno;
3817   assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
3818   iaLimits.schedPolicy = ClassInfo.pc_cid;
3819   iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
3820   iaLimits.minPrio = -iaLimits.maxPrio;
3821 
3822   strcpy(ClassInfo.pc_clname, "RT");
3823   ClassInfo.pc_cid = -1;
3824   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3825   if (rslt < 0) return errno;
3826   assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
3827   rtLimits.schedPolicy = ClassInfo.pc_cid;
3828   rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
3829   rtLimits.minPrio = 0;
3830 








3831 
3832   // Query our "current" scheduling class.
3833   // This will normally be IA,TS or, rarely, RT.
3834   memset (&ParmInfo, 0, sizeof(ParmInfo));
3835   ParmInfo.pc_cid = PC_CLNULL;
3836   rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo );
3837   if ( rslt < 0 ) return errno;
3838   myClass = ParmInfo.pc_cid;
3839 
3840   // We now know our scheduling classId, get specific information
3841   // the class.
3842   ClassInfo.pc_cid = myClass;
3843   ClassInfo.pc_clname[0] = 0;
3844   rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo );
3845   if ( rslt < 0 ) return errno;
3846 
3847   if (ThreadPriorityVerbose)
3848     tty->print_cr ("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);

3849 
3850   memset(&ParmInfo, 0, sizeof(pcparms_t));
3851   ParmInfo.pc_cid = PC_CLNULL;
3852   rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3853   if (rslt < 0) return errno;
3854 
3855   if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
3856     myMin = rtLimits.minPrio;
3857     myMax = rtLimits.maxPrio;
3858   } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
3859     iaparms_t *iaInfo  = (iaparms_t*)ParmInfo.pc_clparms;
3860     myMin = iaLimits.minPrio;
3861     myMax = iaLimits.maxPrio;
3862     myMax = MIN2(myMax, (int)iaInfo->ia_uprilim);       // clamp - restrict
3863   } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
3864     tsparms_t *tsInfo  = (tsparms_t*)ParmInfo.pc_clparms;
3865     myMin = tsLimits.minPrio;
3866     myMax = tsLimits.maxPrio;
3867     myMax = MIN2(myMax, (int)tsInfo->ts_uprilim);       // clamp - restrict





3868   } else {
3869     // No clue - punt
3870     if (ThreadPriorityVerbose)
3871       tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname);
3872     return EINVAL;      // no clue, punt
3873   }
3874 
3875   if (ThreadPriorityVerbose)
3876         tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);

3877 
3878   priocntl_enable = true;  // Enable changing priorities
3879   return 0;
3880 }
3881 
3882 #define IAPRI(x)        ((iaparms_t *)((x).pc_clparms))
3883 #define RTPRI(x)        ((rtparms_t *)((x).pc_clparms))
3884 #define TSPRI(x)        ((tsparms_t *)((x).pc_clparms))

3885 
3886 
3887 // scale_to_lwp_priority
3888 //
3889 // Convert from the libthread "thr_setprio" scale to our current
3890 // lwp scheduling class scale.
3891 //
3892 static
3893 int     scale_to_lwp_priority (int rMin, int rMax, int x)
3894 {
3895   int v;
3896 
3897   if (x == 127) return rMax;            // avoid round-down
3898     v = (((x*(rMax-rMin)))/128)+rMin;
3899   return v;
3900 }
3901 
3902 
3903 // set_lwp_priority
3904 //
3905 // Set the priority of the lwp.  This call should only be made
3906 // when using bound threads (T2 threads are bound by default).
3907 //
3908 int     set_lwp_priority (int ThreadID, int lwpid, int newPrio )
3909 {
3910   int rslt;
3911   int Actual, Expected, prv;
3912   pcparms_t ParmInfo;                   // for GET-SET
3913 #ifdef ASSERT
3914   pcparms_t ReadBack;                   // for readback
3915 #endif
3916 
3917   // Set priority via PC_GETPARMS, update, PC_SETPARMS
3918   // Query current values.
3919   // TODO: accelerate this by eliminating the PC_GETPARMS call.
3920   // Cache "pcparms_t" in global ParmCache.
3921   // TODO: elide set-to-same-value
3922 
3923   // If something went wrong on init, don't change priorities.
3924   if ( !priocntl_enable ) {
3925     if (ThreadPriorityVerbose)
3926       tty->print_cr("Trying to set priority but init failed, ignoring");
3927     return EINVAL;
3928   }
3929 
3930 
3931   // If lwp hasn't started yet, just return
3932   // the _start routine will call us again.
3933   if ( lwpid <= 0 ) {
3934     if (ThreadPriorityVerbose) {
3935       tty->print_cr ("deferring the set_lwp_priority of thread " INTPTR_FORMAT " to %d, lwpid not set",

3936                      ThreadID, newPrio);
3937     }
3938     return 0;
3939   }
3940 
3941   if (ThreadPriorityVerbose) {
3942     tty->print_cr ("set_lwp_priority(" INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",

3943                    ThreadID, lwpid, newPrio);
3944   }
3945 
3946   memset(&ParmInfo, 0, sizeof(pcparms_t));
3947   ParmInfo.pc_cid = PC_CLNULL;
3948   rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
3949   if (rslt < 0) return errno;
3950 
3951   if (ParmInfo.pc_cid == rtLimits.schedPolicy) {



3952     rtparms_t *rtInfo  = (rtparms_t*)ParmInfo.pc_clparms;
3953     rtInfo->rt_pri     = scale_to_lwp_priority (rtLimits.minPrio, rtLimits.maxPrio, newPrio);

3954     rtInfo->rt_tqsecs  = RT_NOCHANGE;
3955     rtInfo->rt_tqnsecs = RT_NOCHANGE;
3956     if (ThreadPriorityVerbose) {
3957       tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
3958     }
3959   } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
3960     iaparms_t *iaInfo  = (iaparms_t*)ParmInfo.pc_clparms;
3961     int maxClamped     = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
3962     iaInfo->ia_upri    = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
3963     iaInfo->ia_uprilim = IA_NOCHANGE;

3964     iaInfo->ia_mode    = IA_NOCHANGE;

3965     if (ThreadPriorityVerbose) {
3966       tty->print_cr ("IA: [%d...%d] %d->%d\n",
3967                iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
3968     }
3969   } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
3970     tsparms_t *tsInfo  = (tsparms_t*)ParmInfo.pc_clparms;
3971     int maxClamped     = MIN2(tsLimits.maxPrio, (int)tsInfo->ts_uprilim);
3972     prv                = tsInfo->ts_upri;
3973     tsInfo->ts_upri    = scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio);
3974     tsInfo->ts_uprilim = IA_NOCHANGE;
3975     if (ThreadPriorityVerbose) {
3976       tty->print_cr ("TS: %d [%d...%d] %d->%d\n",
3977                prv, tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
3978     }
3979     if (prv == tsInfo->ts_upri) return 0;











3980   } else {
3981     if ( ThreadPriorityVerbose ) {
3982       tty->print_cr ("Unknown scheduling class\n");
3983     }
3984       return EINVAL;    // no clue, punt
3985   }
3986 
3987   rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
3988   if (ThreadPriorityVerbose && rslt) {
3989     tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
3990   }
3991   if (rslt < 0) return errno;
3992 
3993 #ifdef ASSERT
3994   // Sanity check: read back what we just attempted to set.
3995   // In theory it could have changed in the interim ...
3996   //
3997   // The priocntl system call is tricky.
3998   // Sometimes it'll validate the priority value argument and
3999   // return EINVAL if unhappy.  At other times it fails silently.
4000   // Readbacks are prudent.
4001 
4002   if (!ReadBackValidate) return 0;
4003 
4004   memset(&ReadBack, 0, sizeof(pcparms_t));
4005   ReadBack.pc_cid = PC_CLNULL;
4006   rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
4007   assert(rslt >= 0, "priocntl failed");
4008   Actual = Expected = 0xBAD;
4009   assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
4010   if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
4011     Actual   = RTPRI(ReadBack)->rt_pri;
4012     Expected = RTPRI(ParmInfo)->rt_pri;
4013   } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
4014     Actual   = IAPRI(ReadBack)->ia_upri;
4015     Expected = IAPRI(ParmInfo)->ia_upri;
4016   } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
4017     Actual   = TSPRI(ReadBack)->ts_upri;
4018     Expected = TSPRI(ParmInfo)->ts_upri;



4019   } else {
4020     if ( ThreadPriorityVerbose ) {
4021       tty->print_cr("set_lwp_priority: unexpected class in readback: %d\n", ParmInfo.pc_cid);

4022     }
4023   }
4024 
4025   if (Actual != Expected) {
4026     if ( ThreadPriorityVerbose ) {
4027       tty->print_cr ("set_lwp_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
4028              lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
4029     }
4030   }
4031 #endif
4032 
4033   return 0;
4034 }
4035 
4036 
4037 
4038 // Solaris only gives access to 128 real priorities at a time,
4039 // so we expand Java's ten to fill this range.  This would be better
4040 // if we dynamically adjusted relative priorities.
4041 //
4042 // The ThreadPriorityPolicy option allows us to select 2 different
4043 // priority scales.
4044 //
4045 // ThreadPriorityPolicy=0
4046 // Since the Solaris' default priority is MaximumPriority, we do not
4047 // set a priority lower than Max unless a priority lower than
4048 // NormPriority is requested.
4049 //
4050 // ThreadPriorityPolicy=1
4051 // This mode causes the priority table to get filled with
4052 // linear values.  NormPriority get's mapped to 50% of the
4053 // Maximum priority an so on.  This will cause VM threads
4054 // to get unfair treatment against other Solaris processes
4055 // which do not explicitly alter their thread priorities.
4056 //
4057 
4058 
4059 int os::java_to_os_priority[MaxPriority + 1] = {
4060   -99999,         // 0 Entry should never be used
4061 
4062   0,              // 1 MinPriority
4063   32,             // 2
4064   64,             // 3
4065 
4066   96,             // 4
4067   127,            // 5 NormPriority
4068   127,            // 6
4069 
4070   127,            // 7
4071   127,            // 8
4072   127,            // 9 NearMaxPriority
4073 
4074   127             // 10 MaxPriority


4075 };
4076 
4077 
4078 OSReturn os::set_native_priority(Thread* thread, int newpri) {












4079   assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
4080   if ( !UseThreadPriorities ) return OS_OK;
4081   int status = thr_setprio(thread->osthread()->thread_id(), newpri);
4082   if ( os::Solaris::T2_libthread() || (UseBoundThreads && thread->osthread()->is_vm_created()) )
4083     status |= (set_lwp_priority (thread->osthread()->thread_id(),
4084                     thread->osthread()->lwp_id(), newpri ));





















4085   return (status == 0) ? OS_OK : OS_ERR;
4086 }
4087 
4088 
4089 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
4090   int p;
4091   if ( !UseThreadPriorities ) {
4092     *priority_ptr = NormalPriority;
4093     return OS_OK;
4094   }
4095   int status = thr_getprio(thread->osthread()->thread_id(), &p);
4096   if (status != 0) {
4097     return OS_ERR;
4098   }
4099   *priority_ptr = p;
4100   return OS_OK;
4101 }
4102 
4103 
4104 // Hint to the underlying OS that a task switch would not be good.




  97 # include <sys/mman.h>
  98 # include <sys/processor.h>
  99 # include <sys/procset.h>
 100 # include <sys/pset.h>
 101 # include <sys/resource.h>
 102 # include <sys/shm.h>
 103 # include <sys/socket.h>
 104 # include <sys/stat.h>
 105 # include <sys/systeminfo.h>
 106 # include <sys/time.h>
 107 # include <sys/times.h>
 108 # include <sys/types.h>
 109 # include <sys/wait.h>
 110 # include <sys/utsname.h>
 111 # include <thread.h>
 112 # include <unistd.h>
 113 # include <sys/priocntl.h>
 114 # include <sys/rtpriocntl.h>
 115 # include <sys/tspriocntl.h>
 116 # include <sys/iapriocntl.h>
 117 # include <sys/fxpriocntl.h>
 118 # include <sys/loadavg.h>
 119 # include <string.h>
 120 # include <stdio.h>
 121 
 122 # define _STRUCTURED_PROC 1  //  this gets us the new structured proc interfaces of 5.6 & later
 123 # include <sys/procfs.h>     //  see comment in <sys/procfs.h>
 124 
 125 #define MAX_PATH (2 * K)
 126 
 127 // for timer info max values which include all bits
 128 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 129 
 130 #ifdef _GNU_SOURCE
 131 // See bug #6514594
 132 extern "C" int madvise(caddr_t, size_t, int);
 133 extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg,
 134                        int attr, int mask);
 135 #endif //_GNU_SOURCE
 136 
 137 /*


1032   // processors with hyperthreading technology.
1033   static int counter = 0;
1034   int pid = os::current_process_id();
1035   alloca(((pid ^ counter++) & 7) * 128);
1036 
1037   int prio;
1038   Thread* thread = (Thread*)thread_addr;
1039   OSThread* osthr = thread->osthread();
1040 
1041   osthr->set_lwp_id( _lwp_self() );  // Store lwp in case we are bound
1042   thread->_schedctl = (void *) schedctl_init () ;
1043 
1044   if (UseNUMA) {
1045     int lgrp_id = os::numa_get_group_id();
1046     if (lgrp_id != -1) {
1047       thread->set_lgrp_id(lgrp_id);
1048     }
1049   }
1050 
1051   // If the creator called set priority before we started,
1052   // we need to call set_native_priority now that we have an lwp.
1053   // We used to get the priority from thr_getprio (we called
1054   // thr_setprio way back in create_thread) and pass it to
1055   // set_native_priority, but Solaris scales the priority
1056   // in java_to_os_priority, so when we read it back here,
1057   // we pass trash to set_native_priority instead of what's
1058   // in java_to_os_priority. So we save the native priority
1059   // in the osThread and recall it here.
1060 
1061   if ( osthr->thread_id() != -1 ) {
1062     if ( UseThreadPriorities ) {
1063       int prio = osthr->native_priority();
1064       if (ThreadPriorityVerbose) {
1065         tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is "
1066                       INTPTR_FORMAT ", setting priority: %d\n",
1067                       osthr->thread_id(), osthr->lwp_id(), prio);
1068       }
1069       os::set_native_priority(thread, prio);
1070     }
1071   } else if (ThreadPriorityVerbose) {
1072     warning("Can't set priority in _start routine, thread id hasn't been set\n");
1073   }
1074 
1075   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
1076 
1077   // initialize signal mask for this thread
1078   os::Solaris::hotspot_sigmask(thread);
1079 
1080   thread->run();
1081 
1082   // One less thread is executing
1083   // When the VMThread gets here, the main thread may have already exited
1084   // which frees the CodeHeap containing the Atomic::dec code
1085   if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
1086     Atomic::dec(&os::Solaris::_os_thread_count);
1087   }


1344 
1345   status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
1346   if (status != 0) {
1347     if (PrintMiscellaneous && (Verbose || WizardMode)) {
1348       perror("os::create_thread");
1349     }
1350     thread->set_osthread(NULL);
1351     // Need to clean up stuff we've allocated so far
1352     delete osthread;
1353     return false;
1354   }
1355 
1356   Atomic::inc(&os::Solaris::_os_thread_count);
1357 
1358   // Store info on the Solaris thread into the OSThread
1359   osthread->set_thread_id(tid);
1360 
1361   // Remember that we created this thread so we can set priority on it
1362   osthread->set_vm_created();
1363 
1364   // Set the default thread priority.  If using bound threads, setting
1365   // lwp priority will be delayed until thread start.
1366   set_native_priority(thread, 
1367                       DefaultThreadPriority == -1 ?
1368                         java_to_os_priority[NormPriority] :
1369                         DefaultThreadPriority);

1370 
1371   // Initial thread state is INITIALIZED, not SUSPENDED
1372   osthread->set_state(INITIALIZED);
1373 
1374   // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
1375   return true;
1376 }
1377 
1378 /* defined for >= Solaris 10. This allows builds on earlier versions
1379  *  of Solaris to take advantage of the newly reserved Solaris JVM signals
1380  *  With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
1381  *  and -XX:+UseAltSigs does nothing since these should have no conflict
1382  */
1383 #if !defined(SIGJVM1)
1384 #define SIGJVM1 39
1385 #define SIGJVM2 40
1386 #endif
1387 
1388 debug_only(static bool signal_sets_initialized = false);
1389 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;


3718 // +    We assume that all threads in the process belong to the same
3719 //              scheduling class.   IE. an homogenous process.
3720 // +    Must be root or in IA group to change change "interactive" attribute.
3721 //              Priocntl() will fail silently.  The only indication of failure is when
3722 //              we read-back the value and notice that it hasn't changed.
3723 // +    Interactive threads enter the runq at the head, non-interactive at the tail.
3724 // +    For RT, change timeslice as well.  Invariant:
3725 //              constant "priority integral"
3726 //              Konst == TimeSlice * (60-Priority)
3727 //              Given a priority, compute appropriate timeslice.
3728 // +    Higher numerical values have higher priority.
3729 
3730 // sched class attributes
3731 typedef struct {
3732         int   schedPolicy;              // classID
3733         int   maxPrio;
3734         int   minPrio;
3735 } SchedInfo;
3736 
3737 
3738 static SchedInfo tsLimits, iaLimits, rtLimits, fxLimits;
3739 
3740 #ifdef ASSERT
3741 static int  ReadBackValidate = 1;
3742 #endif
3743 static int  myClass     = 0;
3744 static int  myMin       = 0;
3745 static int  myMax       = 0;
3746 static int  myCur       = 0;
3747 static bool priocntl_enable = false;
3748 
3749 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
3750 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
3751 
3752 // Call the version of priocntl suitable for all supported versions
3753 // of Solaris. We need to call through this wrapper so that we can
3754 // build on Solaris 9 and run on Solaris 8, 9 and 10.
3755 //
3756 // This code should be removed if we ever stop supporting Solaris 8
3757 // and earlier releases.
3758 
3759 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3760 typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3761 static priocntl_type priocntl_ptr = priocntl_stub;
3762 
3763 // Stub to set the value of the real pointer, and then call the real
3764 // function.
3765 
3766 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) {
3767   // Try Solaris 8- name only.
3768   priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl");
3769   guarantee(tmp != NULL, "priocntl function not found.");
3770   priocntl_ptr = tmp;


3778 //
3779 // Return errno or 0 if OK.
3780 //
3781 static
3782 int     lwp_priocntl_init ()
3783 {
3784   int rslt;
3785   pcinfo_t ClassInfo;
3786   pcparms_t ParmInfo;
3787   int i;
3788 
3789   if (!UseThreadPriorities) return 0;
3790 
3791   // We are using Bound threads, we need to determine our priority ranges
3792   if (os::Solaris::T2_libthread() || UseBoundThreads) {
3793     // If ThreadPriorityPolicy is 1, switch tables
3794     if (ThreadPriorityPolicy == 1) {
3795       for (i = 0 ; i < MaxPriority+1; i++)
3796         os::java_to_os_priority[i] = prio_policy1[i];
3797     }
3798     if (UseCriticalJavaThreadPriority) {
3799       // MaxPriority always maps to the FX scheduling class and criticalPrio.
3800       // See set_native_priority() and set_lwp_class_and_priority().
3801       // Save original MaxPriority mapping in case attempt to
3802       // use critical priority fails.
3803       java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
3804       // Set negative to distinguish from other priorities
3805       os::java_to_os_priority[MaxPriority] = -criticalPrio;
3806     }
3807   }
3808   // Not using Bound Threads, set to ThreadPolicy 1
3809   else {
3810     for ( i = 0 ; i < MaxPriority+1; i++ ) {
3811       os::java_to_os_priority[i] = prio_policy1[i];
3812     }
3813     return 0;
3814   }
3815 

3816   // Get IDs for a set of well-known scheduling classes.
3817   // TODO-FIXME: GETCLINFO returns the current # of classes in the
3818   // the system.  We should have a loop that iterates over the
3819   // classID values, which are known to be "small" integers.
3820 
3821   strcpy(ClassInfo.pc_clname, "TS");
3822   ClassInfo.pc_cid = -1;
3823   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3824   if (rslt < 0) return errno;
3825   assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3826   tsLimits.schedPolicy = ClassInfo.pc_cid;
3827   tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3828   tsLimits.minPrio = -tsLimits.maxPrio;
3829 
3830   strcpy(ClassInfo.pc_clname, "IA");
3831   ClassInfo.pc_cid = -1;
3832   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3833   if (rslt < 0) return errno;
3834   assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
3835   iaLimits.schedPolicy = ClassInfo.pc_cid;
3836   iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
3837   iaLimits.minPrio = -iaLimits.maxPrio;
3838 
3839   strcpy(ClassInfo.pc_clname, "RT");
3840   ClassInfo.pc_cid = -1;
3841   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3842   if (rslt < 0) return errno;
3843   assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
3844   rtLimits.schedPolicy = ClassInfo.pc_cid;
3845   rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
3846   rtLimits.minPrio = 0;
3847 
3848   strcpy(ClassInfo.pc_clname, "FX");
3849   ClassInfo.pc_cid = -1;
3850   rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3851   if (rslt < 0) return errno;
3852   assert(ClassInfo.pc_cid != -1, "cid for FX class is -1");
3853   fxLimits.schedPolicy = ClassInfo.pc_cid;
3854   fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri;
3855   fxLimits.minPrio = 0;
3856 
3857   // Query our "current" scheduling class.
3858   // This will normally be IA, TS or, rarely, FX or RT.
3859   memset(&ParmInfo, 0, sizeof(ParmInfo));
3860   ParmInfo.pc_cid = PC_CLNULL;
3861   rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3862   if (rslt < 0) return errno;
3863   myClass = ParmInfo.pc_cid;
3864 
3865   // We now know our scheduling classId, get specific information
3866   // about the class.
3867   ClassInfo.pc_cid = myClass;
3868   ClassInfo.pc_clname[0] = 0;
3869   rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo);
3870   if (rslt < 0) return errno;
3871 
3872   if (ThreadPriorityVerbose) {
3873     tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
3874   }
3875 
3876   memset(&ParmInfo, 0, sizeof(pcparms_t));
3877   ParmInfo.pc_cid = PC_CLNULL;
3878   rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3879   if (rslt < 0) return errno;
3880 
3881   if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
3882     myMin = rtLimits.minPrio;
3883     myMax = rtLimits.maxPrio;
3884   } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
3885     iaparms_t *iaInfo  = (iaparms_t*)ParmInfo.pc_clparms;
3886     myMin = iaLimits.minPrio;
3887     myMax = iaLimits.maxPrio;
3888     myMax = MIN2(myMax, (int)iaInfo->ia_uprilim);       // clamp - restrict
3889   } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
3890     tsparms_t *tsInfo  = (tsparms_t*)ParmInfo.pc_clparms;
3891     myMin = tsLimits.minPrio;
3892     myMax = tsLimits.maxPrio;
3893     myMax = MIN2(myMax, (int)tsInfo->ts_uprilim);       // clamp - restrict
3894   } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
3895     fxparms_t *fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
3896     myMin = fxLimits.minPrio;
3897     myMax = fxLimits.maxPrio;
3898     myMax = MIN2(myMax, (int)fxInfo->fx_uprilim);       // clamp - restrict
3899   } else {
3900     // No clue - punt
3901     if (ThreadPriorityVerbose)
3902       tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname);
3903     return EINVAL;      // no clue, punt
3904   }
3905 
3906   if (ThreadPriorityVerbose) {
3907     tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
3908   }
3909 
3910   priocntl_enable = true;  // Enable changing priorities
3911   return 0;
3912 }
3913 
3914 #define IAPRI(x)        ((iaparms_t *)((x).pc_clparms))
3915 #define RTPRI(x)        ((rtparms_t *)((x).pc_clparms))
3916 #define TSPRI(x)        ((tsparms_t *)((x).pc_clparms))
3917 #define FXPRI(x)        ((fxparms_t *)((x).pc_clparms))
3918 
3919 
3920 // scale_to_lwp_priority
3921 //
3922 // Convert from the libthread "thr_setprio" scale to our current
3923 // lwp scheduling class scale.
3924 //
3925 static
3926 int     scale_to_lwp_priority (int rMin, int rMax, int x)
3927 {
3928   int v;
3929 
3930   if (x == 127) return rMax;            // avoid round-down
3931     v = (((x*(rMax-rMin)))/128)+rMin;
3932   return v;
3933 }
3934 
3935 
3936 // set_lwp_class_and_priority
3937 //
3938 // Set the class and priority of the lwp.  This call should only
3939 // be made when using bound threads (T2 threads are bound by default).
3940 //
3941 int set_lwp_class_and_priority(int ThreadID, int lwpid,
3942                                int newPrio, int new_class, bool scale) {
3943   int rslt;
3944   int Actual, Expected, prv;
3945   pcparms_t ParmInfo;                   // for GET-SET
3946 #ifdef ASSERT
3947   pcparms_t ReadBack;                   // for readback
3948 #endif
3949 
3950   // Set priority via PC_GETPARMS, update, PC_SETPARMS
3951   // Query current values.
3952   // TODO: accelerate this by eliminating the PC_GETPARMS call.
3953   // Cache "pcparms_t" in global ParmCache.
3954   // TODO: elide set-to-same-value
3955 
3956   // If something went wrong on init, don't change priorities.
3957   if ( !priocntl_enable ) {
3958     if (ThreadPriorityVerbose)
3959       tty->print_cr("Trying to set priority but init failed, ignoring");
3960     return EINVAL;
3961   }
3962 

3963   // If lwp hasn't started yet, just return
3964   // the _start routine will call us again.
3965   if ( lwpid <= 0 ) {
3966     if (ThreadPriorityVerbose) {
3967       tty->print_cr ("deferring the set_lwp_class_and_priority of thread "
3968                      INTPTR_FORMAT " to %d, lwpid not set",
3969                      ThreadID, newPrio);
3970     }
3971     return 0;
3972   }
3973 
3974   if (ThreadPriorityVerbose) {
3975     tty->print_cr ("set_lwp_class_and_priority("
3976                    INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
3977                    ThreadID, lwpid, newPrio);
3978   }
3979 
3980   memset(&ParmInfo, 0, sizeof(pcparms_t));
3981   ParmInfo.pc_cid = PC_CLNULL;
3982   rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
3983   if (rslt < 0) return errno;
3984 
3985   int cur_class = ParmInfo.pc_cid;
3986   ParmInfo.pc_cid = (id_t)new_class;
3987 
3988   if (new_class == rtLimits.schedPolicy) {
3989     rtparms_t *rtInfo  = (rtparms_t*)ParmInfo.pc_clparms;
3990     rtInfo->rt_pri     = scale ? scale_to_lwp_priority(rtLimits.minPrio, rtLimits.maxPrio, newPrio)
3991                                : newPrio;
3992     rtInfo->rt_tqsecs  = RT_NOCHANGE;
3993     rtInfo->rt_tqnsecs = RT_NOCHANGE;
3994     if (ThreadPriorityVerbose) {
3995       tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
3996     }
3997   } else if (new_class == iaLimits.schedPolicy) {
3998     iaparms_t* iaInfo  = (iaparms_t*)ParmInfo.pc_clparms;
3999     int maxClamped     = MIN2(iaLimits.maxPrio, cur_class == new_class ? (int)iaInfo->ia_uprilim : iaLimits.maxPrio);
4000     iaInfo->ia_upri    = scale ? scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio)
4001                                : newPrio;
4002     iaInfo->ia_uprilim = cur_class == new_class ? IA_NOCHANGE : (pri_t)iaLimits.maxPrio;
4003     iaInfo->ia_mode    = IA_NOCHANGE;
4004     iaInfo->ia_nice    = cur_class == new_class ? IA_NOCHANGE : NZERO;
4005     if (ThreadPriorityVerbose) {
4006       tty->print_cr("IA: [%d...%d] %d->%d\n",
4007                     iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
4008     }
4009   } else if (new_class == tsLimits.schedPolicy) {
4010     tsparms_t* tsInfo  = (tsparms_t*)ParmInfo.pc_clparms;
4011     int maxClamped     = MIN2(tsLimits.maxPrio, cur_class == new_class ? (int)tsInfo->ts_uprilim : tsLimits.maxPrio);
4012     tsInfo->ts_upri    = scale ? scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio)
4013                                : newPrio;
4014     tsInfo->ts_uprilim = cur_class == new_class ? TS_NOCHANGE : (pri_t)tsLimits.maxPrio;
4015     if (ThreadPriorityVerbose) {
4016       tty->print_cr("TS: [%d...%d] %d->%d\n",
4017                     tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
4018     }
4019   } else if (new_class == fxLimits.schedPolicy) {
4020     fxparms_t* fxInfo  = (fxparms_t*)ParmInfo.pc_clparms;
4021     int maxClamped     = MIN2(fxLimits.maxPrio, cur_class == new_class ? (int)fxInfo->fx_uprilim : fxLimits.maxPrio);
4022     fxInfo->fx_upri    = scale ? scale_to_lwp_priority(fxLimits.minPrio, maxClamped, newPrio)
4023                                : newPrio;
4024     fxInfo->fx_uprilim = cur_class == new_class ? FX_NOCHANGE : (pri_t)fxLimits.maxPrio;
4025     fxInfo->fx_tqsecs  = FX_NOCHANGE;
4026     fxInfo->fx_tqnsecs = FX_NOCHANGE;
4027     if (ThreadPriorityVerbose) {
4028       tty->print_cr("FX: [%d...%d] %d->%d\n",
4029                     fxLimits.minPrio, maxClamped, newPrio, fxInfo->fx_upri);
4030     }
4031   } else {
4032     if (ThreadPriorityVerbose) {
4033       tty->print_cr("Unknown new scheduling class %d\n", new_class);
4034     }
4035     return EINVAL;    // no clue, punt
4036   }
4037 
4038   rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
4039   if (ThreadPriorityVerbose && rslt) {
4040     tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
4041   }
4042   if (rslt < 0) return errno;
4043 
4044 #ifdef ASSERT
4045   // Sanity check: read back what we just attempted to set.
4046   // In theory it could have changed in the interim ...
4047   //
4048   // The priocntl system call is tricky.
4049   // Sometimes it'll validate the priority value argument and
4050   // return EINVAL if unhappy.  At other times it fails silently.
4051   // Readbacks are prudent.
4052 
4053   if (!ReadBackValidate) return 0;
4054 
4055   memset(&ReadBack, 0, sizeof(pcparms_t));
4056   ReadBack.pc_cid = PC_CLNULL;
4057   rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
4058   assert(rslt >= 0, "priocntl failed");
4059   Actual = Expected = 0xBAD;
4060   assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
4061   if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
4062     Actual   = RTPRI(ReadBack)->rt_pri;
4063     Expected = RTPRI(ParmInfo)->rt_pri;
4064   } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
4065     Actual   = IAPRI(ReadBack)->ia_upri;
4066     Expected = IAPRI(ParmInfo)->ia_upri;
4067   } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
4068     Actual   = TSPRI(ReadBack)->ts_upri;
4069     Expected = TSPRI(ParmInfo)->ts_upri;
4070   } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
4071     Actual   = FXPRI(ReadBack)->fx_upri;
4072     Expected = FXPRI(ParmInfo)->fx_upri;
4073   } else {
4074     if (ThreadPriorityVerbose) {
4075       tty->print_cr("set_lwp_class_and_priority: unexpected class in readback: %d\n",
4076                     ParmInfo.pc_cid);
4077     }
4078   }
4079 
4080   if (Actual != Expected) {
4081     if (ThreadPriorityVerbose) {
4082       tty->print_cr ("set_lwp_class_and_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
4083                      lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
4084     }
4085   }
4086 #endif
4087 
4088   return 0;
4089 }
4090 


4091 // Solaris only gives access to 128 real priorities at a time,
4092 // so we expand Java's ten to fill this range.  This would be better
4093 // if we dynamically adjusted relative priorities.
4094 //
4095 // The ThreadPriorityPolicy option allows us to select 2 different
4096 // priority scales.
4097 //
4098 // ThreadPriorityPolicy=0
4099 // Since the Solaris' default priority is MaximumPriority, we do not
4100 // set a priority lower than Max unless a priority lower than
4101 // NormPriority is requested.
4102 //
4103 // ThreadPriorityPolicy=1
4104 // This mode causes the priority table to get filled with
4105 // linear values.  NormPriority get's mapped to 50% of the
4106 // Maximum priority an so on.  This will cause VM threads
4107 // to get unfair treatment against other Solaris processes
4108 // which do not explicitly alter their thread priorities.
4109 //
4110 
4111 int os::java_to_os_priority[CriticalPriority + 1] = {

4112   -99999,         // 0 Entry should never be used
4113 
4114   0,              // 1 MinPriority
4115   32,             // 2
4116   64,             // 3
4117 
4118   96,             // 4
4119   127,            // 5 NormPriority
4120   127,            // 6
4121 
4122   127,            // 7
4123   127,            // 8
4124   127,            // 9 NearMaxPriority
4125 
4126   127,            // 10 MaxPriority
4127 
4128   -criticalPrio   // 11 CriticalPriority
4129 };
4130 

4131 OSReturn os::set_native_priority(Thread* thread, int newpri) {
4132   OSThread* osthread = thread->osthread();
4133 
4134   // Save requested priority in case the thread hasn't been started
4135   osthread->set_native_priority(newpri);
4136 
4137   // Check for critical priority request
4138   bool fxcritical = false;
4139   if (newpri == -criticalPrio) {
4140     fxcritical = true;
4141     newpri = criticalPrio;
4142   }
4143 
4144   assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
4145   if (!UseThreadPriorities) return OS_OK;
4146 
4147   int status = 0;
4148 
4149   if (!fxcritical) {
4150     // Use thr_setprio only if we have a priority that thr_setprio understands
4151     status = thr_setprio(thread->osthread()->thread_id(), newpri);
4152   }
4153 
4154   if (os::Solaris::T2_libthread() ||
4155       (UseBoundThreads && osthread->is_vm_created())) {
4156     int lwp_status =
4157       set_lwp_class_and_priority(osthread->thread_id(),
4158                                  osthread->lwp_id(),
4159                                  newpri,
4160                                  fxcritical ? fxLimits.schedPolicy : myClass,
4161                                  !fxcritical);
4162     if (lwp_status != 0 && fxcritical) {
4163       // Try again, this time without changing the scheduling class
4164       newpri = java_MaxPriority_to_os_priority;
4165       lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
4166                                               osthread->lwp_id(),
4167                                               newpri, myClass, false);
4168     }
4169     status |= lwp_status;
4170   }
4171   return (status == 0) ? OS_OK : OS_ERR;
4172 }
4173 
4174 
4175 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
4176   int p;
4177   if ( !UseThreadPriorities ) {
4178     *priority_ptr = NormalPriority;
4179     return OS_OK;
4180   }
4181   int status = thr_getprio(thread->osthread()->thread_id(), &p);
4182   if (status != 0) {
4183     return OS_ERR;
4184   }
4185   *priority_ptr = p;
4186   return OS_OK;
4187 }
4188 
4189 
4190 // Hint to the underlying OS that a task switch would not be good.


src/os/solaris/vm/os_solaris.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File