Skip to content

Commit dafb574

Browse files
committed
Switch task group child task creation over to Builtin.createAsyncTask().
Extend the behavior of `swift_task_create_common` to also encompass adding the pending group task (when requested) and attaching it to the group.
1 parent a61adac commit dafb574

File tree

4 files changed

+112
-70
lines changed

4 files changed

+112
-70
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,11 +2029,12 @@ class TaskCreateFlags : public FlagSet<size_t> {
20292029
Priority = 0,
20302030
Priority_width = 8,
20312031

2032-
Task_IsChildTask = 8,
2033-
Task_IsAsyncLetTask = 9,
2034-
Task_CopyThreadLocals = 10,
2035-
Task_InheritContext = 11,
2036-
Task_EnqueueJob = 12,
2032+
Task_IsChildTask = 8,
2033+
Task_IsAsyncLetTask = 9,
2034+
Task_CopyThreadLocals = 10,
2035+
Task_InheritContext = 11,
2036+
Task_EnqueueJob = 12,
2037+
Task_AddPendingGroupTaskUnconditionally = 13,
20372038
};
20382039

20392040
explicit constexpr TaskCreateFlags(size_t bits) : FlagSet(bits) {}
@@ -2056,6 +2057,9 @@ class TaskCreateFlags : public FlagSet<size_t> {
20562057
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_EnqueueJob,
20572058
enqueueJob,
20582059
setEnqueueJob)
2060+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_AddPendingGroupTaskUnconditionally,
2061+
addPendingGroupTaskUnconditionally,
2062+
setAddPendingGroupTaskUnconditionally)
20592063
};
20602064

20612065
/// Flags for schedulable jobs.

stdlib/public/Concurrency/Task.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,12 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
445445
}
446446
}
447447

448+
// Add to the task group, if requested.
449+
if (taskCreateFlags.addPendingGroupTaskUnconditionally()) {
450+
assert(group && "Missing group");
451+
swift_taskGroup_addPending(group, /*unconditionally=*/true);
452+
}
453+
448454
AsyncTask *parent = nullptr;
449455
if (jobFlags.task_isChildTask()) {
450456
parent = swift_task_getCurrent();
@@ -611,6 +617,11 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
611617
initialContext->Flags = AsyncContextKind::Ordinary;
612618
initialContext->Flags.setShouldNotDeallocateInCallee(true);
613619

620+
// Attach to the group, if needed.
621+
if (group) {
622+
swift_taskGroup_attachChild(group, task);
623+
}
624+
614625
// If we're supposed to copy task locals, do so now.
615626
if (taskCreateFlags.copyThreadLocals()) {
616627
swift_task_localsCopyTo(task);

stdlib/public/Concurrency/Task.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,22 @@ struct TaskCreateFlags {
468468
}
469469
}
470470
}
471+
472+
/// Whether to add a pending group task unconditionally as part of creating
473+
/// the task.
474+
var addPendingGroupTaskUnconditionally: Bool {
475+
get {
476+
(bits & (1 << 13)) != 0
477+
}
478+
479+
set {
480+
if newValue {
481+
bits = bits | 1 << 13
482+
} else {
483+
bits = (bits & ~(1 << 13))
484+
}
485+
}
486+
}
471487
}
472488

473489
// ==== Task Creation ----------------------------------------------------------
@@ -774,6 +790,60 @@ extension UnsafeCurrentTask: Equatable {
774790

775791
// ==== Internal ---------------------------------------------------------------
776792

793+
@available(SwiftStdlib 5.5, *)
794+
struct TaskOptionRecord {
795+
// The kind of option record.
796+
enum Kind: UInt8 {
797+
case executor = 0
798+
case taskGroup = 1
799+
}
800+
801+
// Flags stored within an option record.
802+
struct Flags {
803+
var bits: Int = 0
804+
805+
init(kind: Kind) {
806+
self.bits = 0
807+
self.kind = kind
808+
}
809+
810+
/// The kind of option record described by these flags.
811+
var kind: Kind {
812+
get {
813+
Kind(rawValue: UInt8(bits & 0xFF))!
814+
}
815+
816+
set {
817+
bits = (bits & ~0xFF) | Int(newValue.rawValue)
818+
}
819+
}
820+
}
821+
822+
var flags: Flags
823+
var parent: UnsafeMutablePointer<TaskOptionRecord>? = nil
824+
825+
init(kind: Kind, parent: UnsafeMutablePointer<TaskOptionRecord>? = nil) {
826+
self.flags = Flags(kind: kind)
827+
self.parent = parent
828+
}
829+
}
830+
831+
@available(SwiftStdlib 5.5, *)
832+
extension TaskOptionRecord {
833+
struct TaskGroup {
834+
var base: TaskOptionRecord
835+
var group: Builtin.RawPointer
836+
837+
init(
838+
parent: UnsafeMutablePointer<TaskOptionRecord>? = nil,
839+
group: Builtin.RawPointer
840+
) {
841+
self.base = .init(kind: .taskGroup, parent: parent)
842+
self.group = group
843+
}
844+
}
845+
}
846+
777847
@available(SwiftStdlib 5.5, *)
778848
@_silgen_name("swift_task_getCurrent")
779849
func _getCurrentAsyncTask() -> Builtin.NativeObject?

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -211,25 +211,16 @@ public struct TaskGroup<ChildTaskResult> {
211211
priority: TaskPriority? = nil,
212212
operation: __owned @Sendable @escaping () async -> ChildTaskResult
213213
) {
214-
_ = _taskGroupAddPendingTask(group: _group, unconditionally: true)
215-
216-
// Set up the job flags for a new task.
217-
var flags = JobFlags()
218-
flags.kind = .task
214+
var flags = TaskCreateFlags()
219215
flags.priority = priority
220-
flags.isFuture = true
221216
flags.isChildTask = true
222-
flags.isGroupChildTask = true
223-
224-
// Create the asynchronous task future.
225-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
226-
Int(flags.bits), _group, /*options*/nil, operation)
217+
flags.enqueueJob = true
218+
flags.addPendingGroupTaskUnconditionally = true
227219

228-
// Attach it to the group's task record in the current task.
229-
_taskGroupAttachChild(group: _group, child: childTask)
220+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
230221

231-
// Enqueue the resulting job.
232-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
222+
// Create the asynchronous task future.
223+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
233224
}
234225

235226
/// Add a child task to the group.
@@ -258,23 +249,15 @@ public struct TaskGroup<ChildTaskResult> {
258249
return false
259250
}
260251

261-
// Set up the job flags for a new task.
262-
var flags = JobFlags()
263-
flags.kind = .task
252+
var flags = TaskCreateFlags()
264253
flags.priority = priority
265-
flags.isFuture = true
266254
flags.isChildTask = true
267-
flags.isGroupChildTask = true
255+
flags.enqueueJob = true
268256

269-
// Create the asynchronous task future.
270-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
271-
Int(flags.bits), _group, /*options*/nil, operation)
257+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
272258

273-
// Attach it to the group's task record in the current task.
274-
_taskGroupAttachChild(group: _group, child: childTask)
275-
276-
// Enqueue the resulting job.
277-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
259+
// Create the asynchronous task future.
260+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
278261

279262
return true
280263
}
@@ -453,26 +436,16 @@ public struct ThrowingTaskGroup<ChildTaskResult, Failure: Error> {
453436
priority: TaskPriority? = nil,
454437
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
455438
) {
456-
// we always add, so no need to check if group was cancelled
457-
_ = _taskGroupAddPendingTask(group: _group, unconditionally: true)
458-
459-
// Set up the job flags for a new task.
460-
var flags = JobFlags()
461-
flags.kind = .task
439+
var flags = TaskCreateFlags()
462440
flags.priority = priority
463-
flags.isFuture = true
464441
flags.isChildTask = true
465-
flags.isGroupChildTask = true
442+
flags.enqueueJob = true
443+
flags.addPendingGroupTaskUnconditionally = true
466444

467-
// Create the asynchronous task future.
468-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
469-
Int(flags.bits), _group, /*options*/nil, operation)
445+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
470446

471-
// Attach it to the group's task record in the current task.
472-
_taskGroupAttachChild(group: _group, child: childTask)
473-
474-
// Enqueue the resulting job.
475-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
447+
// Create the asynchronous task future.
448+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
476449
}
477450

478451
/// Add a child task to the group.
@@ -501,23 +474,15 @@ public struct ThrowingTaskGroup<ChildTaskResult, Failure: Error> {
501474
return false
502475
}
503476

504-
// Set up the job flags for a new task.
505-
var flags = JobFlags()
506-
flags.kind = .task
477+
var flags = TaskCreateFlags()
507478
flags.priority = priority
508-
flags.isFuture = true
509479
flags.isChildTask = true
510-
flags.isGroupChildTask = true
511-
512-
// Create the asynchronous task future.
513-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
514-
Int(flags.bits), _group, /*options*/nil, operation)
480+
flags.enqueueJob = true
515481

516-
// Attach it to the group's task record in the current task.
517-
_taskGroupAttachChild(group: _group, child: childTask)
482+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
518483

519-
// Enqueue the resulting job.
520-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
484+
// Create the asynchronous task future.
485+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
521486

522487
return true
523488
}
@@ -746,14 +711,6 @@ extension ThrowingTaskGroup: AsyncSequence {
746711

747712
/// ==== -----------------------------------------------------------------------
748713

749-
/// Attach task group child to the group group to the task.
750-
@available(SwiftStdlib 5.5, *)
751-
@_silgen_name("swift_taskGroup_attachChild")
752-
func _taskGroupAttachChild(
753-
group: Builtin.RawPointer,
754-
child: Builtin.NativeObject
755-
)
756-
757714
@available(SwiftStdlib 5.5, *)
758715
@_silgen_name("swift_taskGroup_destroy")
759716
func _taskGroupDestroy(group: __owned Builtin.RawPointer)

0 commit comments

Comments
 (0)