Commit Graph

6 Commits

Author SHA1 Message Date
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
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
Johannes Weiss e2990d9672
refactor registration IDs (#1801)
Motivation:

Instead of manual shifting / masking we can write the whole registration
ID code normally in Swift.

Modifications:

Refactored RegistrationID to use Swift instead of shifting / masking.

Result:

Nicer code.
2021-04-23 12:43:30 +01:00
Joakim Hassila f0b825f9b7
Add sequenceIdentifier to Registrations to handle outdated events robustly. (#1799)
Motivation:

Currently the selector implementation just discards all pending events from the kernel when a deregistration
has occurred during the event loop tick. This has been needed to not fail the test testWeDoNotDeliverEventsForPreviouslyClosedChannels.

A cleanup case has been around for a while at: https://github.com/apple/swift-nio/issues/381

And when discussing this in https://github.com/apple/swift-nio/pull/1788 (to solve https://github.com/apple/swift-nio/issues/1761)

we came to an agreement that the solution with tagging registrations on the backend would not suit only io_uring,
but also solve the issue robustly for kqueue and epoll.

Modification:

Added sequenceIdentifier to the Registration and add support for it throughout.
Mask in sequence identifier into user data in both kqueue and epoll.
In kqueue, we just store the sequence identifier in the udata field (to support 32-bit properly).
In epoll, where we know we have 64-bits, we mask it in together with fd.
Removed all references to the old workaround from #381.

Result:

- New solution that doesn't need to discard all events when deregistrations are done during the event loop tick.
- fixes #381
2021-04-13 10:35:41 +01:00
Joakim Hassila ed0b013c57
Split Selector into separate files per backend. (#1795)
Motivation:
Currently all backends are platform-conditional in the `Selector` code, making it
harder to read and difficult to extend for future new backend implementations.
By splitting the `Selector` into a generic part and per-backend platform implementation
it is easier to add additional backends in the future.

Modifications:
Split Selector into `SelectorGeneric`, `SelectorEpoll` and `SelectorKqueue`.
Add a _SelectorBackendProtocol that should be implemented by actual backends.
Fixed tests.

Result:
- Easier to read code
- Makes it easier to add new backends

Co-authored-by: Cory Benfield <lukasa@apple.com>
Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2021-04-09 16:49:02 +01:00