Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do Linux JVMs actually implement Thread priorities?

Tags:

Wrote a quick Java proggy to spawn 10 threads with each priority and calculate pi (4*atan(1) method) with BigDecimals 500,000 times each, join on each thread and report the elapsed time for run method. Yeah, prob'ly not the best example, but keeping it basic.

I'm aware of Bug4813310

It is non-trivial to do in C, but can we assume that native priorities are never set on Linux JVMs?

$uname -r && grep bogomips /proc/cpuinfo 2.4.33.3 bogomips        : 4312.26 $java -version 2>&1 |head -1 Java version "1.6.0_01" $javac T.java && java -Xmx32m -XX:+UseThreadPriorities T 1:3112 2:2636 3:2662 4:3118 5:2870 6:3319 7:3412 8:3304 9:3299 10:3069 

Looks like not much of a deviation that one would expect! That was on a small virtual Linux machine. Maybe just Sun's? We shall try IBM J9 VM:

1:4091 2:4142 3:3957 4:3905 5:3984 6:3985 7:4130 8:4055 9:3752 10:4071 

The gross numbers look pretty good in comparison, but there is no scale to the numbers from a thread priority perspective.

Let's try 500k iterations on a 2.6 kernel with an older Sun JVM, one that is constantly loaded with load averages rarely below 7:

$uname -r && grep bogomips /proc/cpuinfo 2.6.9-67.ELsmp bogomips        : 3992.93 bogomips        : 3990.00 $java -version 2>&1 |head -1 java version "1.4.2_14" $javac T.java && java -Xmx32m -XX:+UseThreadPriorities T 1:63200 2:64388 3:62532 4:58529 5:62292 6:64872 7:64885 8:64584 9:61653 10:61575 

Let's try IBM's J9 on a real slab just with 2.6 kernel and since a bigger system I'll increase iterations to 2,000,000.

$uname -r && grep bogomips /proc/cpuinfo 2.6.9-78.ELsmp bogomips        : 5989.03 bogomips        : 5985.03 bogomips        : 5985.01 bogomips        : 5985.02 bogomips        : 5984.99 bogomips        : 5985.02 bogomips        : 5984.99 bogomips        : 5985.02 $java -Xmx32m T # this is the IBM J9 1:1718 2:1569 3:1989 4:1897 5:1839 6:1688 7:1634 8:1552 9:2027 10:1522 

Some great times, but still no apparent thread/process priorities.

Let's try a Windows box. I know that Windows has a fairly aggressive thread priority scheme. Anything above normal anecdotaly consumes much more. As such, let's move to 900,000 iterations in each thread:

C:\>java -version java version "1.6.0_11" C:\>java -Xmx32m T 1:12578 2:12625 3:11469 4:11453 5:10781 6:8937 7:10516 8:8406 9:9953 10:7391 

Very much what we're looking for, no?

So Linux JVM's apparently don't have thread priority? I understand that you can't really renice to a lower nice level in C, but I would assume JVM engineers would have figured out how to keep a low-niced dispatcher of sorts.

like image 614
Jé Queue Avatar asked Nov 02 '09 16:11

Jé Queue


People also ask

Does JVM apply any thread priorities by itself?

No. It will not. Just to add, under the hoods, its the OS or System which has the final call on which threads to run on it's core and thus, its own scheduling algorithm is what eventually matters.

How do I set thread priority in Linux?

The equivalent to SetThreadPriority in linux would be pthread_setschedprio(pthread_t thread, int priority) . Check the man page. This sample is for the default scheduling policy which is SCHED_OTHER. EDIT: thread attribute must be initialized before usage.

Who decide the thread priority?

Explanation: Thread scheduler decides the priority of the thread execution.

How is thread priority assigned?

In multi-threaded applications, each thread is assigned with a priority. The processor is assigned to the thread by the thread scheduler based on its priority i.e. the highest priority thread is assigned the processor first and so on. The default priority of a thread with a value of '5'.


1 Answers

From the JDK 8 source code, a comment reads:

//////////////////////////////////////////////////////////////////////////////// // thread priority support  // Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER // only supports dynamic priority, static priority must be zero. For real-time // applications, Linux supports SCHED_RR which allows static priority (1-99). // However, for large multi-threaded applications, SCHED_RR is not only slower // than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out // of 5 runs - Sep 2005). // // The following code actually changes the niceness of kernel-thread/LWP. It // has an assumption that setpriority() only modifies one kernel-thread/LWP, // not the entire user process, and user level threads are 1:1 mapped to kernel // threads. It has always been the case, but could change in the future. For // this reason, the code should not be used as default (ThreadPriorityPolicy=0). // It is only used when ThreadPriorityPolicy=1 and requires root privilege. 

...

Later on, we see:

static int prio_init() {   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;     }   }    if (UseCriticalJavaThreadPriority) {     os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];   }    return 0; } 

...

And subsequently:

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; } 

So! At least on Sun Java, on Linux, you won't see thread priorities unless you have done -XX:ThreadPriorityPolicy and that seems to require root.

like image 55
Adam Goode Avatar answered Oct 20 '22 03:10

Adam Goode