mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Iterating child tasks depends on knowing the size of AsyncTask, and changing the size of the task broke it. Instead of relying on mirroring the full structure in our out-of-process definitions, add a debug variable to libswift_Concurrency that contains the size of AsyncTask. While we're there, add some more validation to child task enumeration. Check each child task's metadata pointer to make sure that it actually points to the AsyncTask metadata, and have the inner loop also increment and check ChildTaskLoopCount to stop runaway iteration in that loop.
103 lines
3.1 KiB
Swift
103 lines
3.1 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-clang -x c %S/Inputs/reflect_task.c -o %t/reflect_task.c.o -c
|
|
// RUN: %target-build-swift -c -target %target-swift-5.1-abi-triple -parse-stdlib -parse-as-library -lswiftSwiftReflectionTest %s -o %t/reflect_task.swift.o -module-name reflect_task
|
|
// RUN: %target-build-swift %t/reflect_task.swift.o %t/reflect_task.c.o -o %t/reflect_task
|
|
// RUN: %target-codesign %t/reflect_task
|
|
|
|
// RUN: %target-run %target-swift-reflection-test %t/reflect_task | %FileCheck %s --dump-input=fail
|
|
|
|
// REQUIRES: reflection_test_support
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: concurrency
|
|
// UNSUPPORTED: use_os_stdlib
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
// UNSUPPORTED: asan
|
|
|
|
import Swift
|
|
import _Concurrency
|
|
|
|
import SwiftReflectionTest
|
|
|
|
// We do not use swift_task_getCurrent directly since we also can get a
|
|
// declaration (if we get unlucky) from _Concurrency with a differing type. So
|
|
// we instead just compile a shim in a .c file that actually calls
|
|
// swift_task_getCurrent and avoid the collision.
|
|
@_silgen_name("getCurrentTaskShim")
|
|
func _getCurrentTaskShim() -> UInt
|
|
|
|
func add(_ a: UInt, _ b: UInt) async -> UInt {
|
|
if b == 0 {
|
|
reflect(asyncTask: _getCurrentTaskShim())
|
|
return a
|
|
} else {
|
|
return await add(a, b - 1) + 1
|
|
}
|
|
}
|
|
|
|
func sleepForever() async -> Int {
|
|
if #available(SwiftStdlib 5.7, *) {
|
|
try? await Task.sleep(for: .seconds(1_000_000_000))
|
|
return 42
|
|
} else {
|
|
fatalError("This test shouldn't be running against old stdlibs.")
|
|
}
|
|
}
|
|
|
|
func testNestedCallsTask() async {
|
|
reflectionLog(str: "testNestedCallsTask")
|
|
// CHECK: testNestedCallsTask
|
|
|
|
let n = await add(100, 100)
|
|
reflect(any: n)
|
|
// CHECK: Reflecting an async task.
|
|
// CHECK: Async task {{0x[0-9a-fA-F]*}}
|
|
|
|
// The actual number of chunks we'll get depends on internal implementation
|
|
// details that we don't want this test to depend on. We'll just make sure
|
|
// we get at least two, and ignore the details.
|
|
// CHECK: Slab pointer {{0x[0-9a-fA-F]*}}
|
|
// CHECK: Slab size {{[0-9]{2,}()}}
|
|
// CHECK: Chunk at {{0x[0-9a-fA-F]*}} length {{[1-9][0-9]*}} kind {{[0-9]*}}
|
|
// CHECK: Slab pointer {{0x[0-9a-fA-F]*}}
|
|
// CHECK: Slab size {{[0-9]{2,}()}}
|
|
// CHECK: Chunk at {{0x[0-9a-fA-F]*}} length {{[1-9[[0-9]*}} kind {{[0-9]*}}
|
|
}
|
|
|
|
func testOneAsyncLet() async {
|
|
reflectionLog(str: "testOneAsyncLet")
|
|
// CHECK: testOneAsyncLet
|
|
|
|
async let alet = sleepForever()
|
|
reflect(asyncTask: _getCurrentTaskShim())
|
|
// CHECK: Async task {{0x[0-9a-fA-F]*}}
|
|
// CHECK: children = {
|
|
// CHECK: Async task {{0x[0-9a-fA-F]*}}
|
|
// CHECK: }
|
|
}
|
|
|
|
func testMultipleAsyncLet() async {
|
|
reflectionLog(str: "testMultipleAsyncLet")
|
|
// CHECK: testMultipleAsyncLet
|
|
|
|
async let alet1 = sleepForever()
|
|
async let alet2 = sleepForever()
|
|
reflect(asyncTask: _getCurrentTaskShim())
|
|
// CHECK: Async task {{0x[0-9a-fA-F]*}}
|
|
// CHECK: children = {
|
|
// CHECK: Async task {{0x[0-9a-fA-F]*}}
|
|
// CHECK: Async task {{0x[0-9a-fA-F]*}}
|
|
// CHECK: }
|
|
}
|
|
|
|
@main struct Main {
|
|
static func main() async {
|
|
await testNestedCallsTask()
|
|
await testOneAsyncLet()
|
|
await testMultipleAsyncLet()
|
|
|
|
doneReflecting()
|
|
}
|
|
}
|
|
|
|
// CHECK: Done.
|