Skip to content

Add io_uring support to System #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 109 commits into from
Jul 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
15794f5
ioring pitch: first steps
oxy Jul 19, 2023
6338029
stage 2: IORequest enum
oxy Aug 1, 2023
996e940
initial AsyncFileDescriptor work
oxy Aug 1, 2023
1f821a8
AsyncSequence draft implementation
oxy Aug 8, 2023
0762f57
migrate CSystem to systemLibrary
oxy Aug 10, 2023
d099546
fix access control
oxy Aug 11, 2023
b584504
fix off-by-one in IORequest.openat
oxy Aug 11, 2023
b596783
implement closing
oxy Aug 11, 2023
6b4084c
introduce IORing unit tests
oxy Aug 11, 2023
baab9b2
Starting to move to noncopyable structs, and away from swift-atomics
Catfish-Man Oct 24, 2024
6029936
One more noncopyable struct
Catfish-Man Oct 24, 2024
10c070a
WIP, more ~Copyable adoption
Catfish-Man Oct 28, 2024
32966f9
It builds again! With some horrible hacks
Catfish-Man Oct 28, 2024
822e481
Adopt isolation parameters
Catfish-Man Oct 28, 2024
fcb0b69
Merge branch 'main' into david/ioring
Catfish-Man Oct 29, 2024
6f793cf
Merge branch 'main' into david/ioring
Catfish-Man Oct 29, 2024
a9f92a6
Delete stray Package.resolved changes
Catfish-Man Oct 29, 2024
1a3e37d
Fix mismerge
Catfish-Man Oct 29, 2024
f369347
Fix mismerge
Catfish-Man Oct 29, 2024
ef94a37
Refactoring, and give up on resources being noncopyable structs
Catfish-Man Dec 5, 2024
7ea32ae
More refactoring, and working timeout support on ManagedIORing
Catfish-Man Dec 11, 2024
55fd6e7
Add support for timeout-on-wait to IORing, don't have tests yet
Catfish-Man Dec 12, 2024
e5fdf9e
Remove managed abstractions for now
Catfish-Man Feb 6, 2025
fdbceca
Eliminate internal locking and add multiple consume support
Catfish-Man Feb 6, 2025
7107a57
Fix import visibility
Catfish-Man Feb 11, 2025
02481e0
More import fixes
Catfish-Man Feb 11, 2025
bb03f0f
Redesign registered resources API
Catfish-Man Feb 11, 2025
a396967
More registration tweaks
Catfish-Man Feb 11, 2025
d4ca412
Some renaming, and implement linked requests
Catfish-Man Feb 11, 2025
5bfed03
Switch to static methods for constructing requests
Catfish-Man Feb 11, 2025
74366c3
Improve submit API
Catfish-Man Feb 12, 2025
7f6e673
Adjust registered resources API
Catfish-Man Feb 12, 2025
0c6ef16
Fix type
Catfish-Man Feb 12, 2025
a22e5f6
Add a version of registerBuffers that isn't varargs
Catfish-Man Feb 13, 2025
6983196
Add unlinkAt support
Catfish-Man Feb 13, 2025
5ba1377
Dubious approach to this, but I want to try it out a bit
Catfish-Man Feb 13, 2025
0064649
Turn on single issuer as an experiment
Catfish-Man Feb 14, 2025
901f4c8
Revert "Turn on single issuer as an experiment"
Catfish-Man Feb 14, 2025
283e8d6
Reapply "Turn on single issuer as an experiment"
Catfish-Man Feb 14, 2025
d895f2a
Revert "Reapply "Turn on single issuer as an experiment""
Catfish-Man Feb 14, 2025
f3b8cc4
Actually consume events we waited for
Catfish-Man Feb 28, 2025
d338de1
Only get one completion if we asked for one completion
Catfish-Man Feb 28, 2025
5e24673
Switch from unsafe pointers to FilePaths, using hacks
Catfish-Man Mar 3, 2025
49dd797
Add a combined "submit and consume" operation
Catfish-Man Mar 3, 2025
91155fd
Plumb error handling through completion consumers
Catfish-Man Mar 3, 2025
9ad16c0
Plumb through userData
Catfish-Man Mar 3, 2025
880ec90
Add a pointer convenience for getting the user data
Catfish-Man Mar 3, 2025
48455a9
Fix plumbing
Catfish-Man Mar 3, 2025
72c316b
Make completions noncopyable again
Catfish-Man Mar 3, 2025
7fff872
Add the draft proposal so I can link to it
Catfish-Man Mar 6, 2025
0e652c4
Naming updates, cancellation support, IOResources are structs now, ot…
Catfish-Man Apr 4, 2025
b40b094
Revamp error handling
Catfish-Man Apr 16, 2025
27275f8
Merge remote-tracking branch 'refs/remotes/origin/david/ioring' into …
Catfish-Man Apr 16, 2025
2f91217
Fix a few things I missed
Catfish-Man Apr 16, 2025
d4ca203
Most of feature querying and setup flags
Catfish-Man Apr 17, 2025
41f9676
WIP, crashes the compiler
Catfish-Man Apr 17, 2025
014f8b7
Rename userData to context
Catfish-Man Apr 17, 2025
261ca25
Centralize on Errno for errors, and work around lifetime compiler cra…
Catfish-Man Apr 18, 2025
c029c1b
Proposal updates and a minor change to setup flags
Catfish-Man Apr 18, 2025
05eac87
It compiles again!
Catfish-Man Apr 18, 2025
7798f0c
Add cancellation support and drop gerunds
Catfish-Man Apr 21, 2025
9d325b2
Change IORingFileSlot and IORingBuffer to be nested types in IORing
Catfish-Man Apr 21, 2025
ea77ef8
Minor cleanup
Catfish-Man Apr 21, 2025
baa3d62
API tweak
Catfish-Man Apr 21, 2025
3760dc2
Nest IOResource, and update proposal to match
Catfish-Man Apr 21, 2025
a98cd3f
Build fix and rename IOResource
Catfish-Man Apr 21, 2025
344b3b8
Proposal updates
Catfish-Man Apr 21, 2025
c47779f
Try making requests and completions nested types
Catfish-Man Apr 22, 2025
a49ba8a
Give flags a default value
Catfish-Man Apr 22, 2025
f38d72f
Nested types, some renames, misc other updates
Catfish-Man Apr 22, 2025
3a649e3
Fix type of features, and make it clear that Completion is a nested type
Catfish-Man Apr 24, 2025
7e2f797
Fix some errors on newer linux systems
Catfish-Man Apr 28, 2025
f5b8e02
Merge remote-tracking branch 'origin/main' into david/ioring
Catfish-Man Apr 28, 2025
3d6cba2
Work around compiler bugs harder
Catfish-Man Apr 28, 2025
f9c2a2b
Work around io_uring.h in ways that will work on both versions
Catfish-Man Jun 18, 2025
f91cb6b
Improve tests. Not quite working but close
Catfish-Man Jun 27, 2025
131326c
Fix tests
Catfish-Man Jul 1, 2025
321a71c
Expand test coverage
Catfish-Man Jul 3, 2025
27ccce5
Conditionalize IORing stuff for Linux
Catfish-Man Jul 3, 2025
0d4c6fc
Fix Musl
Catfish-Man Jul 3, 2025
de2d6e2
Conditionalize tests too
Catfish-Man Jul 3, 2025
a6149c2
Cleanup, implement buffer unregistering, inline almost everything bec…
Catfish-Man Jul 4, 2025
e580c13
Merge branch 'david/ioring' of https://github.com/apple/swift-system …
Catfish-Man Jul 4, 2025
bbe2f1c
Add doc comments, Span/MutableSpan support, unregistering registered …
Catfish-Man Jul 8, 2025
227a38f
Remove blocking enqueue
Catfish-Man Jul 8, 2025
bc097e9
Remove more blocking enqueue infrastructure
Catfish-Man Jul 8, 2025
55e55c1
Add test and fix submission queue capacity check
Catfish-Man Jul 8, 2025
a6c5a39
Remove the proposal doc
Catfish-Man Jul 8, 2025
528e748
Document completion flags and disable ones we don't currently support
Catfish-Man Jul 8, 2025
d6687d2
Add deleted file back
Catfish-Man Jul 8, 2025
d2b78f8
Remove unneeded defines
Catfish-Man Jul 8, 2025
8757fae
Remove some stray commas the API breakage test complains about
Catfish-Man Jul 8, 2025
4b70ffe
Fix short submits and also fix the registration ops enum, which someh…
Catfish-Man Jul 9, 2025
6dd0eba
Merge branch 'david/ioring' of https://github.com/apple/swift-system …
Catfish-Man Jul 9, 2025
329c5f5
Conditionalize IORing on compiler >= 6.2
Catfish-Man Jul 9, 2025
a6675d7
timespec should be compatible here, let's try it to fix the Ubuntu 22…
Catfish-Man Jul 10, 2025
d121081
More Ubuntu 22 workarounds. This should error at runtime rather than …
Catfish-Man Jul 10, 2025
2f6c4e0
Add support for non-IORING_FEAT_SINGLE_MMAP kernels
Catfish-Man Jul 11, 2025
779c9ac
Fix misuse of _CANCEL_ANY, and add support for non-redicated cancella…
Catfish-Man Jul 11, 2025
7fc787e
Move IORing files to a subdirectory
Catfish-Man Jul 11, 2025
f7c05e1
Combine platform conditionals
Catfish-Man Jul 11, 2025
a56bcda
Un-combine conditionals but flip their order. This should fix the Win…
Catfish-Man Jul 11, 2025
9a04649
Try adding newlines to the ends of files to work around a compiler bug
Catfish-Man Jul 11, 2025
b93169b
Work around windows bugs harder
Catfish-Man Jul 11, 2025
52d9c99
Fix excludes
Catfish-Man Jul 11, 2025
33b58a8
Fix excludes harder
Catfish-Man Jul 11, 2025
a66176f
Only run IORing tests if io_uring support is enabled
Catfish-Man Jul 11, 2025
08ea334
Merge branch 'david/ioring' of https://github.com/apple/swift-system …
Catfish-Man Jul 11, 2025
08ed962
Don't abort the test if we can't open /proc/sys/kernel/io_uring_disabled
Catfish-Man Jul 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,21 @@ let swiftSettings: [SwiftSetting] = [
.when(platforms: [.macOS, .macCatalyst, .iOS, .watchOS, .tvOS, .visionOS])),
.define("SYSTEM_PACKAGE"),
.define("ENABLE_MOCKING", .when(configuration: .debug)),
.enableExperimentalFeature("Lifetimes"),
]

#if os(Linux)
let filesToExclude = ["CMakeLists.txt"]
#else
let filesToExclude = ["CMakeLists.txt", "IORing"]
#endif

#if os(Linux)
let testsToExclude:[String] = []
#else
let testsToExclude = ["IORequestTests.swift", "IORingTests.swift"]
#endif

let package = Package(
name: "swift-system",
products: [
Expand All @@ -40,12 +53,13 @@ let package = Package(
name: "SystemPackage",
dependencies: ["CSystem"],
path: "Sources/System",
exclude: ["CMakeLists.txt"],
exclude: filesToExclude,
cSettings: cSettings,
swiftSettings: swiftSettings),
.testTarget(
name: "SystemTests",
dependencies: ["SystemPackage"],
exclude: testsToExclude,
cSettings: cSettings,
swiftSettings: swiftSettings),
])
1 change: 1 addition & 0 deletions Sources/CSystem/include/CSystemLinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include "io_uring.h"
#endif

60 changes: 60 additions & 0 deletions Sources/CSystem/include/io_uring.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/uio.h>

#include <signal.h>
#include <linux/io_uring.h>

#ifndef SWIFT_IORING_C_WRAPPER
#define SWIFT_IORING_C_WRAPPER

# ifndef __NR_io_uring_setup
# define __NR_io_uring_setup 425
# endif
# ifndef __NR_io_uring_enter
# define __NR_io_uring_enter 426
# endif
# ifndef __NR_io_uring_register
# define __NR_io_uring_register 427
# endif

/*
struct io_uring_getevents_arg {
__u64 sigmask;
__u32 sigmask_sz;
__u32 min_wait_usec; //used to be called `pad`. This compatibility wrapper avoids dealing with that.
__u64 ts;
};
*/
struct swift_io_uring_getevents_arg {
__u64 sigmask;
__u32 sigmask_sz;
__u32 min_wait_usec;
__u64 ts;
};

static inline int io_uring_register(int fd, unsigned int opcode, void *arg,
unsigned int nr_args)
{
return syscall(__NR_io_uring_register, fd, opcode, arg, nr_args);
}

static inline int io_uring_setup(unsigned int entries, struct io_uring_params *p)
{
return syscall(__NR_io_uring_setup, entries, p);
}

static inline int io_uring_enter2(int fd, unsigned int to_submit, unsigned int min_complete,
unsigned int flags, void *args, size_t sz)
{
return syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
flags, args, _NSIG / 8);
}

static inline int io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete,
unsigned int flags, sigset_t *sig)
{
return io_uring_enter2(fd, to_submit, min_complete, flags, sig, _NSIG / 8);
}

#endif
71 changes: 71 additions & 0 deletions Sources/System/IORing/IOCompletion.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#if compiler(>=6.2)
#if os(Linux)

import CSystem

public extension IORing {
struct Completion: ~Copyable {
@inlinable init(rawValue inRawValue: io_uring_cqe) {
rawValue = inRawValue
}
@usableFromInline let rawValue: io_uring_cqe
}
}

public extension IORing.Completion {
struct Flags: OptionSet, Hashable, Codable {
public let rawValue: UInt32

@inlinable public init(rawValue: UInt32) {
self.rawValue = rawValue
}

///`IORING_CQE_F_BUFFER` Indicates the buffer ID is stored in the upper 16 bits
@inlinable public static var allocatedBuffer: Flags { Flags(rawValue: 1 << 0) }
///`IORING_CQE_F_MORE` Indicates more completions will be generated from the request that generated this
@inlinable public static var moreCompletions: Flags { Flags(rawValue: 1 << 1) }
//`IORING_CQE_F_SOCK_NONEMPTY`, but currently unused
//@inlinable public static var socketNotEmpty: Flags { Flags(rawValue: 1 << 2) }
//`IORING_CQE_F_NOTIF`, but currently unused
//@inlinable public static var isNotificationEvent: Flags { Flags(rawValue: 1 << 3) }
//IORING_CQE_F_BUF_MORE will eventually be (1U << 4) if we add IOU_PBUF_RING_INC support
}
}

public extension IORing.Completion {
@inlinable var context: UInt64 {
get {
rawValue.user_data
}
}

@inlinable var userPointer: UnsafeRawPointer? {
get {
UnsafeRawPointer(bitPattern: UInt(rawValue.user_data))
}
}

@inlinable var result: Int32 {
get {
rawValue.res
}
}

@inlinable var flags: IORing.Completion.Flags {
get {
Flags(rawValue: rawValue.flags & 0x0000FFFF)
}
}

@inlinable var bufferIndex: UInt16? {
get {
if self.flags.contains(.allocatedBuffer) {
return UInt16(rawValue.flags >> 16)
} else {
return nil
}
}
}
}
#endif
#endif
Loading