Commit Graph

237 Commits

Author SHA1 Message Date
Doug Gregor
ba0644cf81 Move priority adjustments for async task creation into the runtime.
We're not actually performing the adjustments at the moment due to an
unrelated bug, and will want to perform them within
`swift_task_create_common` based on inheritContext and the given
priority.
2021-06-24 07:53:18 -07:00
Doug Gregor
7def279cdb Drop task options from the createAsyncTask SIL builtin.
We'll keep the task options entirely as a contract between IRGen and
the concurrency runtime, so Swift code need not deal with them.
2021-06-24 07:53:18 -07:00
Doug Gregor
e7e922ea77 Introduce a createAsyncTaskInGroup SIL builtin.
Rather than using group task options constructed from the Swift parts
of the _Concurrency library and passed through `createAsyncTask`'s
options, introduce a separate builtin that always takes a group. Move
the responsibility for creating the options structure into IRGen, so
we don't need to expose the TaskGroupTaskOptionRecord type in Swift.
2021-06-24 07:53:18 -07:00
Doug Gregor
95e38839ab Hollow out swift_asyncLet_startImpl to just a swift_task_create call.
Introduce a task option record to capture the async-let storage, so
that `swift_task_create` can perform the appropriate initialization.
2021-06-24 07:53:18 -07:00
Doug Gregor
8388a92ee9 Correct naming of "CopyThreadLocals" to "CopyTaskLocals" 2021-06-24 07:53:18 -07:00
Doug Gregor
dafb574a35 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.
2021-06-24 07:53:18 -07:00
Doug Gregor
c7edfa3ba9 Centralize non-group task creation on swift_task_create[_f].
Introduce a builtin `createAsyncTask` that maps to `swift_task_create`,
and use that for the non-group task creation operations based on the
task-creation flags. `swift_task_create` and the thin function version
`swift_task_create_f` go through the dynamically-replaceable
`swift_task_create_common`, where all of the task creation logic is
present.

While here, move copying of task locals and the initial scheduling of
the task into `swift_task_create_common`, enabling by separate flags.
2021-06-24 07:53:17 -07:00
Konrad `ktoso` Malawski
8536100354 [Concurrency] introduce task options, and change ABI to accept them
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
2021-06-21 13:03:50 +09:00
Arnold Schwaighofer
5e9d1b52e2 Merge pull request #37939 from aschwaighofer/workaround_runtime_bug
Workaround the current actor runtime's unwillingness to deal with priorities properly
2021-06-16 14:21:50 -07:00
Arnold Schwaighofer
c4bd90f6c4 Workaround the actor runtimes unwillingness to deal with priorities properly
rdar://79378627
2021-06-16 07:39:32 -07:00
Joe Groff
e39dca4dbf SILGen: Hop to the executor for actor-constrained methods in their @objc async thunks.
If a Swift async method is actor-constrained, then when it's projected into ObjC, it should still
run its task on the correct actor, along with the completion handler that ObjC passes into it.
Fixes rdar://76415650.
2021-06-15 12:09:47 -07:00
Andrew Trick
d3ac3d4d84 Use Builtin.hopToActor in _runAsyncMain
If the optimizer is doing it's job, then @MainActor can't be used to
force another actor-independent async callee onto the main actor.

Instead, explicitly hop, which communicates the actual intent and is robust.
2021-06-13 23:44:30 -07:00
Doug Gregor
7d2ce77e4d [Concurrency] Add async properties Task.value and Task.result 2021-05-18 20:03:26 -07:00
Doug Gregor
8750f209fc [Concurrency] Rename TaskPriority members.
Based on feedback from the second review, we decided to go with
high/default/low/background, with aliases for the Dispatch-inspired
names. While here, make TaskPriority be backed by a UInt8 to better
describe the actual restrictions, and start removing userInteractive,
because clients shouldn't be able to specify it.
2021-05-18 16:37:40 -07:00
Doug Gregor
6aefea0716 Fix up some documentation for the async/detach renamings 2021-05-18 15:33:39 -07:00
Doug Gregor
eda5b4daad [Concurrency] Alternative Task API.
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.
2021-05-18 14:36:21 -07:00
Doug Gregor
9788cc2cf4 [Concurrency] Provide an alternative implementation when "async { }" is unusable
There exist Swift builds that support `Sendable` but not the attributes
used on `async`. Make sure that have an implementation of
`_runTaskForBridgedAsyncMethod` that does something.

Fixes rdar://77637570.
2021-05-17 13:11:53 -07:00
Doug Gregor
2b9ca315fe [Concurrency] Remove asyncHandler attribute.
The `asyncHandler` attribute turned out to be the wrong solution
to the problem of creating a sync->async bridge. Remove it.
2021-05-13 17:01:39 -07:00
Fred Riss
bbda706393 [Concurrency] Add a unique Task ID to AsyncTask
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.
2021-05-11 08:28:17 -07:00
Konrad `ktoso` Malawski
6cbb792f92 [TaskLocals] Propagate task-locals through async{} 2021-05-11 11:06:17 +09:00
Dario Rexin
efe6973293 [Concurrency] Reduce overhead of Task.yield and Task.sleep (#37090)
* [Concurrency] Reduce overhead of Task.yield and Task.sleep

Instead of creating a new task, we create a simple job that wraps a Builtin.RawUnsafeContinuation and resumes the continuation when it is executed. The job instance is allocated on the task local allocator, meaning we don't malloc anything.

* Update stdlib/public/Concurrency/Task.swift

Co-authored-by: Konrad `ktoso` Malawski <konrad.malawski@project13.pl>

Co-authored-by: Konrad `ktoso` Malawski <konrad.malawski@project13.pl>
2021-05-10 11:51:20 -07:00
Alexis Laferrière
10d115bd5c [Concurrency] Use the SwiftStdlib 5.5 macro instead of 9999 versions 2021-05-04 09:30:58 -07:00
John McCall
cc2863c136 Merge pull request #36878 from rjmccall/custom-executors
Introduce basic support for custom executors
2021-04-30 13:54:02 -04:00
John McCall
186c53000d Introduce basic support for custom executors.
- Introduce an UnownedSerialExecutor type into the concurrency library.
- Create a SerialExecutor protocol which allows an executor type to
  change how it executes jobs.
- Add an unownedExecutor requirement to the Actor protocol.
- Change the ABI for ExecutorRef so that it stores a SerialExecutor
  witness table pointer in the implementation field.  This effectively
  makes ExecutorRef an `unowned(unsafe) SerialExecutor`, except that
  default actors are represented without a witness table pointer (just
  a bit-pattern).
- Synthesize the unownedExecutor method for default actors (i.e. actors
  that don't provide an unownedExecutor property).
- Make synthesized unownedExecutor properties `final`, and give them
  a semantics attribute specifying that they're for default actors.
- Split `Builtin.buildSerialExecutorRef` into a few more precise
  builtins.  We're not using the main-actor one yet, though.

Pitch thread:
  https://forums.swift.org/t/support-custom-executors-in-swift-concurrency/44425
2021-04-30 03:11:56 -04:00
Doug Gregor
cdc6dbe11d [Concurrency] Deprecate Task.Priority.unspecified and use optionals instead 2021-04-29 22:16:02 -07:00
Doug Gregor
92dd8ef4df [Concurrency] Make async operation return a task handle.
Per updates to the Structured Concurrency protocol, make the `async`
operation (1) overloaded on throwing-ness and (2) return an appropriate
`Task.Handle`.
2021-04-29 20:57:53 -07:00
Doug Gregor
67ed43730d [Concurrency] Have Task.currentPriority query the system as a fallback.
When `Task.currentPriority` is evaluated outside of an actual task,
query the system to determine the priority at which the code is
currently executing. This is the behavior that `async` specifies.
Extend that to `currentPriority` rather than guessing `.default`.
2021-04-29 11:01:43 -07:00
Doug Gregor
2000bf9b5f Add @_implicitSelfCapture to asyncDetached.
Like `async`, `asyncDetached` should not require `self.` because it is
unlikely to introduce cycles.
2021-04-27 17:03:03 -07:00
Doug Gregor
ee5864c309 Merge pull request #37072 from DougGregor/user-initiated-async
[Concurrency] Perform userInitiated adjustment after determining priority
2021-04-27 12:26:39 -07:00
Doug Gregor
b882a12e59 Merge pull request #37070 from DougGregor/bridged-async-via-async 2021-04-26 20:59:07 -07:00
Doug Gregor
fba8ccadfc [Concurrency] Perform userInitiated adjustment after determining priority.
Based on feedback, perform the adjustment from userInteractive to
userInitiated all the time, and rely on `qos_class_self` whenever we
don't have a task.
2021-04-26 15:15:29 -07:00
Doug Gregor
ace5f49790 [Concurrency] Switch _runTaskForBridgedAsyncMethod over to using 'async' 2021-04-26 15:02:49 -07:00
Doug Gregor
ff4b0f335e [Concurrency] Speculatively add asyncDetached as a synonym for async.
Given that `async` is the dominant way to initiate asynchronous work from
a synchronous function, speculatively rename `detach` to `asyncDetached`
to both fit into the naming scheme and clearly bias toward `async.
2021-04-26 12:49:07 -07:00
Konrad `ktoso` Malawski
e0eb940027 [Concurrency] Remove Task.current because it prevents task-local alloc #36993 2021-04-26 17:37:45 +09:00
Doug Gregor
181ffaf733 Fix a typo in async comment 2021-04-22 09:12:37 -07:00
Doug Gregor
3c3f216be3 [Concurrency] Add "async" operation for continuing work asynchronously.
The `async` operation is a global function that initiates asynchronous
work on behalf of the synchronous code that calls it. Unlike `detach`,
`async` inherits priority, actor context, and other aspects of the
synchronous code that initiates it, making it a better "default"
operation for creating asynchronous work than `detach`. The `detach`
operation is still important for creating truly detached tasks that
can later be `await`'d or cancelled if needed.

Implements the main entry point for rdar://76927008.
2021-04-21 22:21:24 -07:00
Konrad `ktoso` Malawski
eed96d21bb [AsyncLet] remove runChild; it is now asyncLetStart 2021-04-19 10:06:23 +09:00
Konrad `ktoso` Malawski
d3c5ebc9b7 [AsyncLet] reimplemented with new ABI and builtins 2021-04-19 10:06:23 +09:00
Konrad `ktoso` Malawski
ba615029c7 [Concurrency] Store child record when async let child task spawned 2021-04-19 10:06:23 +09:00
Evan Wilde
9b82fec131 Merge pull request #36457 from etcwilde/ewilde/delete-runAsyncAndBlock
[Concurrency] Delete runAsyncAndBlock
2021-04-16 08:40:30 -07:00
Evan Wilde
9b15a9ffad Delete runAsyncAndBlock once and for all! 2021-04-14 15:04:56 -07:00
Konrad `ktoso` Malawski
5e0593f1d3 [Concurrency] detach should not take Failure type param 2021-04-15 06:59:35 +09:00
Doug Gregor
e77a27e8ed [Concurrency] Introduce runtime detection of data races.
Through various means, it is possible for a synchronous actor-isolated
function to escape to another concurrency domain and be called from
outside the actor. The problem existed previously, but has become far
easier to trigger now that `@escaping` closures and local functions
can be actor-isolated.

Introduce runtime detection of such data races, where a synchronous
actor-isolated function ends up being called from the wrong executor.
Do this by emitting an executor check in actor-isolated synchronous
functions, where we query the executor in thread-local storage and
ensure that it is what we expect. If it isn't, the runtime complains.
The runtime's complaints can be controlled with the environment
variable `SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL`:

  0 - disable checking
  1 - warn when a data race is detected
  2 - error and abort when a data race is detected

At an implementation level, this introduces a new concurrency runtime
entry point `_checkExpectedExecutor` that checks the given executor
(on which the function should always have been called) against the
executor on which is called (which is in thread-local storage). There
is a special carve-out here for `@MainActor` code, where we check
against the OS's notion of "main thread" as well, so that `@MainActor`
code can be called via (e.g.) the Dispatch library's
`DispatchQueue.main.async`.

The new SIL instruction `extract_executor` performs the lowering of an
actor down to its executor, which is implicit in the `hop_to_executor`
instruction. Extend the LowerHopToExecutor pass to perform said
lowering.
2021-04-12 15:19:51 -07:00
swift-ci
5db3caf9cc Merge pull request #36855 from apple/ktoso-patch-3 2021-04-09 19:53:03 -07:00
Konrad `ktoso` Malawski
34d1e27565 [Concurrency] runDetached shim must be static 2021-04-10 08:54:41 +09:00
John McCall
efeb818161 Clean up the TaskGroup ABI:
- 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.
2021-04-09 03:06:31 -04:00
swift-ci
56b86b6cf1 Merge pull request #36766 from ktoso/wip-add-deprecated-shims-old-task-api 2021-04-06 00:50:33 -07:00
Konrad `ktoso` Malawski
d8b4e3c304 [Concurrency] add deprecated shim for Task.withGroup 2021-04-06 12:51:55 +09:00
Konrad `ktoso` Malawski
39e97c57f2 [Concurrency] add deprecated shim for runDetached 2021-04-06 11:17:25 +09:00
Konrad `ktoso` Malawski
9949bf440d updated to latest Task APIs 2021-04-06 07:20:07 +09:00