typealias Block = () -> Void
typealias Queue = [Block]
var fastQueue = Queue()
var slowQueue = Queue()
let scheduleQueue = DispatchQueue(label: "schedule")
let workQueue = DispatchQueue(label: "work")
let lock = DispatchGroup()
func scheduleSlow(block: @escaping Block) {
scheduleQueue.async {
slowQueue.insert(block, at: 0)
scheduleQueue.async() {
next()
}
}
}
func scheduleFast(block: @escaping Block) {
scheduleQueue.async {
fastQueue.insert(block, at: 0)
scheduleQueue.async() {
next()
}
}
}
private func next() {
lock.wait()
guard let block = fastQueue.popLast() ?? slowQueue.popLast() else {
// Nothing to do
return
}
lock.enter()
workQueue.async {
block()
lock.leave()
}
}
workQueue.suspend()
var buffer = [String]()
let group = DispatchGroup()
for i in 0 ..< 10 {
group.enter()
scheduleSlow {
for i in 0 ..< 1_000_000 {
}
buffer.append("slow #\(i)")
group.leave()
}
group.enter()
scheduleFast {
for i in 0 ..< 1_000_000 {
}
buffer.append("fast #\(i)")
group.leave()
}
}
workQueue.resume()
group.wait()
print(buffer.joined(separator: "\n"))