1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking %import-libdispatch -parse-as-library )
// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: libdispatch
// rdar://76038845
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
// UNSUPPORTED: back_deploy_concurrency
// rdar://101077408 – Temporarily disable on watchOS & iOS simulator
// UNSUPPORTED: DARWIN_SIMULATOR=watchos
// UNSUPPORTED: DARWIN_SIMULATOR=ios
// UNSUPPORTED: DARWIN_SIMULATOR=tvos
// UNSUPPORTED: single_threaded_concurrency
import StdlibUnittest
import Dispatch
#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#elseif canImport(Android)
import Android
#elseif os(WASI)
import WASILibc
#elseif os(Windows)
import CRT
import WinSDK
#endif
func loopUntil(priority: TaskPriority) async {
while (Task.currentPriority != priority) {
await Task.sleep(1_000_000_000)
}
}
func print(_ s: String = "") {
fputs("\(s)\n", stderr)
}
func expectedBasePri(priority: TaskPriority) -> TaskPriority {
let basePri = Task.basePriority!
print("Testing basePri matching expected pri - \(basePri) == \(priority)")
expectEqual(basePri, priority)
return basePri
}
func expectedCurrentPri(priority: TaskPriority) -> TaskPriority {
let curPri = Task.currentPriority
print("Testing curPri matching expected pri - \(curPri) == \(priority)")
expectEqual(curPri, priority)
return curPri
}
func testNestedTaskPriority(basePri: TaskPriority, curPri: TaskPriority) async {
let _ = expectedBasePri(priority: basePri)
let _ = expectedCurrentPri(priority: curPri)
}
@main struct Main {
static func main() async {
let top_level = detach { /* To detach from main actor when running work */
let tests = TestSuite("Task base priority")
if #available(SwiftStdlib 5.1, *) {
tests.test("Structured concurrency base priority propagation") {
let task = Task(priority: .background) {
await loopUntil(priority: .default)
let basePri = expectedBasePri(priority: .background)
let curPri = expectedCurrentPri(priority: .default)
// Structured concurrency via async let, escalated priority of
// parent should propagate
print("Testing propagation for async let structured concurrency child")
async let child = testNestedTaskPriority(basePri: basePri, curPri: curPri)
await child
let dispatchGroup = DispatchGroup()
// Structured concurrency via task groups, escalated priority should
// propagate
await withTaskGroup(of: Void.self, returning: Void.self) { group in
dispatchGroup.enter()
group.addTask {
print("Testing propagation for task group regular child")
let _ = await testNestedTaskPriority(basePri: basePri, curPri: curPri)
dispatchGroup.leave()
return
}
dispatchGroup.enter()
group.addTask(priority: .utility) {
print("Testing propagation for task group child with specified priority")
let _ = await testNestedTaskPriority(basePri: .utility, curPri: curPri)
dispatchGroup.leave()
return
}
// Wait for child tasks to finish running, don't await since that
// will escalate them
dispatchGroup.wait()
}
}
await task.value // Escalate task BG->DEF
}
tests.test("Unstructured base priority propagation") {
let task = Task(priority : .background) {
await loopUntil(priority: .default)
let basePri = expectedBasePri(priority: .background)
let _ = expectedCurrentPri(priority: .default)
let group = DispatchGroup()
// Create an unstructured task
group.enter()
let _ = Task {
let _ = await testNestedTaskPriority(basePri: basePri, curPri: basePri)
group.leave()
return
}
// Wait for unstructured task to finish running, don't await it
// since that will escalate
group.wait()
}
await task.value // Escalate task BG->DEF
}
}
await runAllTestsAsync()
}
await top_level.value
}
}
|