The `createTaskGroup` builtin has changed its signature and now requires
a type metadata argument. Change the feature accordingly so that
compilers with the new and old versions have disjoint feature sets.
Fixes rdar://79561865.
introduce new options parameter to all task spawning
[Concurrency] ABI for asynclet start to accept options
[Concurrency] fix unittest usages of changed task creation ABI
[Concurrency] introduce constants for parameter indexes in ownership
[Concurrency] fix test/SILOptimizer/closure_lifetime_fixup_concurrency.swift
Changes the task, taskGroup, asyncLet wait funtion call ABIs.
To reduce code size pass the context parameters and resumption function
as arguments to the wait function.
This means that the suspend point does not need to store parent context
and resumption to the suspend point's context.
```
void swift_task_future_wait_throwing(
OpaqueValue * result,
SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
AsyncTask *task,
ThrowingTaskFutureWaitContinuationFunction *resume,
AsyncContext *callContext);
```
The runtime passes the caller context to the resume entry point saving
the load of the parent context in the resumption function.
This patch adds a `Metadata *` field to `GroupImpl`. The await entry
pointer no longer pass the metadata pointer and there is a path through
the runtime where the task future is no longer available.
The `Task` type has oscillated somewhat from being purely a namespace,
to having instances that are used (albeit rarely), back to purely
being a namespace that isn't used for all that many names. Many of the
names that used to be on Task have already been moved out, e.g., for
creating new detached tasks, creating new task groups, adding
cancellation handlers, etc.
Collapse `Task.Handle<Success, Failure>` into `Task<Success, Failure>`.
`Task.Handle` is the type that is most frequently referenced in the
concurrency library, so giving it the short name `Task` is most
appropriate. Replace the top-level async/detach functions with a
`Task` initializer and `Task.detached`, respectively.
The `Task` type can still act as a namespace for static operations
such as, e.g., `Task.isCancelled`. Do this with an extension of the
form:
extension Task where Success == Never, Failure == Never { ... }
We've been accruing a number of compatibility shims. Move them all
into their own source file, deprecate them, and make them
always-emit-into-client so they don't have any ABI impact.
This commit changes JobFlags storage to be 32bits, but leaves the runtime
API expressed in terms of size_t. This allows us to pack an Id in the
32bits we freed up.
The offset of this Id in the AsyncTask is an ABI constant. This way
introspection tools can extract the currently running task identifier
without any need for special APIs.
- stop storing the parent task in the TaskGroup at the .swift level
- make sure that swift_taskGroup_isCancelled is implied by the parent
task being cancelled
- make the TaskGroup structs frozen
- make the withTaskGroup functions inlinable
- remove swift_taskGroup_create
- teach IRGen to allocate memory for the task group
- don't deallocate the task group in swift_taskGroup_destroy
To achieve the allocation change, introduce paired create/destroy builtins.
Furthermore, remove the _swiftRetain and _swiftRelease functions and
several calls to them. Replace them with uses of the appropriate builtins.
I should probably change the builtins to return retained, since they're
working with a managed type, but I'll do that in a separate commit.
This allows programs to target older OSes while using Concurrency behind an availability check. When targeting older OSes, the symbols are weak-linked and the compiler will require the use of Concurrency features to be guarded by an availability check.
rdar://75850003
Most of the async runtime functions have been changed to not
expect the task and executor to be passed in. When knowing the
task and executor is necessary, there are runtime functions
available to recover them.
The biggest change I had to make to a runtime function signature
was to swift_task_switch, which has been altered to expect to be
passed the context and resumption function instead of requiring
the caller to park the task. This has the pleasant consequence
of allowing the implementation to very quickly turn around when
it recognizes that the current executor is satisfactory. It does
mean that on arm64e we have to sign the continuation function
pointer as an argument and then potentially resign it when
assigning into the task's resume slot.
rdar://70546948
First, just call an async -> T function instead of forcing the caller
to piece together which case we're in and perform its own copy. This
ensures that the task is actually kept alive properly.
Second, now that we no longer implicitly depend on the waiting tasks
being run synchronously, go ahead and schedule them to run on the
global executor.
This solves some problems which were blocking the work on TLS-ifying
the task/executor state.
- introduce UnsafeCurrentTask
- implement Hashable, Equatable on tasks
- assume we'll have a way to get a task from sync context
- Task.Handle now has a Failure type as well
- Task.Handle.getResult