Commit Graph

1543 Commits

Author SHA1 Message Date
Konrad `ktoso` Malawski
814ede0cf3 [Distributed] Initial distributed actors and functions and new module (#37109)
* [Distributed] Initial distributed checking

* [Distributed] initial types shapes and conform to DistributedActor

* [Distributed] Require Codable params and return types

* [Distributed] initial synthesis of fields and constructors

* [Distributed] Field and initializer synthesis

* [Distributed] Codable requirement on distributed funcs; also handle <T: Codable>

* [Distributed] handle generic type params which are Codable in dist func

[Distributed] conformsToProtocol after all

* [Distributed] Implement remote flag on actors

* Implement remote flag on actors

* add test

* actor initializer that sets remote flag

[Distributed] conformances getting there

* [Distributed] dont require async throws; cleanup compile tests

* [Distributed] do not synthesize default implicit init, only our special ones

* [Distributed] properly synth inits and properties; mark actorTransport as _distributedActorIndependent

Also:

- do not synthesize default init() initializer for dist actor

* [Distributed] init(transport:) designated and typechecking

* [Distributed] dist actor initializers MUST delegate to local-init

* [Distributed] check if any ctors in delegation call init(transport:)

* [Distributed] check init(transport:) delegation through many inits; ban invoking init(resolve:using:) explicitly

* [Distributed] disable IRGen test for now

* [Distributed] Rebase cleanups

* [Concurrent] transport and address are concurrent value

* [Distributed] introduce -enable-experimental-distributed flag

* rebase adjustments again

* rebase again...

* [Distributed] distributed functions are implicitly async+throws outside the actor

* [Distributed] implicitly throwing and async distributed funcs

* remove printlns

* add more checks to implicit function test

* [Distributed] resolve initializer now marks the isRemote actor flag

* [Distributed] distributedActor_destroy invoked instead, rather than before normal

* [Distributed] Generate distributed thunk for actors

* [distributed] typechecking for _remote_ functions existing, add tests for remote funcs

* adding one XFAIL'ed task & actor lifetime test

The `executor_deinit1` test fails 100% of the time
(from what I've seen) so I thought we could track
and see when/if someone happens to fix this bug.

Also, added extra coverage for #36298 via `executor_deinit2`

* Fix a memory issue with actors in the runtime system, by @phausler

* add new test that now passes because of patch by @phausler

See previous commit in this PR.
Test is based on one from rdar://74281361

* fix all tests that require the _remote_ function stubs

* Do not infer @actorIndependent onto `let` decls

* REVERT_ME: remove some tests that hacky workarounds will fail

* another flaky test, help build toolchain

* [Distributed] experimental distributed implies experimental concurrency

* [Distributed] Allow distributed function that are not marked async or throws

* [Distributed] make attrs SIMPLE to get serialization generated

* [Distributed] ActorAddress must be Hashable

* [Distributed] Implement transport.actorReady call in local init

* cleanup after rebase

* [Distributed] add availability attributes to all distributed actor code

* cleanup - this fixed some things

* fixing up

* fixing up

* [Distributed] introduce new Distributed module

* [Distributed] diagnose when missing 'import _Distributed'

* [Distributed] make all tests import the module

* more docs on address

* [Distributed] fixup merge issues

* cleanup: remove unnecessary code for now SIMPLE attribute

* fix: fix getActorIsolationOfContext

* [Distributed] cmake: depend on _concurrency module

* fixing tests...

* Revert "another flaky test, help build toolchain"

This reverts commit 83ae6654dd.

* remove xfail

* clenup some IR and SIL tests

* cleanup

* [Distributed] fix cmake test and ScanDependencies/can_import_with_map.swift

* [Distributed] fix flags/build tests

* cleanup: use isDistributed wherever possible

* [Distributed] don't import Dispatch in tests

* dont link distributed in stdlib unittest

* trying always append distributed module

* cleanups

* [Distributed] move all tests to Distributed/ directory

* [lit] try to fix lit test discovery

* [Distributed] update tests after diagnostics for implicit async changed

* [Distributed] Disable remote func tests on Windows for now

* Review cleanups

* [Distributed] fix typo, fixes Concurrency/actor_isolation_objc.swift

* [Distributed] attributes are DistributedOnly (only)

* cleanup

* [Distributed] cleanup: rely on DistributedOnly for guarding the keyword

* Update include/swift/AST/ActorIsolation.h

Co-authored-by: Doug Gregor <dgregor@apple.com>

* introduce isAnyThunk, minor cleanup

* wip

* [Distributed] move some type checking to TypeCheckDistributed.cpp

* [TypeCheckAttr] remove extra debug info

* [Distributed/AutoDiff] fix SILDeclRef creation which caused AutoDiff issue

* cleanups

* [lit] remove json import from lit test suite, not needed after all

* [Distributed] distributed functions only in DistributedActor protocols

* [Distributed] fix flag overlap & build setting

* [Distributed] Simplify noteIsolatedActorMember to not take bool distributed param

* [Distributed] make __isRemote not public

Co-authored-by: Dario Rexin <drexin@apple.com>
Co-authored-by: Kavon Farvardin <kfarvardin@apple.com>
Co-authored-by: Doug Gregor <dgregor@apple.com>
2021-05-21 09:12:29 +09: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
Konrad `ktoso` Malawski
82e91b7785 [TaskLocals] Enable sync functions to bind task-locals; Keep Storage in TLS 2021-05-11 11:06:16 +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
David Zarzycki
54e20177c5 [runtime] Fix use-after-free bug 2021-05-01 12:24: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
Konrad `ktoso` Malawski
6f3dac190a [TaskLocals] remove TaskLocalInheritance, we'll introduce when needed 2021-04-29 15:48:22 +09:00
Konrad `ktoso` Malawski
58ea749304 [TaskLocal] Crash on inapropriate use within task group 2021-04-29 15:48:22 +09:00
Konrad `ktoso` Malawski
3d96d05546 [TaskLocals] property wrapper keys 2021-04-29 15:48:09 +09:00
Mishal Shah
3116eed2e4 Update the branch to build with Xcode 12.5 (#37046) 2021-04-23 16:24:11 -07:00
Mike Ash
22ef406163 Merge pull request #37018 from mikeash/remove-dynamic-class-is-swift-mask
[Runtime] Remove the _swift_classIsSwiftMask variable.
2021-04-23 11:46:20 -04:00
Mike Ash
44d06a7faf [Runtime] Remove the _swift_classIsSwiftMask variable.
SWIFT_CLASS_IS_SWIFT_MASK is optionally defined to a global variable _swift_classIsSwiftMask, which allows the runtime to choose the appropriate mask when running on OS versions earlier than macOS 10.14.4. This is no longer a supported target for newly built runtimes (Swift apps built with such a target will embed a copy of the back deployment runtime, which is separate) and this global is no longer useful. Instead, unconditionally define SWIFT_CLASS_IS_SWIFT_MASK to 2 on Apple platforms, which is the correct value for current OS versions.

rdar://48413153
2021-04-22 16:25:46 -04:00
Doug Gregor
623e54f45c Merge pull request #37007 from DougGregor/async-operation
[Concurrency] Add "async" operation for continuing work asynchronously.
2021-04-22 12:00:16 -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
Erik Eckstein
93367ed587 concurrency: make the startAsyncLet closure no-escaping
The closure does not escape the startAsyncLet - endAsyncLet scope. Even though it's (potentially) running on a different thread.

The substantial change in the runtime is to not call swift_release on the closure context if it's a non-escaping closure.
2021-04-20 21:57:19 +02: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
Minhyuk Kim
3ca45557fa [docs] Add short note about dynamic subclassing and KVO 2021-04-18 21:34:57 +09:00
Doug Gregor
f7fb5a1a9f Merge pull request #36874 from DougGregor/dynamic-data-race-actor-isolation
[Concurrency] Introduce runtime detection of data races.
2021-04-13 14:56:02 -07: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
Mike Ash
2167f5c797 Merge pull request #36850 from mikeash/isa-superclass-ptrauth-qualifiers
[Runtime] Use ptrauth qualifiers on metadata and superclass fields.
2021-04-12 16:37:09 -04:00
Mike Ash
3da4d20081 [Runtime] Use ptrauth qualifiers on metadata and superclass fields. 2021-04-12 12:59:49 -04:00
John McCall
2e8a19cdaf Merge pull request #36838 from rjmccall/task-group-abi-cleanup
Clean up the TaskGroup ABI
2021-04-09 20:15:41 -04:00
swift-ci
ea23988b5d Merge pull request #36802 from mikeash/concurrentreadablearray-operator-new-delete 2021-04-09 08:56:36 -07:00
Mike Ash
70354af2b5 [Runtime] Avoid operator new/delete in ConcurrentReadableArray.
The callbacks made in ImageInspectionMachO.cpp are called in a dangerous context, with the dyld and ObjC runtime locks held. C++ allows programs to overload the global operator new/delete, and there's no guarantee that those overloads behave. Ideally, we'd avoid them entirely, but that's a bigger job. For now, avoid the worst trouble by avoiding STL and new/delete in these callbacks. That use came from ConcurrentReadableArray's free list, so we switch that from a std::vector to a linked list.

rdar://75036800
2021-04-09 09:29:20 -04: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
Doug Gregor
eb6e74a0a6 Handle demangling/remangling for concurrency-related builtin types.
Fixes rdar://75990281.
2021-04-08 23:49:37 -07:00
John McCall
0242d7572e Delay deallocation of default actors when they're currently running.
For ordinary memory-management reasons, this should only ever
happen when there will be no more uses of the actor outside of the
actor runtime.  The actor runtime, meanwhile, doesn't care about
anything except the default-actor control state of the actor.  So
we can just allow the rest of the actor to be destructed when it
isn't needed anymore, then destroy the actor state and deallocate
the object when we get around to switching off the executor.

This does assume that the task doesn't do anything which semantically
detects the executor it's on before switching off it, since doing so
might read a bogus executor.  However, we should only get an executor
in a zombie state like this when a hop has been removed or reordered,
and detection events should count as inhibiting that and forcing the
true executor to be switched to (and thus detected).

(But maybe lifetime optimization can make this happen?  Maybe we
need semantic detection to filter out zombie executors.)
2021-04-08 12:57:12 -04:00
John McCall
156264f8e8 Make ExecutorRef two words. 2021-04-08 12:57:12 -04:00
Nate Chandler
d3e0e7af07 [ptrauth] Signed AsyncFunctionPointers as data.
Previously, AsyncFunctionPointer constants were signed as code.  That
was incorrect considering that these constants are in fact data.  Here,
that is fixed.

rdar://76118522
2021-04-05 18:24:41 -07:00
Konrad `ktoso` Malawski
a5ac6f06fa [Concurrency] detach, spawnUnlessCancelled, priority param cleanup 2021-04-03 09:54:42 +09:00
Mike Ash
e98fc3e304 Merge pull request #36572 from mikeash/async-task-dispatch-integration2
[Concurrency] Make Job objects work as Dispatch objects.
2021-03-31 09:42:58 -04:00
Richard Wei
d997526948 Fix function differentiability kind metadata and mangling. (#36601)
* Move differentiability kinds from target function type metadata to trailing objects so that we don't exhaust all remaining bits of function type metadata.
  * Differentiability kind is now stored in a tail-allocated word when function type flags say it's differentiable, located immediately after the normal function type metadata's contents (with proper alignment in between).
  * Add new runtime function `swift_getFunctionTypeMetadataDifferentiable` which handles differentiable function types.
* Fix mangling of different differentiability kinds in function types. Mangle it like `ConcurrentFunctionType` so that we can drop special cases for escaping functions.
    ```
    function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
    ...
    differentiable ::= 'jf'                    // @differentiable(_forward) on function type
    differentiable ::= 'jr'                    // @differentiable(reverse) on function type
    differentiable ::= 'jd'                    // @differentiable on function type
    differentiable ::= 'jl'                    // @differentiable(_linear) on function type
    ```

Resolves rdar://75240064.
2021-03-30 09:59:06 -07:00
John McCall
98711fd628 Revise the continuation ABI.
The immediate desire is to minimize the set of ABI dependencies
on the layout of an ExecutorRef.  In addition to that, however,
I wanted to generally reduce the code size impact of an unsafe
continuation since it now requires accessing thread-local state,
and I wanted resumption to not have to create unnecessary type
metadata for the value type just to do the initialization.

Therefore, I've introduced a swift_continuation_init function
which handles the default initialization of a continuation
and returns a reference to the current task.  I've also moved
the initialization of the normal continuation result into the
caller (out of the runtime), and I've moved the resumption-side
cmpxchg into the runtime (and prior to the task being enqueued).
2021-03-28 12:58:16 -04:00
Mike Ash
0989524338 [Concurrency] Make Job objects work as Dispatch objects.
Fill out the metadata for Job to have a Dispatch-compatible vtable. When available, use the dispatch_enqueue_onto_queue_4Swift to enqueue Jobs directly onto queues. Otherwise, keep using dispatch_async_f as we have been.

rdar://75227953
2021-03-26 18:31:00 -04:00
Joe Groff
4150b31954 Fix calling convention for withCompletionHandler runtime calls.
rdar://75370240
2021-03-25 14:45:47 -07:00
Mike Ash
c4e4e44f71 Merge pull request #36390 from mikeash/concurrency-compatibility-overrides
[Concurrency] Add compatibility overrides to Concurrency library.
2021-03-24 13:07:07 -04:00
Evan Wilde
8f974c1a79 Merge pull request #36524 from etcwilde/ewilde/fix-after-main-crash
[Concurrency] Make asyncMainDrainQueue noreturn
2021-03-22 23:00:33 -07:00
Mike Ash
6aab257c33 [Concurrency] Add compatibility overrides to Concurrency library.
Take the existing CompatibilityOverride mechanism and generalize it so it can be used in both the runtime and Concurrency libraries. The mechanism is preprocessor-heavy, so this requires some tricks. Use the SWIFT_TARGET_LIBRARY_NAME define to distinguish the libraries, and use a different .def file and mach-o section name accordingly.

We want the global/main executor functions to be a little more flexible. Instead of using the override mechanism, we expose function pointers that can be set by the compatibility library, or by any other code that wants to use a custom implementation.

rdar://73726764
2021-03-22 11:09:06 -04:00
Evan Wilde
b0b4cb67a1 Make asyncMainDrainQueue noreturn
CFRunLoopRun returns once it finishes, though the kernel may clean us up
before we get there. We effectively have a race condition between the
kernel cleaning us up and returning from a never returning function.

Small programs likely get cleaned up before reaching the ud2 instruction
emitted after the never returning function in swift, so they don't
notice, but programs of a sufficient size do. At that size, the program
will crash after what the programmer expects to be the end of their
program.
2021-03-19 12:33:26 -07:00
Joe Groff
79fb05b362 Concurrency: Hop back to the previous executor after actor calls.
Tasks shouldn't normally hog the actor context indefinitely after making a call that's bound to
that actor, since that prevents the actor from potentially taking on other jobs it needs to
be able to address. Set up SILGen so that it saves the current executor (using a new runtime
entry point) and hops back to it after every actor call, not only ones where the caller context
is also actor-bound.

The added executor hopping here also exposed a bug in the runtime implementation while processing
DefaultActor jobs, where if an actor job returned to the processing loop having already yielded
the thread back to a generic executor, we would still attempt to make the actor give up the thread
again, corrupting its state.

rdar://71905765
2021-03-18 11:47:50 -07:00
Arnold Schwaighofer
f75fbb7594 IRGen: Async ABI passing parameter and results directly
The error is still passed in the async context. I will fix this in a
follow-up.
2021-03-17 07:41:01 -07:00
John McCall
6c879d6fd3 Change the async ABI to not pass the active task and executor.
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
2021-03-16 22:52:54 -04:00
Varun Gandhi
7e6fb9f127 Remove USE_SWIFT_ASYNC_LOWERING CMake setting.
It was added for staging; but that has been completed.
2021-03-12 10:51:08 -08:00
Joe Groff
872afda50b Merge pull request #36298 from jckarter/created-task-closure-context-leak
SIL: Clean up ownership handling in `createAsyncTask` builtins.
2021-03-09 14:17:13 -08:00
Joe Groff
d9798c0868 Concurrency: Redo non-_f variants of swift_task_create to accept closures as is.
In their previous form, the non-`_f` variants of these entry points were unused, and IRGen
lowered the `createAsyncTask` builtins to use the `_f` variants with a large amount of caller-side
codegen to manually unpack closure values. Amid all this, it also failed to make anyone responsible
for releasing the closure context after the task completed, causing every task creation to leak.
Redo the `swift_task_create_*` entry points to accept the two words of an async closure value
directly, and unpack the closure to get its invocation entry point and initial context size
inside the runtime. (Also get rid of the non-future `swift_task_create` variant, since it's unused
and it's subtly different in a lot of hairy ways from the future forms. Better to add it later
when it's needed than to have a broken unexercised version now.)
2021-03-08 16:54:19 -08:00
Joe Groff
016496384e Concurrency: Remove currently-unused non-_f variants of swift_task_create
I'm about to replace these with new variations that correctly handle spawning a task with
a closure as its initial entry point, without leaking or requiring large amounts of caller-side
code generation.
2021-03-05 12:01:06 -08:00
Dario Rexin
af4b6bc068 [Concurrency] Add asynchronous Task.sleep function 2021-03-04 09:37:58 -08:00