[Jack-Devel] JACK thread priorities on different OSes (Was: Installers for Jack 1.9.8...)

PrevNext  Index
DateThu, 12 May 2011 00:20:32 -0600
From David Nielson <[hidden] at comcast dot net>
To[hidden] at lists dot jackaudio dot org
In-Reply-ToStéphane Letz Re: [Jack-Devel] Installers for Jack 1.9.8 (SVN 4384) for Windows 64 and 32 bits
Follow-UpTommaso Cucinotta Re: [Jack-Devel] JACK thread priorities on different OSes (Was: Installers for Jack 1.9.8...)
On 05/12/2011 12:13 AM, Stéphane Letz wrote:
> Le 12 mai 2011 à 03:31, Devin Anderson a écrit :
>
>> On Wed, May 11, 2011 at 2:54 AM, Stéphane Letz<[hidden]>  wrote:
>>
>>> That seems a good "theoritical" idea, but I'm still not sure it can be done
>>> in practice.
>> Right now, save for Linux, thread priorities aren't really *used* in
>> practice, or the way that it is done is sub-par.
>>
>> On Windows, if the priority is>= 90 and MMCSS is available (Vista,
>> Windows 7), then an MMCSS priority is set; otherwise, the thread is
>> set with a priority of 'THREAD_PRIORITY_TIME_CRITICAL':
>>
>>     http://trac.jackaudio.org/browser/jack2/trunk/jackmp/windows/JackWinThread.cpp#L201
>>
>> ... meaning that when a thread requests a priority of 90 or above, it
>> *might* have a priority that's higher than other threads, or it might
>> just have the same thread priority as every other thread that asks for
>> a realtime priority, which defeats the purpose of having thread
>> priorities, since JACK 2 doesn't deal with Windows process priorities.
>>
>> On OSX, the priority you request doesn't even figure into the what happens:
>>
>>     http://trac.jackaudio.org/browser/jack2/trunk/jackmp/macosx/JackMachThread.cpp#L188
>>
>> There is, however, an OS-specific method you can call to set thread
>> parameters called 'SetParams':
>>
>>     http://trac.jackaudio.org/browser/jack2/trunk/jackmp/macosx/JackMachThread.cpp#L222
>>
>> ... which has a usage that isn't exactly clear.
>>
>> Currently, the only platform for which the current thread priority
>> implementation makes sense is Linux.  Even then, it isn't really clear
>> when a thread should request a certain priority in JACK.  There's no
>> documentation suggesting that, for example, if you're writing a MIDI
>> driver and you want your hardware output thread(s) to be able to
>> deliver MIDI messages via hardware with reasonably accurate timing,
>> then you should set your thread priority in this or that manner.
>>
>> What I'm suggesting is that the thread priorities in JACK 2 be changed
>> so that they accept a priority related to the type of job the thread
>> will do:
>>
>> enum JackThreadPriority {
>>    // JACK audio thread
>>    PRIORITY_AUDIO,
>>    // JACK callbacks
>>    PRIORITY_CALLBACK,
>>    // JACK MIDI thread that communicates directly with hardware
>>    PRIORITY_MIDI_TERMINAL,
>>
>>    // More priorities here ...
>> };
>>
>> ... or maybe a constant that suggests what sort of priority is necessary:
>>
>> enum JackThreadPriority {
>>     PRIORITY_LOW,
>>     PRIORITY_NORMAL,
>>     PRIORITY_HIGH,
>>     PRIORITY_CRITICAL,
>>     // More priorities here ...
>> };
>>
>> ... and that the underlying OS implementation does the right thing
>> with the given thread priority.
>>
>>> The thing is that on each system JACK2 runs on, the
>>> underlying scheduling system is different, especially for real-time
>>> threads. POSIX system (Linux, Solaris) are probably the most flexible
>>> (with a precise setup of priority), but on OSX there is only a single class
>>> for RT threads and RT thread interleaving can be "somewhat" controled.
>>> On Windows the situation seems even worse, and I still don't know if
>>> there is a way to setup different classes of RT threads, and control
>>> thread interleaving the correct way. The situation is maybe only:
>>> Windows in not an OS suitable for "hard" RT stuff...
>> Regardless of whether or not Windows is not a suitable OS for RT stuff
>> (and I certainly don't believe it is), I think that a system like this
>> could be used to try to make things as usable as possible.
>>
>> Here's a brief idea for Windows thread priorities:
>>
>> 1.) Alter the -P switch to set the *process* priority instead of the
>> realtime thread priorities.
>> 2.) Map job priorities to Windows thread priorities:
>>
>>     PRIORITY_AUDIO: THREAD_PRIORITY_HIGHEST
>>     PRIORITY_CALLBACK: THREAD_PRIORITY_NORMAL
>>     PRIORITY_MIDI_TERMINAL: THREAD_PRIORITY_TIME_CRITICAL
>>
>>     ... etc.
>>
>> These values might not be the correct values, but they can be tweaked
>> to do the right thing on Windows.
>>
>> On Linux, you might map priority constants relative to the -P switch value:
>>
>>     PRIORITY_AUDIO: P
>>     PRIORITY_CALLBACK: P - 1
>>     PRIORITY_MIDI_TERMINAL: P + 1
>>
>> I don't understand OSX's 'thread_policy_set' function, but I'm sure
>> something similar can be done.
>>
>> I think a system like this would make it easier and clearer to set
>> priorities for JACK 2 threads.
>>
>> -- 
> We can certainly makes thing clearer at JACK implementation level, define some enum, but the point is to see if we can then find a  suitable "mapping" to the real stuff on each system:
>
> - I'm really not sure touching the "process" priority class on WIndows with the -P value (http://msdn.microsoft.com/en-us/library/ms685100(v=vs.85).aspx) is the way to go, since (AFAICS) it touches *all threads* in the given process, and this is not what we want. We would want to setup what happens for the RT thread (Audio, possibly MIDI...) only and not the others ones.
>
> - concerning OSX: as I said there is no priority setting in the RT class. But this is more "reservation" like approach, Basically a period, a "uninteruptible computation grain", and a "constraint" (which is basically equals to the period. Periodic tasks (like the audio ones) have to defines their period, MIDI task don"t need that (period = 0). Then the "uninteruptible computation grain", is the way to "control" RT thread interleaving, but this is done in a quite ad-hoc way. Basically CoreAudio guys have defined different values of this computation grain for the different buffer sizes, and that is all!
>
> What JACK2 does is just to *read* the values that the CoreAudio audio thread is using (so on server side), and just use use them on client side for all RT audio threads. So that all RT audio threads in the JACK context share the same setting, which makes sense since they are all running at the same buffer size. The MIDI thread have a specific setting (see JackCoreMidiOutputPort::Init()) , again by just looking at what CoreMIDI does, and using the same values....
>
> So if we define an enum for thread in JACK level, we can map it to priority values on POSIX, but I guess we'll keep the ad-hoc way on OSX, and the other ad-hoc way on Windows (MMCSS when available and so on...)
>
> What else?
>
> Stéphane
This thread has drifted very far from its original content. I suggest 
changing the subject line to something more fitting...

David Nielson
PrevNext  Index

1305181257.3144_0.ltw:2,a <4DCB7C30.8070000 at comcast dot net>