Commit Graph

1884 Commits

Author SHA1 Message Date
Cory Benfield c9fb1c23a1
Avoid syncShutdownGracefully knowing about MTELG. (#1904)
Motivation:

As part of the ongoing split of NIO into two components, we need to
decouple EventLoopGroup from MultiThreadedEventLoopGroup. This is
largely straightforward, but EventLoopGroup.syncShutdownGracefully uses
a hook on MTELG to try to provide debugging help.

That hook cannot stand, so we must break it. Unfortunately this slightly
reduces our ability to detect possible blocks of a SelectableEventLoop,
but in return we get to increase our ability to detect blocks of other
event loop groups.

Modifications:

- Added a debugging hook to detect possible blocking of event loops.

Result:

Less coupling.
2021-07-20 13:22:41 +01:00
Cory Benfield d0e54e9d7e
Provide a fallback date for new files. (#1903)
Motivation:

The test generation script automatically fills in the dates for the
autogenerated test files. Unfortunately, it doesn't tolerate a brand-new
file very well and puts in year zero. That's not right.

Modifications:

Default to the current year if no years are present.

Result:

Better default dates.
2021-07-20 11:35:00 +01:00
Cory Benfield 3e94fb4504
Enable all EventLoops to track promise creation. (#1899)
Motivation:

EventLoopFuture is capable of tracking where it was allocated from in
debug mode, to enable high-fidelity tracking of leaked promises.
Currently this behaviour is limited to SelectableEventLoop, but there is
no good reason to tie it so specifically to that loop.

Modifications:

- Extend `EventLoop` to allow all event loops to track promise
  allocation and destruction.
- Add helpers to `EmbeddedEventLoop` to let it participate.
- Add new type to express a future ID.

Result:

Wider support for diagnostics.
2021-07-16 13:26:28 +01:00
Cory Benfield 58ae43e99f
Avoid EventLoopFuture.wait knowing about specific implementations. (#1900)
Motivation:

As we break apart NIO, it's a bit awkward that EventLoopFuture.wait
knows about two specific EventLoop implementations. It does this in
order to detect deadlocks, so we should try to preserve the capability
as best as possible.

Modifications:

- Add EventLoop._preconditionSafeToWait, which can reproduce much of the
  logic currently in EventLoopFuture.wait().
- Provide implementations for SelectableEventLoop and EmbeddedEventLoop.

Result:

Partial reproduction of the current behaviour of EventLoopFuture.wait().
Unfortunately this cannot completely reimplement this behaviour, as we
cannot safely call MultiThreadedEventLoopGroup.currentEventLoop for all
event loops. This is as close as we can safely get without breaking the
abstraction boundary, sadly.
2021-07-16 10:18:34 +01:00
Cory Benfield f607e5a47c
Extract basic data structures to NIOCore. (#1895)
Motivation:

Currently the "core" NIO module (currently called NIO) contains two
fairly distinct kinds of things. The first is the core abstractions and
data structures: the things that all NIO programs must necessarily deal
with. This includes our base abstraction protocols (e.g. `EventLoop`,
`Channel`, and `ChannelHandler`), as well as our base data types (e.g.
`ByteBuffer`, `SocketAddress`, `EventLoopFuture`).

The second thing the core NIO module contains is the default POSIX
sockets event-loop and channels. These are the mainline production loops
for NIO programs, and are supported in the various BSD-like OSes to
varying extents. These can be thought of as a baseline implementation of
the core abstraction protocols that form the first part of NIO.

These two fairly distinct use-cases have no particular reason to be
glued together, and in fact in gluing them together we have done a bit
of a disservice to our adopters. The biggest issue is that it has become
impossible to write a NIO program or library that does not bring along
the POSIX layer of NIO. This has made porting NIO to other platforms
difficult (Windows has been painful, and Webassembly is coming down the
road as well), and has also bloated the size of iOS/macOS applications
that use NIO via NIOTransportServices, as all of these applications must
bring along an event loop and several Channels they will not use.

To that end, we plan to begin a scope of work to split the core NIO
module in two. Specifically, we intend to extract the baseline protocols
and data types into a new module, called `NIOCore`, which will be able
to be the baseline NIO module.

The end goal is that libraries that implement protocols on top of
SwiftNIO should be able to depend solely on `NIOCore`, not `NIO`. This
will allow NIO applications to bring along only the event loops they
want or need, without needing to pay for the POSIX sockets
implementation. This should also make porting easier, as there will be
no pressure to bring the existing `NIO` module to new platforms if it
does not fit well.

Modifications:

This is the first in a series of patches, which extracts some of the
low-hanging fruit. In particular, it extracts:

- `ByteBuffer` (and associated types)
- `RecvByteBufferAllocator`
- `CircularBuffer`

This also adds in the backwards compatibility shim: the `NIO` package
performs an exported import of `NIOCore`. This will allow this change to
avoid breaking API.

However, to make a clean break we intend not to release a new NIO minor
version until we have completed our extraction. If we fail to do this it
won't be the end of the world, we can release subsequent minor versions
that continue to extract new types. However, as much as possible should
go at once.

This patch also duplicates a few methods and files. At the end of the
patch series we need to reconcile this duplication. In many cases the
duplication will no longer be necessary, but in some cases we may have
necessary duplicates.

Result:

The first step along the road to better platform citizenship is taken.
2021-07-14 09:58:25 +01:00
Matt Eaton 3873886ebd
issue-1036: Fix for dates on Linux test generation script. (#1894)
* issue-1036: Fix for dates on Linux test generation script.

Motivation:

Fix for issue-1036 to add a date or date range for the header.
These dates are derived from the git log on the file.

Modifications:

Parsing method to extract the date or date range from the git log
of the file.  This was added to generate_linux_tests.

Result:

Dynamic date or date range added to the file header.

* issue-1036: Added revised headers from generation script

* Regenerating dates on XCTests.

Motivation:

Addressing feedback from PR.

Modifications:

All of the XCTests now have -2021 as a header date attached to them.

Result:

Dates modified on the XCTests.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-07-13 14:31:01 +01:00
Johannes Weiss 87c532383a
remove NIO1 API shims (#1897)
Motivation:

The lastest NIO versions require Swift 5.2+ to compile. Given that
hopefully nobody ever created a NIO1 application for Swift 5.2+, I'd say
it's about time to remove the NIO1 API shims (and related docs).

Modification:

- remove the NIO1 API shims
- remove the migration docs

Result:

Less code.
2021-07-13 12:36:28 +01:00
Guillaume Lessard 69f1f2d29c
add a missing `subscript(bounds:)` implementation (#1893)
- an older version of the standard library supplied a bogus implementation
  by error. Calling *that* would have been a crashing bug.

Co-authored-by: Guillaume Lessard <guillaume.l@apple.com>
2021-07-10 06:48:29 +01:00
Austin ffa6a871f7
Feature: Datagram Packet Info (#1888)
* Break out control message parsing by IP version

* Add shims for Darwin packet info

* Add shims for Linux packet info

* Add channel option for receiving datagram packet info

* Add NIOPacketInfo to AddressedEnvelope.Metadata

* Pipe up packet info channel option to receive path

* Add NIOPacketInfo info and fix backwards compatability

* Document packet info socket options

* Cleanup packet info control message parsing

* Add packet info and ECN combined tests

* Find real interface index during NIOPacketInfo tests

* Add PacketInfo tests to Linux tests
2021-07-08 11:04:53 +01:00
Peter Tolsma 3f33ef369f
Make ByteBuffer unconditionally use zero-copy for JSON Decoding (#1889) 2021-07-05 08:05:16 +01:00
Matteo Comisso d1b7c07883
Adds Equatable and ExpressibleByArrayLiteral conformance to ByteBufferView (#1886)
* Adds Equatable and ExpressibleByArrayLiteral conformance to ByteBufferView

* Adds linux test

* Equatable conformance compares slices of buffers

* Adds Hashable conformance to ByteBufferView

* Runs script for linux tests

* Force unwrap slicing the buffer in ByteBufferView equatable conformance implementation

* Adds Hashable conformance tests

* Addresses comments on test-related changes

* Minor grammar change

* Generates linux tests

Co-authored-by: Matteo Comisso <matteocomisso@skyscanner.net>
Co-authored-by: Matteo Comisso <matteo.comisso@me.copm>
2021-06-30 10:26:40 +01:00
Antoine Cœur d79e33308b
docs: formatting comments with double slash (#1881)
Motivation:

Triple slashes should be for exportable documentation (like functions declarations).

Modification:

Replaced `///` with `//`.

Result:

Better looking code comments.

Co-authored-by: Antoine Cœur <acoeur@apple.com>
2021-06-21 11:58:10 +01:00
David Evans b0effbcfd9
Make Swift 5.2 the minimum requirement (#1860)
Make Swift 5.2 the minimum requirement, dropping support for Swift 5.0 and 5.1.

Motivation:

Whenever we have problems, Swift 5.0 and 5.1 seem to be the culprits. Dropping support for these very old versions will require less maintenance and free up our time to work on new features.

Modifications:

Set the tools version in Package.swift to 5.2
Remove CI configurations for 5.0 and 5.1
Update the various readmes to reflect that this change will be rolled out in NIO 2.30.0
Result:

Swift 5.2 is the minimum version of Swift required to use NIO.
2021-06-18 21:02:41 +01:00
Si Beaumont 7f3a2f56b0
Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency (#1879)
* Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Signed-off-by: Si Beaumont <beaumont@apple.com>

* fixup: Move elg lifecycle into async function in async demo

* fixup: Ensure continuation is run exactly once

* fixup: Shutdown event loop group in catch in async demo
2021-06-14 10:51:42 +01:00
buttaface a1f405285a
Fix tests for 32-bit platforms, tested for Android armv7 (#1877)
Motivation:

Get the tests passing on 32-bit platforms again.

Modifications:

- Change the way _UInt56.max is initialized.
- Set the proper max capacity for AdaptiveRecvByteBufferAllocator
  and change the test to match it.
- Add a cmsghdrExample for Android armv7.

Result:

All the same tests pass on Android armv7 as Android AArch64.
2021-06-11 12:20:19 +01:00
Cory Benfield 67f0843653
Concurrency features are runtime-specific. (#1876)
Motivation:

The Swift concurrency features are only available in specific releases
of platforms where the Swift runtime ships with the platform. We need to
add availability guards to reflect that.

Modifications:

- Added appropriate availability guards for the async/await methods.

Result:

More likely to compile on Apple platforms.
2021-06-10 11:23:53 +01:00
akash-55 7688cf712f
#1714 Update Codec.swift (#1873)
* Update Codec.swift

* Update Sources/NIO/Codec.swift

Co-authored-by: Cory Benfield <lukasa@apple.com>

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-06-09 15:57:47 +01:00
Tim Condon 6d05b4f64b
Update _NIOConcurrency for Swift 5.5 latest changes (#1872) 2021-06-09 10:41:47 +01:00
Maxim Zaks c776f6e539
Improving performance of base64 encoding by about 10% (#1862)
* Improving performance of base64 encoding by about 10%

* revert alphabet change and use String(customUnsafeUninitializedCapacity:initializingUTF8With:)

* Add performance test for random request key generation

* use reduce

* fix indentation

* add `@inlinable` on custom unsefe inializer for older Swift version

* fix issues mentioned in review

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-06-07 11:12:06 +01:00
Bastian Inuk Christensen 93a40323d0
Made the externs const in CNIOLinux (#1869)
* Made the extern to const in CNIODarwin ##1867

* Added const to LNX

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-06-03 12:32:40 +01:00
Bastian Inuk Christensen 7db25900ab
Made the extern to const in CNIODarwin ##1867 (#1868) 2021-06-03 12:04:37 +01:00
Cory Benfield 0b3a8e4e34
Work around awkward SO_TIMESTAMP definition. (#1866)
Motivation:

On some Linux platforms the definition of SO_TIMESTAMP is too complex
for the clang importer to handle. Delegate to C to find out what it
should be. The same problem applies to SO_RCVTIMEO.

Modifications:

- Define SO_TIMESTAMP in CNIOLinux instead.
- Define SO_RCVTIMEO in CNIOLinux instead.

Result:

Should build on the awkward Linux platforms.
2021-06-02 11:15:58 +01:00
Johannes Weiss b23f40b4fa
add Swift 5.5 job (#1845) 2021-06-01 18:58:56 +01:00
Johannes Weiss e1aebf76e8
http_parser: update vendored copy (#1822)
Motivation:

It's good to update vendored deps.

Modification:

Update http_parser

Result:

newer code.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-06-01 15:26:10 +01:00
Maxim Zaks cf054f27b5
Add performance test for web socket client random request key (#1863)
* Add performance test for web socket client random request key

* use `reduce` function to minimise memory consumption of the test

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-06-01 11:08:13 +01:00
Cory Benfield 47b3501592
Fix spelling of detach (#1865)
Motivation:

The spelling of detach changed. This patch adopts the new spelling.

Modifications:

Changed detach to Task.detached.

Result:

5.5 should build again.
2021-06-01 10:33:06 +01:00
Cory Benfield 43fa7686db
Add alloc counter benchmark for result erasing maps. (#1858)
Motivation:

Peter thinks that result-erasing maps should not allocate, and we have
special code paths in the code to try to make Void -> Void maps not
allocate. Sadly, both code paths currently do allocate.

Per our rules for not trying to make optimizations without data, we
should start measuing these closures so we can make optimizations.

Modifications:

- Added an alloc couter test for result-erasing maps.

Result:

Alloc counter test suitable for any fix of #1697.
2021-05-25 12:56:38 +01:00
David Nadoba 465f87dd7c
Random WebSocket Request Key (#1855)
* add randomRequestKey method

* fix some typos

* fix compilation on 5.0

* run generate_linux_tests.rb

* add test with default random number generator

* @inlineable

* base64Encoding @inlineable
2021-05-24 16:02:16 +01:00
David Nadoba 4ded06871a
Add method to generate a random mask (#1824)
* add static method to generate a random mask

* use SystemRandomNumberGenerator by default and add documentation

* use WebSocketMaskingKey instead of Self to support Swift 5.0

* add tests for random masking key

* add return keyword to support Swift 5.0

* run scripts/generate_linux_tests.rb

* rename T to Generator

* test SystemRandomNumberGenerator

* Revert "test SystemRandomNumberGenerator"

This reverts commit d9bdbe57ac.

* work around thread sanitizer bug on Swift 5.3
2021-05-24 10:12:36 +01:00
Cory Benfield d161bf6587
Tests should tolerate cpusets. (#1853)
Motivation:

Our current CPU pinning tests do not expect to be pinned to cores that
do not include core 0. That's unnecessary.

Modifications:

- Expect to pin to the first core in our cpuset.

Result:

Tests run inside cpusets.
2021-05-07 11:28:18 +01:00
Johannes Weiss 06195d2f46
dev/scripts: add missing license headers (#1852)
Motivation:

We need license headers but the soundness script couldn't check if the
scripts don't have a `.sh` extension.

Modification:

- Add missing license headers.
- Better license checking (search for shell shebangs too)

Result:

Proper license attribution.
2021-05-07 10:28:07 +01:00
tomer doron aa9cfb6fb6
fix 5.4. docker setup (#1851)
motivation: update syntax for release images

changes: replace use of "base_image" with "ubuntu_version" and "swift_version" pair, which the intended way to use release images
2021-05-07 08:30:27 +01:00
Cory Benfield e0e289ac0e
Rewrite RecvByteBufferAllocator. (#1850)
Motivation:

Platforms with 32-bit integers continue to exist. On those platforms,
the way we calculate the size table for AdaptiveRecvByteBufferAllocator
will trap, as we attempt to compare an Int to UInt32.max as a loop
termination condition.

While I was amending this code, I noticed that
AdaptiveRecvByteBufferAllocator had a number of very strange behaviours,
and was arguably excessively complex. To that end, this patch
constitutes a substantial rewrite of the allocator. To understand what
it does, we need to describe the previous allocator algorithm.

The goal of AdaptiveRecvByteBufferAllocator is to attempt to dynamically
track the throughput of a TCP connection and to minimise the memory
usage required to get it to achieve maximum throughput, within
user-defined constraints. To that end, it implements a fairly simple
resizing algorithm.

At a high level, the algorithm is as follows. The allocator keeps track
of the size of the buffer it is offering the user. When the user reports
how much of that buffer they actually used, the allocator determines
whether better throughput could be achieved with larger allocation
sizes, or whether throughput would not be harmed with smaller allocation
sizes. It then adjusts accordingly.

When does the allocator believe beetter throughput could be achieved
with larger allocation sizes? When the allocation was entirely filled.
If a network recv() entirely fills the buffer, that means there was
likely more data to read that could not be added to the buffer. Improved
throughput would be gained by using larger buffers, as fewer system
calls would be necessary.

Similarly, the allocator believes it could shrink the buffer size
without harming throughput when the recv() uses less memory than the
next buffer size down. However, the algorithm attempts to detect the
possibility that we have "read until the end". The reason this is
relevant is that after a read completes we will often serve other work
on the loop for a while, causing data to pile up. As a result, we don't
want to shrink the buffer if the average read size would be higher, just
because one read happened to be short.

The original implementation's algorithm was based on a bucketed
scheme. For allocation sizes below 512 bytes, the allocation buckets
moved 16 bytes at a time. In principle this gave the allocator 16 byte
granularity. For allocation sizes above 512 bytes, the allocation
buckets would double: 512, 1024, 2048, 4096, and so on, up to
UInt32.max. This, incidentally, was the source of the crash on 32-bit
systems.

Unfortunately, this scheme had a few failings.

Firstly, the implementation complexity was fairly high. The bounds
provided by the user needed to be turned into bucket indices,
necessitating an awkward and complex binary search of the bucket array.
The bucket array itself needed to be generated, forcing a dispatch_once
to guard it and dirtying memory.

Secondly, the scheme was weighted very heavily toward growing memory and
not giving it back. Whenever the buffer was filled and a new size up
wanted to be chosen, the allocator would jump _4_ size buckets. As the
default initial size was 2048 bytes, and the default maximum was 65kB,
the first read of 2048 bytes would cause the allocator to immediately
jump up to allocating 32kB of memory for the next read: a huge leap! It
would then only release memory after two short reads, at which point it
would drop back only 1 bucket, meaning that there was a very aggressive
sawtooth pattern favouring higher memory usage. This pattern favours
benchmarks, where high-throughput localhost connections will naturally
want larger buffer sizes, but it is unnecessarily aggressive for
real-world networks.

Thirdly, the scheme had a bug that would mean it did not require two
_consecutive_ short reads to shrink the buffer, just two short reads
between an increase. This means that it had a tendency not to stabilise:
two "read to the end"s in two different event loop ticks would cause
the buffer to shrink, even if there had been 10 almost-full-reads
in between.

Fourthly, the system would occasionally report that the Channel should
reallocate the buffer because it was larger, when in fact it wasn't:
we'd hit the max, and were never going to get larger. This forced
high-throughput Channels to excessively allocate, albeit only in systems
that customized this allocator (and basically no-one does).

Fifthly, the bucketing system was defeated by ByteBuffer. While having
16-byte granularity was nice in principle, ByteBuffer only allows
power-of-two allocation sizes. This meant that, at the low end, there
were several wasted buckets that were effectively identical. Between 256
bytes and 512 bytes there were 15 redundant buckets!

This last point is the main reason to justify a rewrite. The complexity
of the scheme was in principle justified by having fine, granular
control of allocation sizes. Given that those don't exist, there is no
reason not to simply resort to power-of-two sizing. Once we do that, we
can replace the complex bucketing system by simple shift-and-multiply
math. The effect of this is to produce smaller code (we save about 30%
of the instructions, even as we add some extra safety preconditions)
with no additional branching, and no need to load from a random table in
memory. This avoids the need to keep that table in cache, reducing cache
pressure in the hot read loop. Additionally, we can drop the index into
the table, which lets us save some per-Channel memory, further reducing
cache pressure.

Additionally, constructing one of these is now vastly cheaper. That
matters less (it's not really hot-code), but it does improve Channel
creation time somewhat.

Modifications:

- Remove the size table.
- Round all values to powers of two.
- Implement new "previous power of two" function.
- Cap the allocation size at the largest power of 2 representable in a
  32-bit Int.
- Add more tests.

Result:

The result is less code, simpler code, and faster code. No trapping on
32-bit integer platforms.
2021-05-06 16:44:06 +01:00
Johannes Weiss c51907f551
alloc limit updater: allow other repos (#1844)
Motivation:

The allocation limit updater script is handy but so far only worked for
the SwiftNIO core repo.

Modifications:

- allow the user to pass other URL prefixes and repos

Result:

Can be used for other repos
2021-05-04 19:15:38 +01:00
Johannes Weiss b27b08a828
docker: use 5.4 release instead of nightly (#1843) 2021-05-04 16:21:44 +01:00
Johannes Weiss 0504ff04dd
dev/lldb-smoker: LLDB smoke test using NIO (#1840)
Motivation:

We often hit a bunch of problems with LLDB, especially on Linux. So
maybe it would be cool if we could smoke test LLDB using SwiftNIO.

Modifications:

Add script `dev/lldb-smoker` which does the following things:

- takes 2000 random picks amongst all the files in the package
- for each of those files, pick a random line number
- write an LLDB script which sets break points for each of the file/line
  pairs (one-shot breakpoints)
- runs the program
- for each breakpoint hit, run `frame variable` to list all the
  variables

Result:

LLDB smoke test
2021-05-04 11:05:40 +01:00
David Nadoba 6befe13e23
WebSocket Frame Aggregator (#1823)
* implement and test WebSocketFrameAggregator

* add documentation

* fix review comments

* run scripts/generate_linux_tests.rb

* fix Swift 5.0

* move redundant channel creation into init

* create channel in setUp

* wrap all trys in XCTAssertNoThrow

* cache accumulatedFrameSize

* accumulate buffered frames into the first frames data buffer

* Revert "accumulate buffered frames into the first frames data buffer"

This reverts commit 0f83823f95.

* use channel allocator
2021-04-30 15:39:24 +01:00
Johannes Weiss 903048293b
ByteBuffer: more random tests (#1837)
Motivation:

Noticed that in #1835 I still had no tests where genuinely every offset
stored in a ByteBuffer is non-zero.

Modification:

Add a test for that too now.

Result:

More test coverage.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-04-30 13:21:48 +01:00
Johannes Weiss f7e5eb521c
update version support (new floor: Ubuntu 18.04) (#1838)
Motivation:

Ubuntu 14.04 ... 17.10 are all not supported anymore by the end of the day.
Also Swift 5.4 was released recently.

Modification:

- support Ubuntu 18.04+
- officially support Swift 5.4

Result:

More sensible and correct version support info.
2021-04-30 13:03:37 +01:00
Johannes Weiss 9edca4aa21
ByteBufferTests: some extra tests around withUnsafeMutableReadableBytes (#1835)
Motivation:

Tests are always good, withUnsafeMutableReadableBytes was undertested
(probably).

Modification:

Add tests.

Result:

Better sleep.
2021-04-30 10:31:46 +01:00
Johannes Weiss e0963def86
bring back accidental commented benchmark (#1833)
Motivation:

In #1733 I accidentally commented out a perf benchmark (who knows why).

Modification:

Bring it back.

Result:

Benchmark is back.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-04-29 12:06:57 +01:00
Joakim Hassila 8ea0afb4c4
Added second implementation of liburing as discussed in #1761. (#1804)
Motivation:

As outlined in #1761, io_uring is a new async I/O facility on Linux.

This commit includes a second stab at adding this to SwiftNIO.

Modifications:

Added Uring Selector implementation.

Added liburing support shims.

Disabled one assert that trips during normal usage likely due to async nature of poll updates, for discussion

Added shared kernel sqpoll ring support (can be run with normal user privs in 5.13)

Support for both single shot polls (should work all the way back to 5.1 kernels, needs testing) and multishot streaming polls and modifications for polls (scheduled due in 5.13) for slightly better performance (and better impedance match to SwiftNIO usage)

Added extensive debug logs which can be enabled with -D compiler flags (should likely be removed when bringup and testing is complete)

Adjusted tests.

Added documentation.

Result:

Basic liburing support is in place.

Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2021-04-29 10:40:27 +01:00
Cory Benfield c6fc49a84a
Reduce selector wakeups. (#1820)
Motivation:

Right now all tasks scheduled onto an event loop from a different loop
wake up the underlying selector by writing to an eventfd. This is a
fairly inefficient way to handle things: it incurs a lot of syscall
traffic unnecessarily.

Given that we currently protect the pending tasks queue with a big dumb
lock, we can safely keep track of whether we're going to dequeue this
task. If we are, we don't need to wake the selector.

Modifications:

- Keep track of whether we're de-queueing tasks or not.
- Arrange to wake the selector only once.

Result:

Cheaper task enqueueing on hot loops.
2021-04-28 15:09:07 +01:00
Cory Benfield 8369411d6f
Stop measuring alloc counts on 5.0 (#1826)
Motivation:

5.0 is several years old now, and while we still support it there is
beginning to be some conflict with performance optimizations for newer
Swift versions. We should stop counting the allocation counts on this
version now: we no longer care as much about regressions.

Modifications:

- Stop setting alloc counter limits on 5.0
- Remove the script that tries to add them back.

Result:

No longer measure allocs on 5.0
2021-04-28 14:02:13 +01:00
Johannes Weiss 0a860b1c3d
CI: print out version info (#1821)
Motivation:

Sometimes it's useful to know the kernel & Swift versions that CI uses.

Modifications:

Print the versions in the soundness check.

Result:

More info.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-04-27 13:34:54 +01:00
Cory Benfield 21782f3bdc
Implement reserveCapacity for CircularBuffer. (#1819)
Motivation:

While spelunking through the code I noticed we called
CircularBuffer.reserveCapacity, but never actually implemented it. This
means it never did anything. It should do something.

Modifications:

- Implemented reserveCapacity.

Result:

reserveCapacity does something now.
2021-04-26 14:10:43 +01:00
Fabian Fett e08f9f903e
Reducing allocations in future chains (#1818) 2021-04-26 13:54:26 +01:00
Fabian Fett 72f5a56328
Less allocs during `flatMapErrorThrowing` (#1816)
Motivation:

We alloc quite a lot with our implementations of flatMapThrowing and flatMapErrorThrowing.
While we don't use Futures a lot in NIO itself a lot of our users, depend quite a bit on them. Let's make their code faster.

Modifications:

Create a Promise and use _whenComplete directly instead of going through another flatMap method

Result:

In my testing I see a reduction of 3 allocs per invocation 🎉
2021-04-23 19:27:38 +01:00
Johannes Weiss eb1590a48a
script to download & apply alloc limits from Jenkins (#1817)
Motivation:

When doing bigger alloc count changes, it's really tedious to apply them
manually given that the CI has the right numbers already.

Modifications:

Add a script to download and update them automatically.

Result:

Less toil.
2021-04-23 17:54:52 +01:00
Johannes Weiss 5f94bd34a4
Selectors: make file descriptors CInts everywhere (#1815)
Motivation:

We and the OSes only support `CInt` as file descriptors. For some reason
we had interfaces that took `Int`s as fds which requires frequent
casting around. This is unnecessary.

Modifications:

- make fds `CInt` (internally)
- clean up some `Int32` as `CInt` use

Result:

cleaner code, less casting
2021-04-23 14:20:21 +01:00