Mercurial > hg > truffle
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) { |