swiftlang / swift-corelibs-libdispatch

The libdispatch Project, (a.k.a. Grand Central Dispatch), for concurrency on multicore hardware
swift.org
Apache License 2.0
2.47k stars 460 forks source link

bug: There is no way to get current queue / current queue label under Linux #813

Open mman opened 8 months ago

mman commented 8 months ago

To aid in debugging of multi threaded / multi queue code it is at times useful to obtain a label of the current dispatch queue where a piece of code is executing.

This has been possible using a hacky solution documented by Quinn here:

https://developer.apple.com/forums/thread/701313

And although this works nicely under macOS and iOS, it does not compile under Linux.

import Dispatch

let queue = DispatchQueue(label: "hello-cruel-world")

func main() {
    queue.async {
        print("DispatchQueue.label: \(queue.label)")
        print("dqgl: \(String(cString: __dispatch_queue_get_label(nil)))")
        exit(0)
    }
    dispatchMain()
}

main()
q.swift:8:40: error: cannot find '__dispatch_queue_get_label' in scope
        print("dqgl: \(String(cString: __dispatch_queue_get_label(nil)))")
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~
q.swift:8:67: error: 'nil' requires a contextual type
        print("dqgl: \(String(cString: __dispatch_queue_get_label(nil)))")
                                                                  ^

Alternatively, or yet better, it may be good to offer an API to get current queue where a piece of code is executing, as from the current queue we can get the label easily.

Please accept my apology if I am missing an obvious way how to achieve this.

rokhinip commented 7 months ago

Alternatively, or yet better, it may be good to offer an API to get current queue where a piece of code is executing, as from the current queue we can get the label easily.

There is dispatch_get_current_queue() which is deprecated because a piece of code can be executing on multiple queues at once (eg. dispatch_sync()). What behaviour are you expecting when this is the case?

The queue label is not always guaranteed to be at the same offset inside the queue structure so I wouldn't recommend doing hacky things to get them.

mman commented 7 months ago

Alternatively, or yet better, it may be good to offer an API to get current queue where a piece of code is executing, as from the current queue we can get the label easily.

There is dispatch_get_current_queue() which is deprecated because a piece of code can be executing on multiple queues at once (eg. dispatch_sync()). What behaviour are you expecting when this is the case?

If I understand the problem correctly, then multiple nested dispatch_sync calls the queue object should be the one where the code was submitted latest... or when I am "now"... like in this (simplified code)

let q1 = DispatchQueue("q1")
let q2 = DispatchQueue("q2")
let q3 = DispatchQueue("q3")
q1.sync {
  print("\(DispatchQueue.current.label)") // should print "q1"
  q2.sync {
    print("\(DispatchQueue.current.label)")  // should print "q2"
    q3.sync {
      print("\(DispatchQueue.current.label)") // should print "q3"
    }
  }
}

The queue label is not always guaranteed to be at the same offset inside the queue structure so I wouldn't recommend doing hacky things to get them.

That is for sure understood...