Qos_class_self()


(Drew Crawford) #1

On Darwin, we have the function qos_class_self(), that we use to find out the QOS of the current queue.

On Linux, this function seems not available.

Googling suggests qos_class_self comes via libpthread, which might not (?) be the libdispatch implementation on Linux?

Is there a way to portably create a queue with the current QOS?

Drew


(Daniel A. Steffen) #2

Hi Drew,

On Darwin, we have the function qos_class_self(), that we use to find out the QOS of the current queue.

please note that qos_class_self() does _not_ return the QoS of the current queue, it returns the QoS of the current thread, which is quite different, whatever is running on the queue can have changed the QoS, including the attributes of the block itself, if any (possibly automatically propagated from the submitting thread and applied by libdispatch).

On Linux, this function seems not available.

Googling suggests qos_class_self comes via libpthread, which might not (?) be the libdispatch implementation on Linux?

Is there a way to portably create a queue with the current QOS?

QoS itself in its current form is not portable at present and as you say indeed provided by libpthread on Darwin platforms and not libdispatch.

if we need it to be, it might make sense to add support for some of the QoS accessor APIs to the libdispatch Linux port, but I’m not convinced we should be replicating any of the related non-portable functionality until QoS works on Linux more generally (in particular QoS overrides would need kernel support and without that, support for QoS in libdispatch doesn’t make very much sense in the first place given that it will just lead to priority inversions).

Daniel

···

On Feb 6, 2016, at 17:39, Drew Crawford via swift-corelibs-dev <swift-corelibs-dev@swift.org> wrote:


(Drew Crawford) #3

I would argue that we should stub qos_class_self now, and decide how to implement it later.

This is because I use the API defensively, e.g. here is a real example:

        //ensure that the operation does not exceed the current priority
        dispatch_async(dispatch_get_global_queue(qos_class_self(), 0)) {[unowned self] () -> Void in
            self.readMessageIntoBuffer()
        }

If QOS is not implemented, then this codelisting is still correct.

However if QOS becomes implemented someday, and I have in the meantime rewritten this code not to use qos_class_self (because it wasn't available) then the code is probably incorrect, because it no longer avoids the priority inversion.

In other words, I think there is value in giving GCD this information even if it isn't prepared to make use of it. When it someday becomes prepared, programs will already be compatible.

···

On Feb 8, 2016, at 1:00 PM, Daniel A. Steffen <dsteffen@apple.com> wrote:

if we need it to be, it might make sense to add support for some of the QoS accessor APIs to the libdispatch Linux port, but I’m not convinced we should be replicating any of the related non-portable functionality until QoS works on Linux more generally (in particular QoS overrides would need kernel support and without that, support for QoS in libdispatch doesn’t make very much sense in the first place given that it will just lead to priority inversions).


(Daniel A. Steffen) #4

if we need it to be, it might make sense to add support for some of the QoS accessor APIs to the libdispatch Linux port, but I’m not convinced we should be replicating any of the related non-portable functionality until QoS works on Linux more generally (in particular QoS overrides would need kernel support and without that, support for QoS in libdispatch doesn’t make very much sense in the first place given that it will just lead to priority inversions).

I would argue that we should stub qos_class_self now, and decide how to implement it later.

This is because I use the API defensively, e.g. here is a real example:

        //ensure that the operation does not exceed the current priority
        dispatch_async(dispatch_get_global_queue(qos_class_self(), 0)) {[unowned self] () -> Void in
            self.readMessageIntoBuffer()
        }

on Darwin, dispatch_async does this for you already if you use the default global queue, there is no need to specify this information in this way (dispatch_async propagates QoS automatically and applies it if the queue submitted to has unspecified QoS or is the default global queue)

···

On Feb 8, 2016, at 13:10, Drew Crawford <drew@sealedabstract.com> wrote:

On Feb 8, 2016, at 1:00 PM, Daniel A. Steffen <dsteffen@apple.com <mailto:dsteffen@apple.com>> wrote:

If QOS is not implemented, then this codelisting is still correct.

However if QOS becomes implemented someday, and I have in the meantime rewritten this code not to use qos_class_self (because it wasn't available) then the code is probably incorrect, because it no longer avoids the priority inversion.

In other words, I think there is value in giving GCD this information even if it isn't prepared to make use of it. When it someday becomes prepared, programs will already be compatible.