Topic: Real time priority and nice on Linux
tl;dr According to my experience and investigation there's no need to manually run Pianoteq with elevated priorities on Linux. As long as /etc/security/limits.conf is set correctly as advised in README_LINUX.txt, Pianoteq is going to set the needed priorities on its own.
I recently got hold of a 5-year old laptop and decided it to use as a dedicated machine for Pianoteq. The laptop came with Windows 7 and I initially tried to run Pianoteq on it. Despite my previous positive experience with Pianoteq on Windows running on my other laptop, I failed to get it to work reasonably well. Windows annoyed me with stuff running in the background that was stealing CPU cycles randomly.
So I decided to go for Linux. I downloaded AV Linux, which seems to be a nice and lightweight distribution with kernel optimized for low latency. I also did a bit of research regarding setting up Linux for Pianoteq. On the forum I found advice to give Pianoteq real time priority by running it through chrt or to give it the regular nice priority. I initially followed the advice to use chrt. However, I was still hitting some issues with clicks and pops. I am not entirely sure what resolved the issue, because I was trying different things. However, I ended up running Pianoteq without any elevated priorities and no issues at all.
I started digging a bit more and figured out that Pianoteq complains about not being able to set real-time priorities when /etc/security/limits.conf is not set up properly. I decided to check the scheduling policy and priorities of all Pianoteq threads when it is started without chrt or nice, but with proper limits.conf. It turns out that some of the threads do run with SCHED_RR, which is a real-time scheduling policy. Also, they have priorities varying from 65 to 90. There are 3 threads under the regular SCHED_OTHER policy with the default nice of 0.
[michal 22:01 amd64]$ ps -e -T -opid,spid,policy,rtprio,nice,cmd | grep Pianoteq
4636 4636 TS - 0 ./Pianoteq 5
4636 4643 RR 90 - ./Pianoteq 5
4636 5269 RR 65 - ./Pianoteq 5
4636 5271 RR 69 - ./Pianoteq 5
4636 5281 TS - 0 ./Pianoteq 5
4636 5282 RR 65 - ./Pianoteq 5
4636 5283 TS - 0 ./Pianoteq 5
I went to gdb to see roughly what the threads are doing:
7 Thread 0x7f84165bd700 (LWP 4643) "Juce MIDI Input" 0x00007f841e85dfdd in poll () at ../sysdeps/unix/syscall-template.S:81
6 Thread 0x7f84151af700 (LWP 5269) "Pianoteq" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
5 Thread 0x7f84149ae700 (LWP 5271) "Juce Timer" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:193
4 Thread 0x7f84175bf700 (LWP 5281) "threaded-ml" 0x00007f841e85dfdd in poll () at ../sysdeps/unix/syscall-template.S:81
3 Thread 0x7f8416dbe700 (LWP 5282) "Juce ALSA" 0x00007f841e85dfdd in poll () at ../sysdeps/unix/syscall-template.S:81
2 Thread 0x7f84159b0700 (LWP 5283) "Pianoteq" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
* 1 Thread 0x7f8420645780 (LWP 4636) "Pianoteq" 0x00007f841e862c53 in select () at ../sysdeps/unix/syscall-template.S:81
If you match the output from ps and gdb you get the following:
RR 90 "Juce MIDI Input"
RR 65 "Pianoteq"
RR 69 "Juce Timer"
TS 0 "threaded-ml"
RR 65 "Juce ALSA"
TS 0 "Pianoteq"
TS 0 main()
In my opinion, it indicates that Pianoteq and its developers know what they are doing. The threads that do the real work get RR priority, while e.g. the main() thread does not. Even more interesting are the varying priority values. They may be tuned to make it work even better e.g. get the MIDI messages earlier to get the sound generation to work ASAP.
If I run Pianoteq with chrt -r 88 as suggested in another thread, threads get the following priorities:
[michal 00:45 amd64]$ ps -e -T -opid,spid,policy,rtprio,nice,cmd | grep Pianoteq
8297 8297 RR 88 - ./Pianoteq 5
8297 8300 RR 88 - ./Pianoteq 5
8297 8301 RR 65 - ./Pianoteq 5
8297 8302 RR 90 - ./Pianoteq 5
8297 8926 RR 65 - ./Pianoteq 5
8297 8927 RR 88 - ./Pianoteq 5
8297 8928 RR 69 - ./Pianoteq 5
Consequently, the main() thread gets a higher priority than the thread responsible for ALSA. I believe this is not a optimal solution.
So to me it seems that it may even be detrimental to fiddle with Pianoteq's priority on Linux. I think setting up limits.conf is just enough. I would love to hear a bit more about it from the developers