Skip to content

Commit 2f4fe57

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 ccfc9d6 commit 2f4fe57

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
@@ -440,6 +440,12 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
440440
}
441441
}
442442

443+
// Add to the task group, if requested.
444+
if (taskCreateFlags.addPendingGroupTaskUnconditionally()) {
445+
assert(group && "Missing group");
446+
swift_taskGroup_addPending(group, /*unconditionally=*/true);
447+
}
448+
443449
AsyncTask *parent = nullptr;
444450
if (jobFlags.task_isChildTask()) {
445451
parent = swift_task_getCurrent();
@@ -604,6 +610,11 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
604610
initialContext->Flags = AsyncContextKind::Ordinary;
605611
initialContext->Flags.setShouldNotDeallocateInCallee(true);
606612

613+
// Attach to the group, if needed.
614+
if (group) {
615+
swift_taskGroup_attachChild(group, task);
616+
}
617+
607618
// If we're supposed to copy task locals, do so now.
608619
if (taskCreateFlags.copyThreadLocals()) {
609620
swift_task_localsCopyTo(task);

stdlib/public/Concurrency/Task.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,22 @@ struct TaskCreateFlags {
496496
}
497497
}
498498
}
499+
500+
/// Whether to add a pending group task unconditionally as part of creating
501+
/// the task.
502+
var addPendingGroupTaskUnconditionally: Bool {
503+
get {
504+
(bits & (1 << 13)) != 0
505+
}
506+
507+
set {
508+
if newValue {
509+
bits = bits | 1 << 13
510+
} else {
511+
bits = (bits & ~(1 << 13))
512+
}
513+
}
514+
}
499515
}
500516

501517
// ==== Task Creation ----------------------------------------------------------
@@ -838,6 +854,60 @@ extension UnsafeCurrentTask: Equatable {
838854

839855
// ==== Internal ---------------------------------------------------------------
840856

857+
@available(SwiftStdlib 5.5, *)
858+
struct TaskOptionRecord {
859+
// The kind of option record.
860+
enum Kind: UInt8 {
861+
case executor = 0
862+
case taskGroup = 1
863+
}
864+
865+
// Flags stored within an option record.
866+
struct Flags {
867+
var bits: Int = 0
868+
869+
init(kind: Kind) {
870+
self.bits = 0
871+
self.kind = kind
872+
}
873+
874+
/// The kind of option record described by these flags.
875+
var kind: Kind {
876+
get {
877+
Kind(rawValue: UInt8(bits & 0xFF))!
878+
}
879+
880+
set {
881+
bits = (bits & ~0xFF) | Int(newValue.rawValue)
882+
}
883+
}
884+
}
885+
886+
var flags: Flags
887+
var parent: UnsafeMutablePointer<TaskOptionRecord>? = nil
888+
889+
init(kind: Kind, parent: UnsafeMutablePointer<TaskOptionRecord>? = nil) {
890+
self.flags = Flags(kind: kind)
891+
self.parent = parent
892+
}
893+
}
894+
895+
@available(SwiftStdlib 5.5, *)
896+
extension TaskOptionRecord {
897+
struct TaskGroup {
898+
var base: TaskOptionRecord
899+
var group: Builtin.RawPointer
900+
901+
init(
902+
parent: UnsafeMutablePointer<TaskOptionRecord>? = nil,
903+
group: Builtin.RawPointer
904+
) {
905+
self.base = .init(kind: .taskGroup, parent: parent)
906+
self.group = group
907+
}
908+
}
909+
}
910+
841911
@available(SwiftStdlib 5.5, *)
842912
@_silgen_name("swift_task_getCurrent")
843913
func _getCurrentAsyncTask() -> Builtin.NativeObject?

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -239,25 +239,16 @@ public struct TaskGroup<ChildTaskResult> {
239239
priority: TaskPriority? = nil,
240240
operation: __owned @Sendable @escaping () async -> ChildTaskResult
241241
) {
242-
_ = _taskGroupAddPendingTask(group: _group, unconditionally: true)
243-
244-
// Set up the job flags for a new task.
245-
var flags = JobFlags()
246-
flags.kind = .task
242+
var flags = TaskCreateFlags()
247243
flags.priority = priority
248-
flags.isFuture = true
249244
flags.isChildTask = true
250-
flags.isGroupChildTask = true
251-
252-
// Create the asynchronous task future.
253-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
254-
Int(flags.bits), _group, /*options*/nil, operation)
245+
flags.enqueueJob = true
246+
flags.addPendingGroupTaskUnconditionally = true
255247

256-
// Attach it to the group's task record in the current task.
257-
_taskGroupAttachChild(group: _group, child: childTask)
248+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
258249

259-
// Enqueue the resulting job.
260-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
250+
// Create the asynchronous task future.
251+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
261252
}
262253

263254
/// Add a child task to the group.
@@ -286,23 +277,15 @@ public struct TaskGroup<ChildTaskResult> {
286277
return false
287278
}
288279

289-
// Set up the job flags for a new task.
290-
var flags = JobFlags()
291-
flags.kind = .task
280+
var flags = TaskCreateFlags()
292281
flags.priority = priority
293-
flags.isFuture = true
294282
flags.isChildTask = true
295-
flags.isGroupChildTask = true
283+
flags.enqueueJob = true
296284

297-
// Create the asynchronous task future.
298-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
299-
Int(flags.bits), _group, /*options*/nil, operation)
285+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
300286

301-
// Attach it to the group's task record in the current task.
302-
_taskGroupAttachChild(group: _group, child: childTask)
303-
304-
// Enqueue the resulting job.
305-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
287+
// Create the asynchronous task future.
288+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
306289

307290
return true
308291
}
@@ -473,26 +456,16 @@ public struct ThrowingTaskGroup<ChildTaskResult, Failure: Error> {
473456
priority: TaskPriority? = nil,
474457
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
475458
) {
476-
// we always add, so no need to check if group was cancelled
477-
_ = _taskGroupAddPendingTask(group: _group, unconditionally: true)
478-
479-
// Set up the job flags for a new task.
480-
var flags = JobFlags()
481-
flags.kind = .task
459+
var flags = TaskCreateFlags()
482460
flags.priority = priority
483-
flags.isFuture = true
484461
flags.isChildTask = true
485-
flags.isGroupChildTask = true
462+
flags.enqueueJob = true
463+
flags.addPendingGroupTaskUnconditionally = true
486464

487-
// Create the asynchronous task future.
488-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
489-
Int(flags.bits), _group, /*options*/nil, operation)
465+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
490466

491-
// Attach it to the group's task record in the current task.
492-
_taskGroupAttachChild(group: _group, child: childTask)
493-
494-
// Enqueue the resulting job.
495-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
467+
// Create the asynchronous task future.
468+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
496469
}
497470

498471
/// Add a child task to the group.
@@ -521,23 +494,15 @@ public struct ThrowingTaskGroup<ChildTaskResult, Failure: Error> {
521494
return false
522495
}
523496

524-
// Set up the job flags for a new task.
525-
var flags = JobFlags()
526-
flags.kind = .task
497+
var flags = TaskCreateFlags()
527498
flags.priority = priority
528-
flags.isFuture = true
529499
flags.isChildTask = true
530-
flags.isGroupChildTask = true
531-
532-
// Create the asynchronous task future.
533-
let (childTask, _) = Builtin.createAsyncTaskGroupFuture(
534-
Int(flags.bits), _group, /*options*/nil, operation)
500+
flags.enqueueJob = true
535501

536-
// Attach it to the group's task record in the current task.
537-
_taskGroupAttachChild(group: _group, child: childTask)
502+
var groupOption = TaskOptionRecord.TaskGroup(group: _group)
538503

539-
// Enqueue the resulting job.
540-
_enqueueJobGlobal(Builtin.convertTaskToJob(childTask))
504+
// Create the asynchronous task future.
505+
_ = Builtin.createAsyncTask(flags.bits, UnsafeRawPointer(&groupOption)._rawValue, operation)
541506

542507
return true
543508
}
@@ -841,14 +806,6 @@ extension ThrowingTaskGroup: AsyncSequence {
841806

842807
/// ==== -----------------------------------------------------------------------
843808

844-
/// Attach task group child to the group group to the task.
845-
@available(SwiftStdlib 5.5, *)
846-
@_silgen_name("swift_taskGroup_attachChild")
847-
func _taskGroupAttachChild(
848-
group: Builtin.RawPointer,
849-
child: Builtin.NativeObject
850-
)
851-
852809
@available(SwiftStdlib 5.5, *)
853810
@_silgen_name("swift_taskGroup_destroy")
854811
func _taskGroupDestroy(group: __owned Builtin.RawPointer)

0 commit comments

Comments
 (0)