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.
|