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.
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.
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.
Explanation: Thread scheduler decides the priority of the thread execution.
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'.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With