comparison src/os/solaris/vm/os_solaris.cpp @ 4854:de268c8a8075

7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11 Summary: Add CriticalPriority == MaxPriority+1 and enable scheduling class as well as thread priority to change on Solaris. Reviewed-by: dholmes, dcubed
author phh
date Thu, 26 Jan 2012 20:06:06 -0500
parents d7e3846464d0
children 869be5c8882e
comparison
equal deleted inserted replaced
4853:6db63e782d3d 4854:de268c8a8075
1 /* 1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
112 # include <unistd.h> 112 # include <unistd.h>
113 # include <sys/priocntl.h> 113 # include <sys/priocntl.h>
114 # include <sys/rtpriocntl.h> 114 # include <sys/rtpriocntl.h>
115 # include <sys/tspriocntl.h> 115 # include <sys/tspriocntl.h>
116 # include <sys/iapriocntl.h> 116 # include <sys/iapriocntl.h>
117 # include <sys/fxpriocntl.h>
117 # include <sys/loadavg.h> 118 # include <sys/loadavg.h>
118 # include <string.h> 119 # include <string.h>
119 # include <stdio.h> 120 # include <stdio.h>
120 121
121 # define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later 122 # define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later
127 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) 128 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
128 129
129 #ifdef _GNU_SOURCE 130 #ifdef _GNU_SOURCE
130 // See bug #6514594 131 // See bug #6514594
131 extern "C" int madvise(caddr_t, size_t, int); 132 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 extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg,
133 int attr, int mask); 134 int attr, int mask);
134 #endif //_GNU_SOURCE 135 #endif //_GNU_SOURCE
135 136
136 /* 137 /*
137 MPSS Changes Start. 138 MPSS Changes Start.
138 The JVM binary needs to be built and run on pre-Solaris 9 139 The JVM binary needs to be built and run on pre-Solaris 9
213 #define MinimumPriority 0 214 #define MinimumPriority 0
214 #define NormalPriority 64 215 #define NormalPriority 64
215 #define MaximumPriority 127 216 #define MaximumPriority 127
216 217
217 // Values for ThreadPriorityPolicy == 1 218 // Values for ThreadPriorityPolicy == 1
218 int prio_policy1[MaxPriority+1] = { -99999, 0, 16, 32, 48, 64, 219 int prio_policy1[CriticalPriority+1] = {
219 80, 96, 112, 124, 127 }; 220 -99999, 0, 16, 32, 48, 64,
221 80, 96, 112, 124, 127, 127 };
220 222
221 // System parameters used internally 223 // System parameters used internally
222 static clock_t clock_tics_per_sec = 100; 224 static clock_t clock_tics_per_sec = 100;
223 225
224 // Track if we have called enable_extended_FILE_stdio (on Solaris 10u4+) 226 // Track if we have called enable_extended_FILE_stdio (on Solaris 10u4+)
1046 thread->set_lgrp_id(lgrp_id); 1048 thread->set_lgrp_id(lgrp_id);
1047 } 1049 }
1048 } 1050 }
1049 1051
1050 // If the creator called set priority before we started, 1052 // If the creator called set priority before we started,
1051 // we need to call set priority now that we have an lwp. 1053 // we need to call set_native_priority now that we have an lwp.
1052 // Get the priority from libthread and set the priority 1054 // We used to get the priority from thr_getprio (we called
1053 // for the new Solaris lwp. 1055 // thr_setprio way back in create_thread) and pass it to
1056 // set_native_priority, but Solaris scales the priority
1057 // in java_to_os_priority, so when we read it back here,
1058 // we pass trash to set_native_priority instead of what's
1059 // in java_to_os_priority. So we save the native priority
1060 // in the osThread and recall it here.
1061
1054 if ( osthr->thread_id() != -1 ) { 1062 if ( osthr->thread_id() != -1 ) {
1055 if ( UseThreadPriorities ) { 1063 if ( UseThreadPriorities ) {
1056 thr_getprio(osthr->thread_id(), &prio); 1064 int prio = osthr->native_priority();
1057 if (ThreadPriorityVerbose) { 1065 if (ThreadPriorityVerbose) {
1058 tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT ", setting priority: %d\n", 1066 tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is "
1059 osthr->thread_id(), osthr->lwp_id(), prio ); 1067 INTPTR_FORMAT ", setting priority: %d\n",
1068 osthr->thread_id(), osthr->lwp_id(), prio);
1060 } 1069 }
1061 os::set_native_priority(thread, prio); 1070 os::set_native_priority(thread, prio);
1062 } 1071 }
1063 } else if (ThreadPriorityVerbose) { 1072 } else if (ThreadPriorityVerbose) {
1064 warning("Can't set priority in _start routine, thread id hasn't been set\n"); 1073 warning("Can't set priority in _start routine, thread id hasn't been set\n");
1351 osthread->set_thread_id(tid); 1360 osthread->set_thread_id(tid);
1352 1361
1353 // Remember that we created this thread so we can set priority on it 1362 // Remember that we created this thread so we can set priority on it
1354 osthread->set_vm_created(); 1363 osthread->set_vm_created();
1355 1364
1356 // Set the default thread priority otherwise use NormalPriority 1365 // Set the default thread priority. If using bound threads, setting
1357 1366 // lwp priority will be delayed until thread start.
1358 if ( UseThreadPriorities ) { 1367 set_native_priority(thread,
1359 thr_setprio(tid, (DefaultThreadPriority == -1) ? 1368 DefaultThreadPriority == -1 ?
1360 java_to_os_priority[NormPriority] : 1369 java_to_os_priority[NormPriority] :
1361 DefaultThreadPriority); 1370 DefaultThreadPriority);
1362 }
1363 1371
1364 // Initial thread state is INITIALIZED, not SUSPENDED 1372 // Initial thread state is INITIALIZED, not SUSPENDED
1365 osthread->set_state(INITIALIZED); 1373 osthread->set_state(INITIALIZED);
1366 1374
1367 // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain 1375 // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
3726 int maxPrio; 3734 int maxPrio;
3727 int minPrio; 3735 int minPrio;
3728 } SchedInfo; 3736 } SchedInfo;
3729 3737
3730 3738
3731 static SchedInfo tsLimits, iaLimits, rtLimits; 3739 static SchedInfo tsLimits, iaLimits, rtLimits, fxLimits;
3732 3740
3733 #ifdef ASSERT 3741 #ifdef ASSERT
3734 static int ReadBackValidate = 1; 3742 static int ReadBackValidate = 1;
3735 #endif 3743 #endif
3736 static int myClass = 0; 3744 static int myClass = 0;
3737 static int myMin = 0; 3745 static int myMin = 0;
3738 static int myMax = 0; 3746 static int myMax = 0;
3739 static int myCur = 0; 3747 static int myCur = 0;
3740 static bool priocntl_enable = false; 3748 static bool priocntl_enable = false;
3741 3749
3750 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
3751 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
3742 3752
3743 // Call the version of priocntl suitable for all supported versions 3753 // Call the version of priocntl suitable for all supported versions
3744 // of Solaris. We need to call through this wrapper so that we can 3754 // 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. 3755 // build on Solaris 9 and run on Solaris 8, 9 and 10.
3746 // 3756 //
3781 3791
3782 // We are using Bound threads, we need to determine our priority ranges 3792 // We are using Bound threads, we need to determine our priority ranges
3783 if (os::Solaris::T2_libthread() || UseBoundThreads) { 3793 if (os::Solaris::T2_libthread() || UseBoundThreads) {
3784 // If ThreadPriorityPolicy is 1, switch tables 3794 // If ThreadPriorityPolicy is 1, switch tables
3785 if (ThreadPriorityPolicy == 1) { 3795 if (ThreadPriorityPolicy == 1) {
3786 for (i = 0 ; i < MaxPriority+1; i++) 3796 for (i = 0 ; i < CriticalPriority+1; i++)
3787 os::java_to_os_priority[i] = prio_policy1[i]; 3797 os::java_to_os_priority[i] = prio_policy1[i];
3798 }
3799 if (UseCriticalJavaThreadPriority) {
3800 // MaxPriority always maps to the FX scheduling class and criticalPrio.
3801 // See set_native_priority() and set_lwp_class_and_priority().
3802 // Save original MaxPriority mapping in case attempt to
3803 // use critical priority fails.
3804 java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
3805 // Set negative to distinguish from other priorities
3806 os::java_to_os_priority[MaxPriority] = -criticalPrio;
3788 } 3807 }
3789 } 3808 }
3790 // Not using Bound Threads, set to ThreadPolicy 1 3809 // Not using Bound Threads, set to ThreadPolicy 1
3791 else { 3810 else {
3792 for ( i = 0 ; i < MaxPriority+1; i++ ) { 3811 for ( i = 0 ; i < CriticalPriority+1; i++ ) {
3793 os::java_to_os_priority[i] = prio_policy1[i]; 3812 os::java_to_os_priority[i] = prio_policy1[i];
3794 } 3813 }
3795 return 0; 3814 return 0;
3796 } 3815 }
3797
3798 3816
3799 // Get IDs for a set of well-known scheduling classes. 3817 // Get IDs for a set of well-known scheduling classes.
3800 // TODO-FIXME: GETCLINFO returns the current # of classes in the 3818 // TODO-FIXME: GETCLINFO returns the current # of classes in the
3801 // the system. We should have a loop that iterates over the 3819 // the system. We should have a loop that iterates over the
3802 // classID values, which are known to be "small" integers. 3820 // classID values, which are known to be "small" integers.
3826 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); 3844 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
3827 rtLimits.schedPolicy = ClassInfo.pc_cid; 3845 rtLimits.schedPolicy = ClassInfo.pc_cid;
3828 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; 3846 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
3829 rtLimits.minPrio = 0; 3847 rtLimits.minPrio = 0;
3830 3848
3849 strcpy(ClassInfo.pc_clname, "FX");
3850 ClassInfo.pc_cid = -1;
3851 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3852 if (rslt < 0) return errno;
3853 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1");
3854 fxLimits.schedPolicy = ClassInfo.pc_cid;
3855 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri;
3856 fxLimits.minPrio = 0;
3831 3857
3832 // Query our "current" scheduling class. 3858 // Query our "current" scheduling class.
3833 // This will normally be IA,TS or, rarely, RT. 3859 // This will normally be IA, TS or, rarely, FX or RT.
3834 memset (&ParmInfo, 0, sizeof(ParmInfo)); 3860 memset(&ParmInfo, 0, sizeof(ParmInfo));
3835 ParmInfo.pc_cid = PC_CLNULL; 3861 ParmInfo.pc_cid = PC_CLNULL;
3836 rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo ); 3862 rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3837 if ( rslt < 0 ) return errno; 3863 if (rslt < 0) return errno;
3838 myClass = ParmInfo.pc_cid; 3864 myClass = ParmInfo.pc_cid;
3839 3865
3840 // We now know our scheduling classId, get specific information 3866 // We now know our scheduling classId, get specific information
3841 // the class. 3867 // about the class.
3842 ClassInfo.pc_cid = myClass; 3868 ClassInfo.pc_cid = myClass;
3843 ClassInfo.pc_clname[0] = 0; 3869 ClassInfo.pc_clname[0] = 0;
3844 rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo ); 3870 rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo);
3845 if ( rslt < 0 ) return errno; 3871 if (rslt < 0) return errno;
3846 3872
3847 if (ThreadPriorityVerbose) 3873 if (ThreadPriorityVerbose) {
3848 tty->print_cr ("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname); 3874 tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
3875 }
3849 3876
3850 memset(&ParmInfo, 0, sizeof(pcparms_t)); 3877 memset(&ParmInfo, 0, sizeof(pcparms_t));
3851 ParmInfo.pc_cid = PC_CLNULL; 3878 ParmInfo.pc_cid = PC_CLNULL;
3852 rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); 3879 rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3853 if (rslt < 0) return errno; 3880 if (rslt < 0) return errno;
3863 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { 3890 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
3864 tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms; 3891 tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
3865 myMin = tsLimits.minPrio; 3892 myMin = tsLimits.minPrio;
3866 myMax = tsLimits.maxPrio; 3893 myMax = tsLimits.maxPrio;
3867 myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict 3894 myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict
3895 } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
3896 fxparms_t *fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
3897 myMin = fxLimits.minPrio;
3898 myMax = fxLimits.maxPrio;
3899 myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict
3868 } else { 3900 } else {
3869 // No clue - punt 3901 // No clue - punt
3870 if (ThreadPriorityVerbose) 3902 if (ThreadPriorityVerbose)
3871 tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname); 3903 tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname);
3872 return EINVAL; // no clue, punt 3904 return EINVAL; // no clue, punt
3873 } 3905 }
3874 3906
3875 if (ThreadPriorityVerbose) 3907 if (ThreadPriorityVerbose) {
3876 tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax); 3908 tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
3909 }
3877 3910
3878 priocntl_enable = true; // Enable changing priorities 3911 priocntl_enable = true; // Enable changing priorities
3879 return 0; 3912 return 0;
3880 } 3913 }
3881 3914
3882 #define IAPRI(x) ((iaparms_t *)((x).pc_clparms)) 3915 #define IAPRI(x) ((iaparms_t *)((x).pc_clparms))
3883 #define RTPRI(x) ((rtparms_t *)((x).pc_clparms)) 3916 #define RTPRI(x) ((rtparms_t *)((x).pc_clparms))
3884 #define TSPRI(x) ((tsparms_t *)((x).pc_clparms)) 3917 #define TSPRI(x) ((tsparms_t *)((x).pc_clparms))
3918 #define FXPRI(x) ((fxparms_t *)((x).pc_clparms))
3885 3919
3886 3920
3887 // scale_to_lwp_priority 3921 // scale_to_lwp_priority
3888 // 3922 //
3889 // Convert from the libthread "thr_setprio" scale to our current 3923 // Convert from the libthread "thr_setprio" scale to our current
3898 v = (((x*(rMax-rMin)))/128)+rMin; 3932 v = (((x*(rMax-rMin)))/128)+rMin;
3899 return v; 3933 return v;
3900 } 3934 }
3901 3935
3902 3936
3903 // set_lwp_priority 3937 // set_lwp_class_and_priority
3904 // 3938 //
3905 // Set the priority of the lwp. This call should only be made 3939 // Set the class and priority of the lwp. This call should only
3906 // when using bound threads (T2 threads are bound by default). 3940 // be made when using bound threads (T2 threads are bound by default).
3907 // 3941 //
3908 int set_lwp_priority (int ThreadID, int lwpid, int newPrio ) 3942 int set_lwp_class_and_priority(int ThreadID, int lwpid,
3909 { 3943 int newPrio, int new_class, bool scale) {
3910 int rslt; 3944 int rslt;
3911 int Actual, Expected, prv; 3945 int Actual, Expected, prv;
3912 pcparms_t ParmInfo; // for GET-SET 3946 pcparms_t ParmInfo; // for GET-SET
3913 #ifdef ASSERT 3947 #ifdef ASSERT
3914 pcparms_t ReadBack; // for readback 3948 pcparms_t ReadBack; // for readback
3925 if (ThreadPriorityVerbose) 3959 if (ThreadPriorityVerbose)
3926 tty->print_cr("Trying to set priority but init failed, ignoring"); 3960 tty->print_cr("Trying to set priority but init failed, ignoring");
3927 return EINVAL; 3961 return EINVAL;
3928 } 3962 }
3929 3963
3930
3931 // If lwp hasn't started yet, just return 3964 // If lwp hasn't started yet, just return
3932 // the _start routine will call us again. 3965 // the _start routine will call us again.
3933 if ( lwpid <= 0 ) { 3966 if ( lwpid <= 0 ) {
3934 if (ThreadPriorityVerbose) { 3967 if (ThreadPriorityVerbose) {
3935 tty->print_cr ("deferring the set_lwp_priority of thread " INTPTR_FORMAT " to %d, lwpid not set", 3968 tty->print_cr ("deferring the set_lwp_class_and_priority of thread "
3969 INTPTR_FORMAT " to %d, lwpid not set",
3936 ThreadID, newPrio); 3970 ThreadID, newPrio);
3937 } 3971 }
3938 return 0; 3972 return 0;
3939 } 3973 }
3940 3974
3941 if (ThreadPriorityVerbose) { 3975 if (ThreadPriorityVerbose) {
3942 tty->print_cr ("set_lwp_priority(" INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ", 3976 tty->print_cr ("set_lwp_class_and_priority("
3977 INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
3943 ThreadID, lwpid, newPrio); 3978 ThreadID, lwpid, newPrio);
3944 } 3979 }
3945 3980
3946 memset(&ParmInfo, 0, sizeof(pcparms_t)); 3981 memset(&ParmInfo, 0, sizeof(pcparms_t));
3947 ParmInfo.pc_cid = PC_CLNULL; 3982 ParmInfo.pc_cid = PC_CLNULL;
3948 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); 3983 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
3949 if (rslt < 0) return errno; 3984 if (rslt < 0) return errno;
3950 3985
3951 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3986 int cur_class = ParmInfo.pc_cid;
3987 ParmInfo.pc_cid = (id_t)new_class;
3988
3989 if (new_class == rtLimits.schedPolicy) {
3952 rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms; 3990 rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms;
3953 rtInfo->rt_pri = scale_to_lwp_priority (rtLimits.minPrio, rtLimits.maxPrio, newPrio); 3991 rtInfo->rt_pri = scale ? scale_to_lwp_priority(rtLimits.minPrio,
3992 rtLimits.maxPrio, newPrio)
3993 : newPrio;
3954 rtInfo->rt_tqsecs = RT_NOCHANGE; 3994 rtInfo->rt_tqsecs = RT_NOCHANGE;
3955 rtInfo->rt_tqnsecs = RT_NOCHANGE; 3995 rtInfo->rt_tqnsecs = RT_NOCHANGE;
3956 if (ThreadPriorityVerbose) { 3996 if (ThreadPriorityVerbose) {
3957 tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri); 3997 tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
3958 } 3998 }
3959 } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) { 3999 } else if (new_class == iaLimits.schedPolicy) {
3960 iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms; 4000 iaparms_t* iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
3961 int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim); 4001 int maxClamped = MIN2(iaLimits.maxPrio,
3962 iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio); 4002 cur_class == new_class
3963 iaInfo->ia_uprilim = IA_NOCHANGE; 4003 ? (int)iaInfo->ia_uprilim : iaLimits.maxPrio);
4004 iaInfo->ia_upri = scale ? scale_to_lwp_priority(iaLimits.minPrio,
4005 maxClamped, newPrio)
4006 : newPrio;
4007 iaInfo->ia_uprilim = cur_class == new_class
4008 ? IA_NOCHANGE : (pri_t)iaLimits.maxPrio;
3964 iaInfo->ia_mode = IA_NOCHANGE; 4009 iaInfo->ia_mode = IA_NOCHANGE;
4010 iaInfo->ia_nice = cur_class == new_class ? IA_NOCHANGE : NZERO;
3965 if (ThreadPriorityVerbose) { 4011 if (ThreadPriorityVerbose) {
3966 tty->print_cr ("IA: [%d...%d] %d->%d\n", 4012 tty->print_cr("IA: [%d...%d] %d->%d\n",
3967 iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri); 4013 iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
3968 } 4014 }
3969 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { 4015 } else if (new_class == tsLimits.schedPolicy) {
3970 tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms; 4016 tsparms_t* tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
3971 int maxClamped = MIN2(tsLimits.maxPrio, (int)tsInfo->ts_uprilim); 4017 int maxClamped = MIN2(tsLimits.maxPrio,
3972 prv = tsInfo->ts_upri; 4018 cur_class == new_class
3973 tsInfo->ts_upri = scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio); 4019 ? (int)tsInfo->ts_uprilim : tsLimits.maxPrio);
3974 tsInfo->ts_uprilim = IA_NOCHANGE; 4020 tsInfo->ts_upri = scale ? scale_to_lwp_priority(tsLimits.minPrio,
4021 maxClamped, newPrio)
4022 : newPrio;
4023 tsInfo->ts_uprilim = cur_class == new_class
4024 ? TS_NOCHANGE : (pri_t)tsLimits.maxPrio;
3975 if (ThreadPriorityVerbose) { 4025 if (ThreadPriorityVerbose) {
3976 tty->print_cr ("TS: %d [%d...%d] %d->%d\n", 4026 tty->print_cr("TS: [%d...%d] %d->%d\n",
3977 prv, tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri); 4027 tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
3978 } 4028 }
3979 if (prv == tsInfo->ts_upri) return 0; 4029 } else if (new_class == fxLimits.schedPolicy) {
4030 fxparms_t* fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
4031 int maxClamped = MIN2(fxLimits.maxPrio,
4032 cur_class == new_class
4033 ? (int)fxInfo->fx_uprilim : fxLimits.maxPrio);
4034 fxInfo->fx_upri = scale ? scale_to_lwp_priority(fxLimits.minPrio,
4035 maxClamped, newPrio)
4036 : newPrio;
4037 fxInfo->fx_uprilim = cur_class == new_class
4038 ? FX_NOCHANGE : (pri_t)fxLimits.maxPrio;
4039 fxInfo->fx_tqsecs = FX_NOCHANGE;
4040 fxInfo->fx_tqnsecs = FX_NOCHANGE;
4041 if (ThreadPriorityVerbose) {
4042 tty->print_cr("FX: [%d...%d] %d->%d\n",
4043 fxLimits.minPrio, maxClamped, newPrio, fxInfo->fx_upri);
4044 }
3980 } else { 4045 } else {
3981 if ( ThreadPriorityVerbose ) { 4046 if (ThreadPriorityVerbose) {
3982 tty->print_cr ("Unknown scheduling class\n"); 4047 tty->print_cr("Unknown new scheduling class %d\n", new_class);
3983 } 4048 }
3984 return EINVAL; // no clue, punt 4049 return EINVAL; // no clue, punt
3985 } 4050 }
3986 4051
3987 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); 4052 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
3988 if (ThreadPriorityVerbose && rslt) { 4053 if (ThreadPriorityVerbose && rslt) {
3989 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); 4054 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
4014 Actual = IAPRI(ReadBack)->ia_upri; 4079 Actual = IAPRI(ReadBack)->ia_upri;
4015 Expected = IAPRI(ParmInfo)->ia_upri; 4080 Expected = IAPRI(ParmInfo)->ia_upri;
4016 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { 4081 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
4017 Actual = TSPRI(ReadBack)->ts_upri; 4082 Actual = TSPRI(ReadBack)->ts_upri;
4018 Expected = TSPRI(ParmInfo)->ts_upri; 4083 Expected = TSPRI(ParmInfo)->ts_upri;
4084 } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
4085 Actual = FXPRI(ReadBack)->fx_upri;
4086 Expected = FXPRI(ParmInfo)->fx_upri;
4019 } else { 4087 } else {
4020 if ( ThreadPriorityVerbose ) { 4088 if (ThreadPriorityVerbose) {
4021 tty->print_cr("set_lwp_priority: unexpected class in readback: %d\n", ParmInfo.pc_cid); 4089 tty->print_cr("set_lwp_class_and_priority: unexpected class in readback: %d\n",
4090 ParmInfo.pc_cid);
4022 } 4091 }
4023 } 4092 }
4024 4093
4025 if (Actual != Expected) { 4094 if (Actual != Expected) {
4026 if ( ThreadPriorityVerbose ) { 4095 if (ThreadPriorityVerbose) {
4027 tty->print_cr ("set_lwp_priority(%d %d) Class=%d: actual=%d vs expected=%d\n", 4096 tty->print_cr ("set_lwp_class_and_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
4028 lwpid, newPrio, ReadBack.pc_cid, Actual, Expected); 4097 lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
4029 } 4098 }
4030 } 4099 }
4031 #endif 4100 #endif
4032 4101
4033 return 0; 4102 return 0;
4034 } 4103 }
4035
4036
4037 4104
4038 // Solaris only gives access to 128 real priorities at a time, 4105 // 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 4106 // so we expand Java's ten to fill this range. This would be better
4040 // if we dynamically adjusted relative priorities. 4107 // if we dynamically adjusted relative priorities.
4041 // 4108 //
4053 // Maximum priority an so on. This will cause VM threads 4120 // Maximum priority an so on. This will cause VM threads
4054 // to get unfair treatment against other Solaris processes 4121 // to get unfair treatment against other Solaris processes
4055 // which do not explicitly alter their thread priorities. 4122 // which do not explicitly alter their thread priorities.
4056 // 4123 //
4057 4124
4058 4125 int os::java_to_os_priority[CriticalPriority + 1] = {
4059 int os::java_to_os_priority[MaxPriority + 1] = {
4060 -99999, // 0 Entry should never be used 4126 -99999, // 0 Entry should never be used
4061 4127
4062 0, // 1 MinPriority 4128 0, // 1 MinPriority
4063 32, // 2 4129 32, // 2
4064 64, // 3 4130 64, // 3
4069 4135
4070 127, // 7 4136 127, // 7
4071 127, // 8 4137 127, // 8
4072 127, // 9 NearMaxPriority 4138 127, // 9 NearMaxPriority
4073 4139
4074 127 // 10 MaxPriority 4140 127, // 10 MaxPriority
4141
4142 -criticalPrio // 11 CriticalPriority
4075 }; 4143 };
4076 4144
4077
4078 OSReturn os::set_native_priority(Thread* thread, int newpri) { 4145 OSReturn os::set_native_priority(Thread* thread, int newpri) {
4146 OSThread* osthread = thread->osthread();
4147
4148 // Save requested priority in case the thread hasn't been started
4149 osthread->set_native_priority(newpri);
4150
4151 // Check for critical priority request
4152 bool fxcritical = false;
4153 if (newpri == -criticalPrio) {
4154 fxcritical = true;
4155 newpri = criticalPrio;
4156 }
4157
4079 assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping"); 4158 assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
4080 if ( !UseThreadPriorities ) return OS_OK; 4159 if (!UseThreadPriorities) return OS_OK;
4081 int status = thr_setprio(thread->osthread()->thread_id(), newpri); 4160
4082 if ( os::Solaris::T2_libthread() || (UseBoundThreads && thread->osthread()->is_vm_created()) ) 4161 int status = 0;
4083 status |= (set_lwp_priority (thread->osthread()->thread_id(), 4162
4084 thread->osthread()->lwp_id(), newpri )); 4163 if (!fxcritical) {
4164 // Use thr_setprio only if we have a priority that thr_setprio understands
4165 status = thr_setprio(thread->osthread()->thread_id(), newpri);
4166 }
4167
4168 if (os::Solaris::T2_libthread() ||
4169 (UseBoundThreads && osthread->is_vm_created())) {
4170 int lwp_status =
4171 set_lwp_class_and_priority(osthread->thread_id(),
4172 osthread->lwp_id(),
4173 newpri,
4174 fxcritical ? fxLimits.schedPolicy : myClass,
4175 !fxcritical);
4176 if (lwp_status != 0 && fxcritical) {
4177 // Try again, this time without changing the scheduling class
4178 newpri = java_MaxPriority_to_os_priority;
4179 lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
4180 osthread->lwp_id(),
4181 newpri, myClass, false);
4182 }
4183 status |= lwp_status;
4184 }
4085 return (status == 0) ? OS_OK : OS_ERR; 4185 return (status == 0) ? OS_OK : OS_ERR;
4086 } 4186 }
4087 4187
4088 4188
4089 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { 4189 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {