The way that we include COMPATIBILITY_OVERRIDE_INCLUDE_PATH freaks out the
syntax highlighting of editors like emacs. It causes the whole file to be
highlighted like it is part of the include string.
To work around this, this patch creates a separate file called
CompatibilityOverrideIncludePath.h that just includes
COMPATIBILITY_OVERRIDE_INCLUDE_PATH. So its syntax highlighting is borked, but
at least in the actual files that contain real code, the syntax highlighting is
restored.
Define `NOMINMAX` and `WIN32_LEAN_AND_MEAN` when including `<Windows.h>`.
Don't export the interface from DLLs.
Make sure we include `<new>` when using placement operator new.
rdar://135380149
`ExecutorHooks.h` is now nothing to do with hooks, so rename it. Also
there are some additional functions it should declare, and a couple of
places where we've slightly messed up the boundary, for instance
`swift_task_asyncMainDrainQueue` was defined in `Task.cpp` rather than
in the executor implementations, which is wrong, so fix that too.
`CooperativeGlobalExecutor.cpp` now builds against the interface from
`ExecutorImpl.h`, rather than including the all the concurrency headers.
rdar://135380149
C++ executor implementations were `#include`ed into `GlobalExecutor.cpp`,
which makes it difficult to replace the global executor when using the
Embedded Concurrency library. Refactor things so that they build into
separate objects, which means replacing them is just a matter of writing
the relevant functions yourself.
rdar://135380149
* [WIP] Initial draft at v2 Clock/Instant/Duration
* Ensure the literal types for _DoubleWide are able to be at least 64 bits on 32 bit platforms
* static cast timespec members to long
* Remove runtime exports from clock functions
* Export clock functions in implementations as they are in headers
* Clean up internal properties by adding leading underscores, refine availability to a TBD marker macro, and break at 80 lines to match style
* Shift operators to concrete Instant types to avoid complexity in solver resolution
* Adjust diagnostic note and error expectation of ambiguities to reflect new potential solver (perhaps incorrect) solutions
* Update stdlib/public/Concurrency/TaskSleep.swift
Co-authored-by: Karoy Lorentey <klorentey@apple.com>
* [stdlib][NFC] Remove trailing whitespace
* [stdlib] Remove _DoubleWidth from stdlib's ABI
* [stdlib] Strip downd _DoubleWidth to _[U]Int128
* Additional adjustments to diagnostic notes and errors expectation of ambiguities to reflect new potential solver (perhaps incorrect) solutions
* Disable type checker performance validation for operator overload inferences (rdar://33958047)
* Decorate Duration, DurationProtocol, Instant and clocks with @available(SwiftStdlib 9999, *)
* Restore diagnostic ambiguity test assertion (due to availability)
* Add a rough attempt at implementing time accessors on win32
* Remove unused clock id, rename SPI for swift clock ids and correct a few more missing availabilities
* remove obsolete case of realtime clock for dispatch after callout
* Use the default implementation of ~ for Int128 and UInt128
* Ensure diagnostic ambiguitiy applies evenly to all platforms and their resolved types
* Restore the simd vector build modifications (merge damage)
* Update to latest naming results for Instant.Duration
* Updates to latest proposal initializers and accessors and adjust encoding/decoding to string based serialization
* Update availability for Clock/Instant/Duration methods and types to be 5.7
* Correct *Clock.now to report via the correct runtime API
* Ensure the hashing of Duration is based upon the attoseconds hashing
* Avoid string based encoding and resort back to high and low bit encoding/decoding but as unkeyed
* Adjust naming of component initializer to use suffixes on parameters
* Duration decoding should use a mutable container for decoding
* fix up components initializer and decode access
* Add platform base initializers for timespec and tiemval to and from Duration
* Add some first draft documentation for standard library types Duration, DurationProtocol and InstantProtocol
* Another round of documentation prose and some drive-by availability fixes
* InstantProtocol availability should be 5.7
* Correct linux timeval creation to be Int and not Int32
Co-authored-by: Karoy Lorentey <klorentey@apple.com>
Each trace point is declared as a function in the new `Tracing.h` header. These functions are called from the appropriate places in the concurrency runtime.
On Darwin, an implementation of these functions is provided which uses the `os/signpost.h` API to emit signpost events/intervals.
When the signpost API is not available, no-op stub implementations are provided. Implementations for other OSes can be provided by providing implementations of the trace functions for that OS.
rdar://81858487
The goal here is not to eventually implement a concurrent thread
pool ourselves. We're just making it easier for integrators who
have their own pool and don't want to use Dispatch to build the
Swift concurrency runtime. Just hook the right functions and
you should be fine.
The necessary functions to hook are:
- swift_task_enqueueGlobal
- swift_task_enqueueGlobalAfterDelay
The following functions *would* be necessary to hook:
- swift_task_enqueueMainExecutor
- swift_task_asyncMainDrainQueue (only if you have an async main?)
However, this configuration does not currently properly support
the main executor, and so `@MainActor` should be avoided for now.
rdar://83513751
The goal here is not to eventually implement a concurrent thread
pool ourselves. We're just making it easier for integrators who
have their own pool and don't want to use Dispatch to build the
Swift concurrency runtime. Just hook the right functions and
you should be fine.
The necessary functions to hook are:
- swift_task_enqueueGlobal
- swift_task_enqueueGlobalAfterDelay
The following functions *would* be necessary to hook:
- swift_task_enqueueMainExecutor
- swift_task_asyncMainDrainQueue (only if you have an async main?)
However, this configuration does not currently properly support
the main executor, and so `@MainActor` should be avoided for now.
rdar://83513751
This patch repairs the build failure for cooperative executor.
And also fixed main executor to avoid assertion failure due to
`witnessTable == nullptr`
Older Dispatch versions have width-limited concurrent queues. While not
as good as the newly-introduced cooperative queues, they at least
address the thread-explosion problem, so use them in the back-deployed
concurrency libraries.
Implements rdar://81131034.
`SWIFT_STDLIB_SINGLE_THREADED_RUNTIME` mode has been broken for a long time.
This patch guards some includes and use of libdispatch headers so that platforms
that doesn't support libdispatch can build cooperative executor runtime.
And fixed missing implementations for cooperative mode.
* Synchronize both versions of actor_counters.swift test
* Synchronize on Job address
Make sure to synchronize on Job address (AsyncTasks are Jobs, but not
all Jobs are AsyncTasks).
* Add fprintf debug output for TSan acquire/release
* Add tsan_release edge on task creation
without this, we are getting false data races between when a task
is created and immediately scheduled on a different thread.
False positive for `Sanitizers/tsan/actor_counters.swift` test:
```
WARNING: ThreadSanitizer: data race (pid=81452)
Read of size 8 at 0x7b2000000560 by thread T5:
#0 Counter.next() <null>:2 (a.out:x86_64+0x1000047f8)
#1 (1) suspend resume partial function for worker(identity:counters:numIterations:) <null>:2 (a.out:x86_64+0x100005961)
#2 swift::runJobInEstablishedExecutorContext(swift::Job*) <null>:2 (libswift_Concurrency.dylib:x86_64+0x280ef)
Previous write of size 8 at 0x7b2000000560 by main thread:
#0 Counter.init(maxCount:) <null>:2 (a.out:x86_64+0x1000046af)
#1 Counter.__allocating_init(maxCount:) <null>:2 (a.out:x86_64+0x100004619)
#2 runTest(numCounters:numWorkers:numIterations:) <null>:2 (a.out:x86_64+0x100006d2e)
#3 swift::runJobInEstablishedExecutorContext(swift::Job*) <null>:2 (libswift_Concurrency.dylib:x86_64+0x280ef)
#4 main <null>:2 (a.out:x86_64+0x10000a175)
```
New edge with this change:
```
[4357150208] allocate task 0x7b3800000000, parent = 0x0
[4357150208] creating task 0x7b3800000000 with parent 0x0
[4357150208] tsan_release on 0x7b3800000000 <<< new release edge
[139088221442048] tsan_acquire on 0x7b3800000000
[139088221442048] trying to switch from executor 0x0 to 0x7ff85e2d9a00
[139088221442048] switch failed, task 0x7b3800000000 enqueued on executor 0x7ff85e2d9a00
[139088221442048] enqueue job 0x7b3800000000 on executor 0x7ff85e2d9a00
[139088221442048] tsan_release on 0x7b3800000000
[139088221442048] tsan_release on 0x7b3800000000
[4357150208] tsan_acquire on 0x7b3800000000
counters: 1, workers: 1, iterations: 1
[4357150208] allocate task 0x7b3c00000000, parent = 0x0
[4357150208] creating task 0x7b3c00000000 with parent 0x0
[4357150208] tsan_release on 0x7b3c00000000 <<< new release edge
[139088221442048] tsan_acquire on 0x7b3c00000000
[4357150208] task 0x7b3800000000 waiting on task 0x7b3c00000000, going to sleep
[4357150208] tsan_release on 0x7b3800000000
[4357150208] tsan_release on 0x7b3800000000
[139088221442048] getting current executor 0x0
[139088221442048] tsan_release on 0x7b3c00000000
...
```
rdar://78932849
* Add static_cast<Job *>()
* Move TSan release edge to swift_task_enqueueGlobal()
Move the TSan release edge from `swift_task_create_commonImpl()` to
`swift_task_enqueueGlobalImpl()`. Task creation itself is not an event
that needs synchronization, but rather that task creation "happens
before" execution of that task on another thread.
This edge is usually added when the task is scheduled via
`swift_task_enqueue()` (which then usually calls
`swift_task_enqueueGlobal()`). However, not all task scheduling goes
through the `swift_task_enqueue()` funnel as some places call the more
specific `swift_task_enqueueGlobal()` directly. So let's annotate this
function (duplicate edges aren't harmful) to ensure we cover all
schedule events, including newly-created tasks (our original problem
here).
rdar://78932849
Co-authored-by: Julian Lettner <julian.lettner@apple.com>
I added Builtin.buildMainActorExecutor before, but because I never
implemented it correctly in IRGen, it's not okay to use it on old
versions, so I had to introduce a new feature only for it.
The shim dispatch queue class in the Concurrency runtime is rather
awful, but I couldn't think of a reasonable alternative without
just entirely hard-coding the witness table in the runtime.
It's not ABI, at least.
We pass swift_task_enqueueGlobal as the original implementation, but that would recurse. We need to pass swift_task_enqueueGlobalImpl instead.
rdar://78780136
Both swiftRuntime and swift_Concurrency had swift::fatalError
implementation, but it causes symbol conflict when -static-stdlib.
This patch renames one of the impl in swift_Concurrency to avoid
conflict.
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
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
Create a TargetDispatchClassMetadata for Swift metadata that also has a dispatch-compatible vtable. Dispatch leaves room for ObjC class metadata so the two regions don't overlap. (The vtable currently consists of a single dummy entry; this will be filled out later.)
Rearrange the Job and AsyncTask hierarchy so that AsyncTask inherits only from Job, which in turn inherits from HeapObject. This gives all Job instances a dispatch-compatible isa field. It also gives them a refcount word, which is wasted on instances that aren't AsyncTask instances. Maybe we can find some use for that space in the future.
rdar://75227953
Currently, the only thing in the system that donates a thread
to run it is swift_runAndBlockThread, but we'll probably need
others. Nothing in the concurrency runtime should block via a
semaphore in this configuration.
As an outrageous hack, work around the layering problems with
using libdispatch from the concurrency library on non-Darwin
systems by making those systems use the cooperative global
executor. This is only acceptable as a temporary solution
for landing this change and setting things onto the right
long-term design.
We expect to iterate on this quite a bit, both publicly
and internally, but this is a fine starting-point.
I've renamed runAsync to runAsyncAndBlock to underline
very clearly what it does and why it's not long for this
world. I've also had to give it a radically different
implementation in an effort to make it continue to work
given an actor implementation that is no longer just
running all work synchronously.
The major remaining bit of actor-scheduling work is to
make swift_task_enqueue actually do something sensible
based on the executor it's been given; currently it's
expecting a flag that IRGen simply doesn't know to set.