Commit Graph

1607 Commits

Author SHA1 Message Date
Doug Gregor
64c670745a Lower the async task slab allocation to 1000 bytes.
Due to malloc quanta rounding, 1024-byte async task allocation slabs
actually end up allocating 1536 bytes on Darwin. Instead, use 1000-byte
slabs.

Fixes rdar://81181856.
2021-08-02 16:09:17 -07:00
Doug Gregor
84d488c9bc Ignore task priorities in the actor runtime.
The actor runtime has some known issues with deadlock when an actor has
to give up its thread because it's running lower-priority work. To
avoid deadlocks here, disable all of the logic that tries to give up
higher-priority threads when only lower-priority work is available, or
to escalate work, effectively making the actor runtime ignore
priorities internally.

Fixes rdar://79378762.
2021-07-30 23:27:17 -07:00
Doug Gregor
c225a1cf45 Fix bit manipulation in ActiveTaskStatus::withEscalatedPriority().
Due to a missing `~` when trying to mask in a new priority + the
`IsEscalated` flag, we were instead getting an incorrect priority as
well as dropping other useful bits. This led to assertions about the
running state of a task not being set.
2021-07-30 23:27:17 -07:00
Doug Gregor
d9e3259ff6 [SE-0304] Clean up handling of task priorities. 2021-07-30 12:53:03 -07:00
Doug Gregor
8884e3a510 [SE-0304] Rename Task.suspend() back to Task.yield(). 2021-07-27 12:19:55 -07:00
Doug Gregor
8180c26a8d Merge pull request #38600 from varungandhi-apple/vg-resume-to-generic-executor
[Runtime] Resume to the generic executor in the absence of an override.
2021-07-23 09:30:20 -07:00
Varun Gandhi
9adc0a5bb1 [Concurrency] Deprecate Task.sleep(_:) in favor of Task.sleep(nanoseconds:). 2021-07-23 07:55:53 -07:00
Joe Groff
fc67ba57f2 Merge pull request #37938 from jckarter/async-let-multi-suspend
Handle multiple awaits and suspend-on-exit for async let tasks.
2021-07-23 07:36:54 -07:00
Michael Gottesman
9a1d18ae4f Merge pull request #38421 from gottesmm/track-task-is-running-with-exclusivity-runtime-fixes
[exclusivity] Add support for Task local exclusivity access sets.
2021-07-22 22:48:36 -07:00
Dario Rexin
2c43247c0a Merge pull request #38568 from drexin/wip-android-libatomic
[Concurrency] Remove libatomic dependency for Android
2021-07-22 21:26:38 -07:00
Varun Gandhi
d348fd90d4 Resume to the generic executor in the absence of an override.
Without this fix, we saw a crash involving URLSession where we'd hit
assertions or corruption in the runtime in various forms:
- Assertion on trying to enqueue work onto a zombie actor.
- job->SchedulerPrivate being overwritten (crash in getNextJobInQueue).
- *(job->SchedulerPrivate) being overwritten (crash in getAsPreprocessedJob
  right after call to getNextJobInQueue).

I haven't been able to create a minimal crashing example yet, but manual
testing shows this does fix the issue.

Fixes rdar://79859254.
2021-07-22 21:11:16 -07:00
Stephen Celis
ea72a9e2ff Constrain AsyncThrowingStream.init(unfolding:) where Failure == Error 2021-07-22 15:17:32 -07:00
Philippe Hausler
9bc1eaff86 [Concurrency] Updates to reflect the feedback from SE-0314 2021-07-22 15:17:32 -07:00
Michael Gottesman
0aec81614d [exclusivity] Add support for Task local exclusivity access sets.
The implemented semantics are that:

1. Tasks have separate exclusivity access sets.
2. Any synchronous context that creates tasks will have its exclusive access set
   merged into the Tasks while the Task is running.

rdar://80492364
2021-07-22 13:25:10 -07:00
Michael Gottesman
fc4d6c86ef [concurrency] Add UnownedJob._runSynchronously(on:) to support running a job synchronously on an executor.
I am going to use this to test that we propagate synchronous accesses into
asynchronous tasks access sets.

To ensure this is not ABI, I underscored/marked this as alwaysEmitIntoClient.
2021-07-22 13:25:10 -07:00
Michael Gottesman
ff6b67c585 [concurrency] Add AsyncTask::flagAsCompleted() and behind SWIFT_TASK_PRINTF_DEBUG allow it to be used to log Task completion.
This should let people debug Task lifetime easier.
2021-07-22 13:25:09 -07:00
Dario Rexin
38c86fc94a [Concurrency] Remove libatomic dependency for Android 2021-07-22 11:13:22 -07:00
Dario Rexin
914928e954 Merge pull request #38551 from drexin/wip-concurrency-libatomic
[Concurrency] Remove libatomic dependency on Concurrency module on Linux
2021-07-22 10:50:40 -07:00
Joe Groff
439edbce1f Handle multiple awaits and suspend-on-exit for async let tasks.
Change the code generation patterns for `async let` bindings to use an ABI based on the following
functions:

- `swift_asyncLet_begin`, which starts an `async let` child task, but which additionally
  now associates the `async let` with a caller-owned buffer to receive the result of the task.
  This is intended to allow the task to emplace its result in caller-owned memory, allowing the
  child task to be deallocated after completion without invalidating the result buffer.
- `swift_asyncLet_get[_throwing]`, which replaces `swift_asyncLet_wait[_throwing]`. Instead of
  returning a copy of the value, this entry point concerns itself with populating the local buffer.
  If the buffer hasn't been populated, then it awaits completion of the task and emplaces the
  result in the buffer; otherwise, it simply returns. The caller can then read the result out of
  its owned memory. These entry points are intended to be used before every read from the
  `async let` binding, after which point the local buffer is guaranteed to contain an initialized
  value.
- `swift_asyncLet_finish`, which replaces `swift_asyncLet_end`. Unlike `_end`, this variant
  is async and will suspend the parent task after cancelling the child to ensure it finishes
  before cleaning up. The local buffer will also be deinitialized if necessary. This is intended
  to be used on exit from an `async let` scope, to handle cleaning up the local buffer if necessary
  as well as cancelling, awaiting, and deallocating the child task.
- `swift_asyncLet_consume[_throwing]`, which combines `get` and `finish`. This will await completion
  of the task, leaving the result value in the result buffer (or propagating the error, if it
  throws), while destroying and deallocating the child task. This is intended as an optimization
  for reading `async let` variables that are read exactly once by their parent task.

To avoid an epoch break with existing swiftinterfaces and ABI clients, the old builtins and entry
points are kept intact for now, but SILGen now only generates code using the new interface.

This new interface fixes several issues with the old async let codegen, including use-after-free
crashes if the `async let` was never awaited, and the inability to read from an `async let` variable
more than once.

rdar://77855176
2021-07-22 10:19:31 -07:00
Varun Gandhi
72909bdd98 Merge pull request #38427 from varungandhi-apple/vg-workaround-priority
Further workaround for priority mishandling in runtime.
2021-07-22 09:19:09 -07:00
Dario Rexin
9fac208ccb [Concurrency] Remove libatomic dependency on Concurrency module on Linux 2021-07-21 18:40:54 -07:00
Konrad `ktoso` Malawski
73797800b4 [Distributed] introduce static resolve func, and fix static isolation on dist actors (#38530) 2021-07-22 08:00:54 +09:00
Doug Gregor
e12a81a12d Merge pull request #38528 from rjmccall/stage-continuation-await
Stage the swift_continuation_await ABI change
2021-07-21 09:05:56 -07:00
Doug Gregor
b9cc312ac1 Merge pull request #38510 from DougGregor/availability-gate-concurrency 2021-07-21 07:33:51 -07:00
John McCall
0ce82d0755 Stage the swift_continuation_await ABI change.
Introduce a fake (but non-ABI) declaration to the swiftinterface
which marks that an SDK support swift_continuation_await, and then
only call it if that declaration exists, otherwise falling back
on the old atomic sequence.  Using that sequence will badly mess
up the runtime's tracking of task state, but it might still work,
and more importantly things will still build, which solves the
short-term problem.  Hopefully we can remove this hack soon.

Fixes rdar://problem/80787731.
2021-07-20 20:31:40 -04:00
John McCall
34ae88e487 Merge pull request #38508 from rjmccall/link-libatomic-concurrency-2
Fix `-latomic` linking condition, include android
2021-07-20 19:16:33 -04:00
Konrad `ktoso` Malawski
ea146ac5d4 [Concurrency,docs] Update task local docs to use latest structured concurrency APIs (#38499) 2021-07-21 07:57:11 +09:00
John McCall
2ff171921e Fix -latomic condition, include android 2021-07-20 16:21:44 -04:00
Doug Gregor
e2d97af4bf Add availability gating for async function and actor type definitions.
Implements rdar://80098709.
2021-07-20 11:28:23 -07:00
John McCall
871ee794bc Link the concurrency runtime against libatomic on Linux.
We mostly get away without this because we're fairly disciplined
about using constant memory orderings, and apparently that's
usually good enough to get inline accesses and avoid needing to
link atomic.  However, we have a few places with the task status
atomic that use a non-constant load ordering with load and
compare_exchange_weak, and my recent change to make that atomic
a double-word was apparently sufficient on some (but not all)
Linux distributions to get the compiler to call the runtime
function.  Regardless, we shouldn't be playing around in the
margins here: Linux requires us to link libatomic, so we should.
2021-07-20 01:57:26 -04:00
Varun Gandhi
fa40675910 Further workaround for priority mishandling in runtime.
See rdar://79378762, SR-14802, SR-14841, SR-14875.

This doesn't resolve all hangs, such as those occurring
due to explicit usage of priorities and certain other
situations where priorities seem to be causing issues
(rdar://79823345), but it does resolve some cases.
2021-07-15 23:03:07 -07:00
swift-ci
d73d8a69d5 Merge pull request #38404 from ktoso/wip-task-cancellation-double 2021-07-15 19:12:06 -07:00
Konrad `ktoso` Malawski
e8888f7965 [Concurrency] prevent races in task cancellation 2021-07-16 08:29:00 +09:00
John McCall
48b8780e58 Merge pull request #38386 from rjmccall/track-task-is-running
Track whether a task is actively running
2021-07-15 16:22:44 -04:00
Konrad `ktoso` Malawski
716a0255c0 [Distributed] Move to ActorIdentity protocol (#38362) 2021-07-15 21:13:55 +09:00
John McCall
264e4ace12 Clear the active task immediately when suspending. 2021-07-14 20:24:01 -04:00
John McCall
bd451f9f08 Remove the hooking for swift_task_getCurrent().
This is very performance-sensitive and unreasonable to change.
2021-07-14 20:24:01 -04:00
John McCall
0d5fd0f520 Remove the ShouldNotDeallocateInCallee bit from AsyncContextFlags.
The original async ABI made callees deallocate the context,
which allows tail calls (at the async-function level) but
interferes with callers' ability to optimize callee frame
allocation.  The purpose of this bit was to allow callers
to do that optimization, but we've since just made callers
responsible for deallocating the context, which is overall
just a lot simpler.  So this has been dead for quite some
time.
2021-07-14 20:24:01 -04:00
John McCall
29434257dd Allow swift_continuation_await to be forced to honor an executor. 2021-07-14 20:24:01 -04:00
John McCall
3aa04db87b Track whether a task is actively running.
Tracking this as a single bit is actually largely uninteresting
to the runtime.  To handle priority escalation properly, we really
need to track this at a finer grain of detail: recording that the
task is running on a specific thread, enqueued on a specific actor,
or so on.  But starting by tracking a single bit is important for
two reasons:

- First, it's more realistic about the performance overheads of
  tasks: we're going to be doing this tracking eventually, and
  the cost of that tracking will be dominated by the atomic
  access, so doing that access now sets the baseline about right.

- Second, it ensures that we've actually got runtime involvement
  in all the right places to do this tracking.

A propos of the latter: there was no runtime involvement with
awaiting a continuation, which is a point at which the task
potentially transitions from running to suspended.  We must do
the tracking as part of this transition, rather than recognizing
in the run-loops that a task is still active and treating it as
having suspended, because the latter point potentially races with
the resumption of the task.  To do this, I've had to introduce
a runtime function, swift_continuation_await, to do this awaiting
rather than inlining the atomic operation on the continuation.

As part of doing this work, I've also fixed a bug where we failed
to load-acquire in swift_task_escalate before walking the task
status records to invoke escalation actions.

I've also fixed several places where the handling of task statuses
may have accidentally allowed the task to revert to uncancelled.
2021-07-14 20:24:01 -04:00
John McCall
930c72aee2 Fix DispatchQueueShim to work correctly in a debug build.
The self object isn't actually a Swift object, so we can neither
do class dispatch on it nor retain it with swift_retain.

Some of the credit goes to Mike Ash on this one.  All the
blame is mine, of course.
2021-07-14 15:50:10 -04:00
Andrew Trick
982b47d829 Add Builtin.hopToActor to the feature list.
This builtin never occurs in @inlinable code. But apparently we still
need to add a language feature for every builtin. This must allow
older compilers to reparse the library source (though I don't know why
that would ever happen!)

Fixes rdar://80525569 error: module 'Builtin' has no member named 'hopToActor')
2021-07-13 16:28:38 -07:00
Philippe Hausler
6a80196da3 Allow AsyncSequence operators to be inlined in their construction (#38310) 2021-07-09 09:23:39 -07:00
Mike Ash
9d3cd5ea7e Merge pull request #38290 from mikeash/frame-pointer-mask-symbol
[Concurrency] Add an exported symbol on Darwin that contains the frame pointer flag bit for async frames.
2021-07-09 09:36:32 -04:00
Doug Gregor
57e22bb92f Merge pull request #38306 from DougGregor/structured-concurrency-review-4
[SE-0304] Align Task API implementation with the fourth revision of the proposal
2021-07-08 22:07:42 -07:00
Doug Gregor
121e34fa04 Reimplement Task.sleep(nanoseconds:) without the raciness.
The prior implementation of `Task.sleep()` effectively had two
different atomic words to capture the state, which could lead to cases
where cancelling before a sleep operation started would fail to
throw `CancellationError`. Reimplement the logic for the cancellable
sleep with a more traditional lock-free approach by
packing all of the state information into a single word, where we
always load, figure out what to do, then compare-and-swap.
2021-07-08 17:26:55 -07:00
Doug Gregor
1a024e96c8 Remove UnownedJob.run(). It never did anything anyway 2021-07-08 13:23:42 -07:00
Doug Gregor
4a0723f68c [SE-0304] Add UnsafeCurrentTask.cancel(). 2021-07-08 13:22:33 -07:00
Doug Gregor
7ba63cf53c [SE-0304] Clarify documentation of Task.sleep(nanoseconds:) slightly 2021-07-08 13:21:56 -07:00
Doug Gregor
59d1e61ac4 [SE-0304] Implement cancellable Task.sleep(nanoseconds:). 2021-07-08 09:46:07 -07:00