Commit Graph

1544 Commits

Author SHA1 Message Date
Dario Rexin
af4b6bc068 [Concurrency] Add asynchronous Task.sleep function 2021-03-04 09:37:58 -08:00
Konrad `ktoso` Malawski
aedbbe615d [TaskGroup] Towards ABI stability of groups 2021-03-02 20:25:22 +09:00
Konrad `ktoso` Malawski
d7169edc21 [TaskLocals] Cleanly separate locals impl from Task, no need for fragment 2021-03-02 00:54:47 +09:00
Konrad `ktoso` Malawski
1cb3000a7e [TaskGroup] group is not NativeObject, just an opqeue value 2021-02-26 16:03:30 +09:00
Konrad `ktoso` Malawski
cdd136096f reworked includes to stop hitting undefined symbols 2021-02-25 15:15:02 +09:00
Konrad `ktoso` Malawski
599572ba54 cleanups of tests after merge 2021-02-25 14:24:43 +09:00
Konrad `ktoso` Malawski
6e525d7469 Merge branch 'main' into wip-no-escape-group 2021-02-25 10:37:20 +09:00
Konrad `ktoso` Malawski
dd9a9a6436 [Concurrency] Task APIs use thread-local ActiveTask now 2021-02-24 19:19:44 +09:00
Konrad `ktoso` Malawski
de5fdcd2f8 [TaskGroup] fix missing retain in scheduling next() immediately on offer 2021-02-24 18:45:33 +09:00
Konrad `ktoso` Malawski
655d8f13e7 cleanup after rebase; this is likely incorrect in some way 2021-02-24 12:10:49 +09:00
Konrad `ktoso` Malawski
6f4fca8721 Merge branch 'main' into wip-no-escape-group 2021-02-24 08:59:53 +09:00
John McCall
2012195cd5 Alter the runtime interface for awaiting futures and task groups.
First, just call an async -> T function instead of forcing the caller
to piece together which case we're in and perform its own copy.  This
ensures that the task is actually kept alive properly.

Second, now that we no longer implicitly depend on the waiting tasks
being run synchronously, go ahead and schedule them to run on the
global executor.

This solves some problems which were blocking the work on TLS-ifying
the task/executor state.
2021-02-21 23:48:13 -05:00
John McCall
1c82c71486 Make an Error.h that declares the public ABI for errors.
NFC except that I added swift_errorRetain and swift_errorRelease
functions on non-ObjC targets so that we have consistent
functions to call in the runtime.  I have not changed everywhere
in the runtime to use these, nor have I changed the compiler to
call them.
2021-02-21 23:45:07 -05:00
Konrad `ktoso` Malawski
4483ac814f [Concurrency] implement withCancellationHandler via records 2021-02-22 13:26:33 +09:00
Konrad `ktoso` Malawski
3132009929 [Concurrency] Track group children in task record + invasive links 2021-02-22 13:26:33 +09:00
Konrad `ktoso` Malawski
1c4655df6a [Concurrency] track child tasks from group in Task records 2021-02-22 13:26:33 +09:00
Konrad `ktoso` Malawski
1860b20cb7 [Concurrency] cancel all child tasks of a group on cancelAll 2021-02-22 13:26:27 +09:00
Konrad `ktoso` Malawski
a100424b4a getting there with assuming that poll is a single task 2021-02-22 13:26:27 +09:00
Konrad `ktoso` Malawski
a226259d84 [Concurrency] TaskGroup moves out of AsyncTask, non escaping body 2021-02-22 13:26:27 +09:00
John McCall
8e9823c369 Store the current task and executor in task-local storage. 2021-02-21 21:39:14 -05:00
Arnold Schwaighofer
4373bdd6d0 Conditionally start using llvm::CallingConv::SwiftTail for async functions
This is conditional on UseAsyncLowering and in the future should also be
conditional on `clangTargetInfo.isSwiftAsyncCCSupported()` once that
support is merged.

Update tests to work either with swiftcc or swifttailcc.
2021-02-18 09:25:15 -08:00
Konrad `ktoso` Malawski
40b6b18945 [Concurrency] implement withCancellationHandler via records 2021-02-18 17:27:15 +09:00
Varun Gandhi
43eb31eb27 [Concurrency] Guard use of async calling convention.
Certain targets don't support the async calling convention, so we first
add the feature check to avoid breaking the codegen/runtime while doing
gradual rollout for different targets.
2021-02-17 10:06:04 -08:00
Konrad `ktoso` Malawski
d2bd6abe61 [Concurrency] TaskLocals allow configuring inheritance: never 2021-02-13 20:09:11 +09:00
Konrad `ktoso` Malawski
b811b12246 [Concurrency] TaskLocals lookup "skip" optimization 2021-02-13 10:39:22 +09:00
Konrad `ktoso` Malawski
1044723787 [Concurrency] Initial Task Local Values implementation 2021-02-13 10:39:22 +09:00
Andrew Trick
29b9e51cb6 Remove ReadNone attribute from runtime functions
The Swift compiler incorrectly sets the LLVM "ReadNone" attribute when
declaring swift_getObjCClassFromObject and swift_projectBox. This
means that the LLVM ARC optimizer will hoist ARC "release" operations
above these runtime calls. Since the implementation of the calls reads
the object, this causes a use-after-free crash.

This problem is easy to reproduce with
swift_getObjCClassFromObject. It was only exposed recently because the
SIL optimizer now shrinks object lifetimes, making it easier for LLVM
optimizations to kick in. It is difficult to expose the problem with
swift_projectBox, but the bug/fix is still obvious.

Fixes rdar://73820091: Use-after free application crash.
2021-02-08 14:53:24 -08:00
Nate Chandler
c59b01feee [Runtime] Ptrauth for runAsyncAndBlock.
rdar://72357371
2021-02-04 20:19:26 -08:00
tbkka
a32dacb131 SwiftDtoa v2: Better, Smaller, Faster floating-point formatting (#35299)
* SwiftDtoa v2: Better, Smaller, Faster floating-point formatting

SwiftDtoa is the C/C++ code used in the Swift runtime to produce the textual representations used by the `description` and `debugDescription` properties of the standard Swift floating-point types.
This update includes a number of algorithmic improvements to SwiftDtoa to improve portability, reduce code size, and improve performance but does not change the actual output.

About SwiftDtoa
===============

In early versions of Swift, the `description` properties used the C library `sprintf` functionality with a fixed number of digits.
In 2018, that logic was replaced with the first version of SwiftDtoa which used used a fast, adaptive algorithm to automatically choose the correct number of digits for a particular value.
The resulting decimal output is always:

* Accurate.  Parsing the decimal form will yield exactly the same binary floating-point value again. This guarantee holds for any parser that accurately implements IEEE 754. In particular, the Swift standard library can guarantee that for any Double `d` that is not a NaN, `Double(d.description) == d`.

* Short. Among all accurate forms, this form has the fewest significant digits. (Caution: Surprisingly, this is not the same as minimizing the number of characters. In some cases, minimizing the number of characters requires producing additional significant digits.)

* Close. If there are multiple accurate, short forms, this code chooses the decimal form that is closest to the exact binary value.  If there are two exactly the same distance, the one with an even final digit will be used.

Algorithms that can produce this "optimal" output have been known since at least 1990, when Steele and White published their Dragon4 algorithm.
However, Dragon4 and other algorithms from that period relied on high-precision integer arithmetic, which made them slow.
More recently, a surge of interest in this problem has produced dramatically better algorithms that can produce the same results using only fast fixed-precision arithmetic.

This format is ideal for JSON and other textual interchange: accuracy ensures that the value will be correctly decoded, shortness minimizes network traffic, and the existence of high-performance algorithms allows this form to be generated more quickly than many `printf`-based implementations.

This format is also ideal for logging, debugging, and other general display. In particular, the shortness guarantee avoids the confusion of unnecessary additional digits, so that the result of `1.0 / 10.0` consistently displays as `0.1` instead of `0.100000000000000000001`.

About SwiftDtoa v2
==================

Compared to the original SwiftDtoa code, this update is:

**Better**:
The core logic is implemented using only C99 features with 64-bit and smaller integer arithmetic.
If available, 128-bit integers are used for better performance.
The core routines do not require any floating-point support from the C/C++ standard library and with only minor modifications should be usable on systems with no hardware or software floating-point support at all.
This version also has experimental support for IEEE 754 binary128 format, though this support is obviously not included when compiling for the Swift standard library.

**Smaller**:
Code size reduction compared to the earlier versions was a primary goal for this effort.
In particular, the new binary128 support shares essentially all of its code with the float80 implementation.

**Faster**:
Even with the code size reductions, all formats are noticeably faster.
The primary performance gains come from three major changes:
Text digits are now emitted directly in the core routines in a form that requires only minimal adjustment to produce the final text.
Digit generation produces 2, 4, or even 8 digits at a time, depending on the format.
The double logic optimistically produces 7 digits in the initial scaling with a Ryu-inspired backtracking when fewer digits suffice.

SwiftDtoa's algorithms
======================

SwiftDtoa started out as a variation of Florian Loitsch' Grisu2 that addressed the shortness failures of that algorithm.
Subsequent work has incorporated ideas from Errol3, Ryu, and other sources to yield a production-quality implementation that is performance- and size-competitive with current research code.

Those who wish to understand the details can read the extensive comments included in the code.
Note that float16 actually uses a different algorithm than the other formats, as the extremely limited range can be handled with much simpler techniques.
The float80/binary128 logic sacrifices some performance optimizations in order to minimize the code size for these less-used formats; the goal for SwiftDtoa v2 has been to match the float80 performance of earlier implementations while reducing code size and widening the arithmetic routines sufficiently to support binary128.

SwiftDtoa Testing
=================

A newly-developed test harness generates several large files of test data that include known-correct results computed with high-precision arithmetic routines.
The test files include:
* Critical values generated by the algorithm presented in the Errol paper (about 48 million cases for binary128)
* Values for which the optimal decimal form is exactly midway between two binary floating-point values.
* All exact powers of two representable in this format.
* Floating-point values that are close to exact powers of ten.

In addition, several billion random values for each format were compared to the results from other implementations.
For binary16 and binary32 this provided exhaustive validation of every possible input value.

Code Size and Performance
=========================

The tables below summarize the code size and performance for the SwiftDtoa C library module by itself on several different processor architectures.
When used from Swift, the `.description` and `.debugDescription` implementations incur additional overhead for creating and returning Swift strings that are not captured here.

The code size tables show the total size in bytes of the compiled `.o` object files for a particular version of that code.
The headings indicate the floating-point formats supported by that particular build (e.g., "16,32" for a version that supports binary16 and binary32 but no other formats).

The performance numbers below were obtained from a custom test harness that generates random bit patterns, interprets them as the corresponding floating-point value, and averages the overall time.
For float80, the random bit patterns were generated in a way that avoids generating invalid values.

All code was compiled with the system C/C++ compiler using `-O2` optimization.

A few notes about particular implementations:
* **SwiftDtoa v1** is the original SwiftDtoa implementation as committed to the Swift runtime in April 2018.
* **SwiftDtoa v1a** is the same as SwiftDtoa v1 with added binary16 support.
* **SwiftDtoa v2** can be configured with preprocessor macros to support any subset of the supported formats.  I've provided sizes here for several different build configurations.
* **Ryu** (Ulf Anders) implements binary32 and binary64 as completely independent source files.  The size here is the total size of the two .o object files.
* **Ryu(size)** is Ryu compiled with the `RYU_OPTIMIZE_SIZE` option.
* **Dragonbox** (Junekey Jeon).  The size here is the compiled size of a simple `.cpp` file that instantiates the template for the specified formats, plus the size of the associated text output logic.
* **Dragonbox(size)** is Dragonbox compiled to minimize size by using a compressed power-of-10 table.
* **gdtoa** has a very large feature set.  For this reason, I excluded it from the code size comparison since I didn't consider the numbers to be comparable to the others.

x86_64
----------------

These were built using Apple clang 12.0.5 on a 2019 16" MacBook Pro (2.4GHz 8-core Intel Core i9) running macOS 11.1.

**Code Size**

Bold numbers here indicate the configurations that have shipped as part of the Swift runtime.

|               | 16,32,64,80 | 32,64,80    | 32,64       |
|---------------|------------:|------------:|------------:|
|SwiftDtoa v1   |             |   **15128** |             |
|SwiftDtoa v1a  |   **16888** |             |             |
|SwiftDtoa v2   |   **20220** |     18628   |        8248 |
|Ryu            |             |             |       40408 |
|Ryu(size)      |             |             |       23836 |
|Dragonbox      |             |             |       23176 |
|Dragonbox(size)|             |             |       15132 |

**Performance**

|              | binary16 | binary32 | binary64 | float80 | binary128 |
|--------------|---------:|---------:|---------:|--------:|----------:|
|SwiftDtoa v1  |          |     25ns |     46ns |    82ns |           |
|SwiftDtoa v1a |     37ns |     26ns |     47ns |    83ns |           |
|SwiftDtoa v2  |     22ns |     19ns |     31ns |    72ns |      90ns |
|Ryu           |          |     19ns |     26ns |         |           |
|Ryu(size)     |          |     17ns |     24ns |         |           |
|Dragonbox     |          |     19ns |     24ns |         |           |
|Dragonbox(size) |        |     19ns |     29ns |         |           |
|gdtoa         |    220ns |    381ns |   1184ns | 16044ns |   22800ns |

ARM64
----------------

These were built using Apple clang 12.0.0 on a 2020 M1 Mac Mini running macOS 11.1.

**Code Size**

|               | 16,32,64 | 32,64 |
|---------------|---------:|------:|
|SwiftDtoa v1   |          |  7436 |
|SwiftDtoa v1a  |     9124 |       |
|SwiftDtoa v2   |     9964 |  8228 |
|Ryu            |          | 35764 |
|Ryu(size)      |          | 16708 |
|Dragonbox      |          | 27108 |
|Dragonbox(size)|          | 19172 |

**Performance**

|              | binary16 | binary32 | binary64 | float80 | binary128 |
|--------------|---------:|---------:|---------:|--------:|----------:|
|SwiftDtoa v1  |          |     21ns |     39ns |         |           |
|SwiftDtoa v1a |     17ns |     21ns |     39ns |         |           |
|SwiftDtoa v2  |     15ns |     17ns |     29ns |    54ns |      71ns |
|Ryu           |          |     15ns |     19ns |         |           |
|Ryu(size)     |          |     29ns |     24ns |         |           |
|Dragonbox     |          |     16ns |     24ns |         |           |
|Dragonbox(size) |        |     15ns |     34ns |         |           |
|gdtoa         |    143ns |    242ns |    858ns | 25129ns |   36195ns |

ARM32
----------------

These were built using clang 8.0.1 on a BeagleBone Black (500MHz ARMv7) running FreeBSD 12.1-RELEASE.

**Code Size**

|               | 16,32,64 | 32,64 |
|---------------|---------:|------:|
|SwiftDtoa v1   |          |  8668 |
|SwiftDtoa v1a  |    10356 |       |
|SwiftDtoa v2   |     9796 |  8340 |
|Ryu            |          | 32292 |
|Ryu(size)      |          | 14592 |
|Dragonbox      |          | 29000 |
|Dragonbox(size)|          | 21980 |

**Performance**

|              | binary16 | binary32 | binary64 | float80 | binary128 |
|--------------|---------:|---------:|---------:|--------:|----------:|
|SwiftDtoa v1  |          |    459ns |   1152ns |         |           |
|SwiftDtoa v1a |    383ns |    451ns |   1148ns |         |           |
|SwiftDtoa v2  |    202ns |    357ns |    715ns |  2720ns |    3379ns |
|Ryu           |          |    345ns |   5450ns |         |           |
|Ryu(size)     |          |    786ns |   5577ns |         |           |
|Dragonbox     |          |    300ns |    904ns |         |           |
|Dragonbox(size) |        |    294ns |   1021ns |         |           |
|gdtoa         |   2180ns |   4749ns |  18742ns |293000ns |  440000ns |

* This is fast enough now even for non-optimized test runs

* Fix float80 Nan/Inf parsing, comment more thoroughly
2021-01-27 14:35:55 -08:00
Arnold Schwaighofer
b0d31730de Merge pull request #35303 from aschwaighofer/introduce_swiftasync_lowering
Add llvm::Attribute::SwiftAsync to the context parameter
2021-01-26 06:03:19 -08:00
Saleem Abdulrasool
8b5869ce62 Merge pull request #35566 from mikeash/whoops-i-did-it-again
[Runtime] #ifdef __clang__ on printf __attribute__ in Portability.h
2021-01-22 20:00:12 -08:00
Mike Ash
c673c13548 [Runtime] #ifdef __clang__ on printf __attribute__ in Portability.h 2021-01-22 19:36:28 -05:00
Konrad `ktoso` Malawski
80ee936a72 Revert "[Concurrency] isCanceled spelling to follow guidance" 2021-01-23 07:27:34 +09:00
Mike Ash
4988127e99 Merge pull request #35525 from mikeash/swift_asprintf-static-checking
[Runtime] Mark swift_asprintf with __attribute__((__format__))
2021-01-22 15:04:39 -05:00
Arnold Schwaighofer
daa72d3cc5 Add llvm::Attribute::SwiftAsync to the context parameter
* Adds support for generating code that uses swiftasync parameter lowering.

* Currently only arm64's llvm lowering supports the swift_async_context_addr intrinsic.

* Add arm64e pointer signing of updated swift_async_context_addr.

This commit needs the PR llvm-project#2291.

* [runtime] unittests should use just-built compiler if the runtime did

This will start to matter with the introduction of usage of swiftasync parameters which only very recent compilers support.

rdar://71499498
2021-01-22 10:01:55 -08:00
Mike Ash
216e555ad6 [Runtime] Mark swift_asprintf with __attribute__((__format__))
This gives us build-time warnings about format string mistakes, like we would get if we called the built-in asprintf directly.

Make TypeLookupError's format string constructor a macro instead so that its callers can get these build-time warnings.

This reveals various mistakes in format strings and arguments in the runtime, which are now fixed.

rdar://73417805
2021-01-22 10:54:45 -05:00
Konrad `ktoso` Malawski
8b37455774 [Concurrency] isCanceled spelling to follow guidance 2021-01-22 12:09:19 +09:00
Evan
4f708fad7e Merge pull request #35215 from etcwilde/ewilde/async-main
Adding async-main support

Resolves: rdar://71828636
2021-01-15 10:57:14 -08:00
Kavon Farvardin
91e2246c19 quick-and-dirty implementation of MainActor in the runtime system
it is "dirty" in the sense that we don't have proper support for
custom executors right now.
2021-01-14 17:43:58 -08:00
Evan Wilde
6b16657922 Explode on uncaught error thrown in main
This patch has two desirable effects for the price of one.
 1. An uncaught error thrown from main will now explode
 2. Move us off of using runAsyncAndBlock

The issue with runAsyncAndBlock is that it blocks the main thread
outright. UI and the main actor need to run on the main thread or bad
things happen, so blocking the main thread results in a bad day for
them.

Instead, we're using CFRunLoopRun to run the core-foundation run loop on
the main thread, or, dispatch_main if CFRunLoopRun isn't available.
The issue with just using dispatch_main is that it doesn't actually
guarantee that it will run the tasks on the main thread either, just
that it clears the main queue. We don't want to require everything that
uses concurrency to have to include CoreFoundation either, but dispatch
is already required, which supplies dispatch_main, which just empties
out the main queue.
2021-01-13 15:49:28 -08:00
Mike Ash
1557dbcb86 [Runtime] Make Concurrent.h ReaderCount loads seq_cst as well since they need to be ordered with the emplacement of new storage pointers. 2021-01-12 16:46:08 -05:00
Mike Ash
29c9f2af52 Merge pull request #35348 from mikeash/fix-concurrentarray-memory-order2
[Runtime] Fix incorrect memory ordering in ConcurrentReadableArray/HashMap
2021-01-12 14:44:43 -05:00
Mike Ash
ef8d20a0e6 [Runtime] Fix incorrect memory ordering in ConcurrentReadableArray/HashMap.
When reallocating storage, the storing the pointer to the new storage had insufficiently strong ordering. This could cause writers to check the reader count before storing the new storage pointer. If a reader then came in between that load and store, it would end up using the old storage pointer, while the writer could end up freeing it.

Also adjust the Concurrent.cpp tests to test with a variety of reader and writer counts. Counterintuitively, when freeing garbage is gated on there being zero readers, having a single reader will shake out problems that having lots of readers will not. We were testing with lots of readers in order to stress the code as much as possible, but this resulted in it being extremely rare for writers to ever see zero active readers.

rdar://69798617
2021-01-12 10:41:56 -05:00
Joe Groff
f2d28cfc12 Merge pull request #35188 from jckarter/checked-continuation
Concurrency: Introduce a `CheckedContinuation` adapter.
2021-01-11 13:39:34 -08:00
Mike Ash
13f84ddd7e [Runtime] Fix premature snapshot destruction in StableAddressConcurrentReadableHashMap::find.
Mark the relevant snapshot methods as ref-qualified (adding a & after the parameter list) so the compiler will enforce this for us and forbid calling them on temporaries.

rdar://72997638
2021-01-11 10:59:08 -05:00
Joe Groff
c151f4b02b Concurrency: Introduce a CheckedContinuation adapter.
To help catch runtime issues adopting `withUnsafeContinuation`, such as callback-based APIs that misleadingly
invoke their callback multiple times and/or not at all, provide a couple of classes that can take ownership of
a fresh `UnsafeContinuation` or `UnsafeThrowingContinuation`, and log attempts to resume the continuation multiple times
or discard the object without ever resuming the continuation.
2021-01-08 13:50:42 -08:00
Mike Ash
4ccfdfb72a [Runtime] Fix StableAddressConcurrentReadableHashMap threading crash.
StableAddressConcurrentReadableHashMap::getOrInsert had a race condition in the first lookup, where the snapshot was destroyed before the pointer was extracted from the returned wrapper. Fix this by creating the snapshot outside the if so that it stays alive.

rdar://problem/71932487
2020-12-21 16:52:56 -05:00
Konrad `ktoso` Malawski
b267778bf1 Rebased to use new global executor 2020-12-17 06:05:13 +09:00
Konrad `ktoso` Malawski
9e1ecc539c [Concurrency] guard offer/poll with a lock for now; cleanups 2020-12-17 06:05:13 +09:00
Konrad `ktoso` Malawski
7b37554096 [Concurrency] Initial TaskGroup implementation working 2020-12-17 06:05:13 +09:00