In task-to-thread concurrency mode, `_getMainExecutorAsSerialExecutor`
returns `SerialExecutorRef::generic()`, which is, give or take, NULL.
Unfortunately we'd declared it as returning `any SerialExecutor`,
rather than `(any SerialExecutor)?`, and then the `getMainExecutor()`
function was calling `asUnownedSerialExecutor()` on it, which then
crashes.
rdar://153152063
Without this, llvm would sometimes wrongly assume there's no indirect
accesses and the optimizations can lead to a runtime crash, by
optimizing away initializing options properly.
Resolves rdar://152548190
statusCompletePendingReadyWaiting(), offer(), and poll() did a one-off compare_exchange_strong which could fail if the group was concurrently cancelled. Put these into loops so that they are retried when needed.
DiscardingTaskGroup creation passed the group result type as the task result type. waitAll() would then use the group result type when collecting task results. Since the task result type is always Void in this case, this would overflow the result buffer if the group result type was larger. This often works as it writes into the free space of the task allocator, but can crash if it happens to be at the end of a page or the group result type is particularly large.
rdar://151663730
(cherry picked from commit 5be22fa7cc)
**Description**: This adds "task name" parameter to all task creating
functions.
This is done in a few ways, e.g. we can backdeploy this to 5.1 in APIs
which do not accept the `TaskExecutor` but it they do we provide a
version for 6.0+ etc. This was requested in the SE acceptable of this
proposal [Acceptance post
SE-0469](https://forums.swift.org/t/accepted-with-modifications-se-0469-task-naming/79438).
This moves all these declarations to gyb since going through them one by
one has become unmaintainable otherwise.
**Scope/Impact**: All task creation APIs now gain a new task name
parameter.
**Risk:** Medium, changes existing APIs rather than adding "even more
overloads" though this risk was discussed in the team and accepted. This
has a potential to be source breaking it someone used Task.init and
friends as function.
**Testing**: CI testing, source compatibility suite testing
**Reviewed by**:
**Original PR:**
- https://github.com/swiftlang/swift/pull/81107 build changes required
for this
- https://github.com/swiftlang/swift/pull/80984
**Radar:**
---------
Co-authored-by: Kuba Mracek <mracek@apple.com>
https://github.com/swiftlang/swift/pull/80821 added `@isolated(any)`
which is an ABI breaking change but since we are not planning to keep
this API around, let's use `@_silgen_name` to bring the old name back
for now.
Resolves: rdar://152178221
This change aligns implementation with the current SE-0472 proposal.
(cherry picked from commit c3c1b4fca0)
(cherry picked from commit 8c05636e28)
(cherry picked from commit 0598b8c9f4)
Previously there was still a sneaky hop which caused ordering issues.
This introduced a specific test startSynchronously_order which checks
that the task enqueues indeed are "immediate" and cleans up how we
handle this.
This also prepares for the being discussed in SE review direction of
this API that it SHOULD be ALLOWED to actually hop and NOT be
synchronous at all IF the isolation is specified on the closure and is
DIFFERENT than the callers dynamic isolation.
This effectively implements "synchronously run right now if dynamically
on the exact isolation as requested by the closure; otherwise enqueue
the task as usual".
resolves rdar://149284186
cc @drexin
(cherry picked from commit a24a28c217)
This is basically the same as the one for Linux, but it would be
somewhat awkward to add the platform conditional on a file named for
Linux when OpenBSD is not Linux.
Important note: if Dispatch is disabled, then this will cause a
compilation error (probably not just for OpenBSD either), because
PlatformExecutorFactory is both defined in PlatformExecutorNone.swift
and PlatformExecutor<...>.swift in this case.
Because this only bites OpenBSD bootstrap builds, and since OpenBSD
support has been upstreamed to Dispatch, default to the Dispatch
implementation for now to get this in, and we'll refactor in a different
pr.
We can always get it back from the git history.
rdar://150695113
(cherry picked from commit 9d59dbed17)
Conflicts:
include/swift/AST/DiagnosticsSema.def
include/swift/Basic/Features.def
test/abi/macOS/arm64/concurrency.swift
test/abi/macOS/x86_64/concurrency.swift
Dispatch uses unsigned times, and cannot cope with times before its
clock started. As such, passing negative times from Swift through to
the C++ code results in large unsigned values, which then causes us to
wait forever. This is undesirable.
rdar://148899609
I had originally thought that we'd get away without this because the
executor construction generally happens in the async `main` function,
but of course if a program doesn't already use Swift Concurrency,
and someone uses it from a plug-in or library it loads, there's a
risk that we might have a race condition.
rdar://149346132
Swift concurrency defines a default platform executor. This was not
defined for FreeBSD resulting in build failures. Defining it to use the
Dispatch executor.
Scope: This only impacts FreeBSD.
Risk: Low. This change only affects FreeBSD.
Reviewers: @compnerd, @ktoso, @al45tair
Testing: Local testing to ensure Concurrency builds on FreeBSD.
Fixes: rdar://150643436
(cherry picked from commit 4a41e50730)
We missed to sign the handler. Along the way the signature of it
changed, so adjust for that.
How to get the number:
```
func PROPER(bar: (TaskPriority, TaskPriority) -> Void) {
let p = TaskPriority.default
bar(p, p)
}
```
```
-> % swiftc -target arm64e-apple-macos13 example.swift -S -o - | swift demangle | grep -a3 autda
stur x8, [x29, #-64]
mov x17, x8
movk x17, #11839, lsl #48 <<<<<<<<<
autda x16, x17
ldr x8, [x16, #64]
lsr x8, x8, #0
add x8, x8, #15
```
Resolves rdar://150378890
If the preloaded status is locked, then we need to reload it in order to distinguish between the current thread holding the lock and another thread holding the lock. Without this, if another thread holds the lock, then we won't set the is-locked bit. We'll still actually hold the lock, but other threads may perform operations locklessly if the bit is not set, which can cause a crash. By reloading status in that case, we ensure that the bit is always set correctly.
This manifested as crashes in task cancellation but could cause other task-related issues as well.
Also remove an assert of !isStatusRecordLocked() in AsyncTask::complete(). We allow other threads to access tasks and take the lock for things like cancellation, so the lock may legitimately be held at that point.
rdar://150327908
(cherry picked from commit 325b66ab20)
We were failing to switch executors to Dispatch queues, where those
were being used as executors, which caused a variety of unusual
symptoms.
rdar://150310927
This changes the isIsolatingCurrentContext function to return `Bool?`
and removes all the witness table trickery we did previously to detect
if it was implemented or not. This comes at a cost of trying to invoke
it always, before `checkIsolated`, but it makes for an simpler
implementation and more checkable even by third party Swift code which
may want to ask this question.
Along with the `withSerialExecutor` function, this now enables us to
check the isolation at runtime when we have an `any Actor` e.g. from
`#isolation`.
Updates SE-0471 according to
https://forums.swift.org/t/se-0471-improved-custom-serialexecutor-isolation-checking-for-concurrency-runtime/78834/
review discussions