Skip to content

Commit 67ef887

Browse files
authored
Merge pull request swiftlang#36602 from ktoso/wip-task-revisions
[Concurrency] Update Task/TaskGroup APIs based on first review
2 parents 511b50e + 989db80 commit 67ef887

File tree

50 files changed

+1274
-582
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1274
-582
lines changed

include/swift/ABI/Task.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ class ContinuationAsyncContext : public AsyncContext {
566566
/// task.
567567
///
568568
/// This type matches the ABI of a function `<T> () async throws -> T`, which
569-
/// is the type used by `Task.runDetached` and `Task.group.add` to create
569+
/// is the type used by `detach` and `Task.group.add` to create
570570
/// futures.
571571
class FutureAsyncContext : public AsyncContext {
572572
public:

include/swift/Runtime/Concurrency.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
117117
JobPriority
118118
swift_task_escalate(AsyncTask *task, JobPriority newPriority);
119119

120+
// TODO: "async let wait" and "async let destroy" would be expressed
121+
// similar to like TaskFutureWait;
122+
120123
/// This matches the ABI of a closure `<T>(Builtin.NativeObject) async -> T`
121124
using TaskFutureWaitSignature =
122125
SWIFT_CC(swiftasync)
@@ -237,11 +240,12 @@ void swift_taskGroup_destroy(TaskGroup *group);
237240
///
238241
/// \code
239242
/// func swift_taskGroup_addPending(
240-
/// group: Builtin.RawPointer
243+
/// group: Builtin.RawPointer,
244+
/// unconditionally: Bool
241245
/// ) -> Bool
242246
/// \endcode
243247
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
244-
bool swift_taskGroup_addPending(TaskGroup *group);
248+
bool swift_taskGroup_addPending(TaskGroup *group, bool unconditionally);
245249

246250
/// Cancel all tasks in the group.
247251
/// This also prevents new tasks from being added.

lib/SILGen/SILGenDecl.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,8 @@ void SILGenFunction::emitPatternBinding(PatternBindingDecl *PBD,
11421142
auto initialization = emitPatternBindingInitialization(PBD->getPattern(idx),
11431143
JumpDest::invalid());
11441144

1145+
// TODO: need to allocate the variable, stackalloc it? pass the address to the start()
1146+
11451147
// If this is an async let, create a child task to compute the initializer
11461148
// value.
11471149
if (PBD->isAsyncLet()) {
@@ -1157,11 +1159,35 @@ void SILGenFunction::emitPatternBinding(PatternBindingDecl *PBD,
11571159
"Could not find async let autoclosure");
11581160
bool isThrowing = init->getType()->castTo<AnyFunctionType>()->isThrowing();
11591161

1162+
// TODO: there's a builtin to make an address into a raw pointer
1163+
// --- note dont need that; just have the builtin take it inout?
1164+
// --- the builtin can take the address (for start())
1165+
1166+
// TODO: make a builtin start async let
1167+
// Builtin.startAsyncLet -- and in the builtin create the async let record
1168+
1169+
// TODO: make a builtin for end async let
1170+
1171+
// TODO: IRGen would make a local allocation for the builtins
1172+
1173+
// TODO: remember if we did an await already?
1174+
1175+
// TODO: force in typesystem that we always await; then end aysnc let does not have to be async
1176+
// the local let variable is actually owning the result
1177+
// - but since throwing we can't know; maybe we didnt await on a thing yet
1178+
// so we do need the tracking if we waited on a thing
1179+
1180+
// TODO: awaiting an async let should be able to take ownership
1181+
// that means we will not await on this async let again, maybe?
1182+
// it means that the async let destroy should not destroy the result anymore
1183+
11601184
// Emit the closure for the child task.
11611185
SILValue childTask;
11621186
{
11631187
FullExpr Scope(Cleanups, CleanupLocation(init));
11641188
SILLocation loc(PBD);
1189+
// TODO: opaque object in the async context that represents the async let
1190+
//
11651191
childTask = emitRunChildTask(
11661192
loc,
11671193
init->getType(),
@@ -1173,7 +1199,7 @@ void SILGenFunction::emitPatternBinding(PatternBindingDecl *PBD,
11731199
enterDestroyCleanup(childTask);
11741200

11751201
// Push a cleanup that will cancel the child task at the end of the scope.
1176-
enterCancelAsyncTaskCleanup(childTask);
1202+
enterCancelAsyncTaskCleanup(childTask); // TODO: this is "went out scope" rather than just a cancel
11771203

11781204
// Save the child task so we can await it as needed.
11791205
AsyncLetChildTasks[{PBD, idx}] = { childTask, isThrowing };

stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ OVERRIDE_TASK_GROUP(taskGroup_cancelAll, void,
180180

181181
OVERRIDE_TASK_GROUP(taskGroup_addPending, bool,
182182
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
183-
swift::, (TaskGroup *group), (group))
183+
swift::, (TaskGroup *group, bool unconditionally),
184+
(group, unconditionally))
184185

185186
OVERRIDE_TASK_LOCAL(task_localValuePush, void,
186187
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),

stdlib/public/Concurrency/Task.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ void AsyncTask::completeFuture(AsyncContext *context) {
102102
reinterpret_cast<char *>(context) - sizeof(FutureAsyncContextPrefix));
103103
bool hadErrorResult = false;
104104
auto errorObject = asyncContextPrefix->errorResult;
105-
// printf("asyncTask::completeFuture errorObject: %p\n", errorObject);
106105
fragment->getError() = errorObject;
107106
if (errorObject) {
108107
hadErrorResult = true;

0 commit comments

Comments
 (0)