if (ThreadPriorityPolicy == 1) {
// Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
// if effective uid is not root. Perhaps, a more elegant way of doing
// this is to test CAP_SYS_NICE capability, but that will require libcap.so
if (geteuid() != 0) {
if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
}
ThreadPriorityPolicy = 0;
}
}
It is meant to reset command line argument from 1 to 0 if the effective user is not root.
Look here:
OSReturn os::set_native_priority(Thread* thread, int newpri) {
if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
return (ret == 0) ? OS_OK : OS_ERR;
}
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
*priority_ptr = java_to_os_priority[NormPriority];
return OS_OK;
}
...
}
I've highlighted the interesting code. Do you see how it checks for policy? It means that if we set ThreadPriorityPolicy to ... say to 666, java will still work like the policy is set to 1. And the check that resets ThreadPriorityPolicy from 1 to 0 for non-root users will not be triggered. Whee! So in fact we can use the policy 1 for non-root users running java with the command line argument -XX:ThreadPriorityPolicy=666. But stop would say you, what will it give us if the system's setpriority function fails for non-root user? It gives us enough if we can run our lovely java initially with nice level -5. A level -5 is the nice level used for HIGHEST priority threads in java as you can see from the following code snippet:
int os::java_to_os_priority[MaxPriority + 1] = {
19, // 0 Entry should never be used
4, // 1 MinPriority
3, // 2
2, // 3
1, // 4
0, // 5 NormPriority
-1, // 6
-2, // 7
-3, // 8
-4, // 9 NearMaxPriority
-5 // 10 MaxPriority
};
Though this looks not fair and totally unholy, I think it is still better then running java with priorities ignored or under root. Thus you can run your java safely and well-scheduled with the command like this:
nice -n -5 su -c 'java -XX:ThreadPriorityPolicy=666 ThreadTester' akshaal
There is other way if you have no access to root user.
java -XX:ThreadPriorityPolicy=666 \
-XX:JavaPriority10_To_OSPriority=0 \
-XX:JavaPriority9_To_OSPriority=1 \
-XX:JavaPriority8_To_OSPriority=2 \
-XX:JavaPriority7_To_OSPriority=3 \
-XX:JavaPriority6_To_OSPriority=4 \
-XX:JavaPriority5_To_OSPriority=5 \
-XX:JavaPriority4_To_OSPriority=6 \
-XX:JavaPriority3_To_OSPriority=7 \
-XX:JavaPriority2_To_OSPriority=8 \
-XX:JavaPriority1_To_OSPriority=9 \
ThreadTester
Hi. I am developing a real-time system using regular JVM (no RTJS please) and I would like to give my thread the highest possible priority. Can I do that as root and using the new -XX:ThreadPriorityPolicy=666 ? Thanks!
ReplyDeleteHi rebecca, are you allways in devlopping the real time systeme using regular JVM ?
ReplyDeleteGreat post, thanks
ReplyDelete