Skip to content

Commit 7f9dba8

Browse files
authored
Merge pull request #208 from apple/david/ioring
Add io_uring support to System
2 parents 99feed6 + 08ed962 commit 7f9dba8

File tree

9 files changed

+1899
-1
lines changed

9 files changed

+1899
-1
lines changed

Package.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,21 @@ let swiftSettings: [SwiftSetting] = [
2222
.when(platforms: [.macOS, .macCatalyst, .iOS, .watchOS, .tvOS, .visionOS])),
2323
.define("SYSTEM_PACKAGE"),
2424
.define("ENABLE_MOCKING", .when(configuration: .debug)),
25+
.enableExperimentalFeature("Lifetimes"),
2526
]
2627

28+
#if os(Linux)
29+
let filesToExclude = ["CMakeLists.txt"]
30+
#else
31+
let filesToExclude = ["CMakeLists.txt", "IORing"]
32+
#endif
33+
34+
#if os(Linux)
35+
let testsToExclude:[String] = []
36+
#else
37+
let testsToExclude = ["IORequestTests.swift", "IORingTests.swift"]
38+
#endif
39+
2740
let package = Package(
2841
name: "swift-system",
2942
products: [
@@ -40,12 +53,13 @@ let package = Package(
4053
name: "SystemPackage",
4154
dependencies: ["CSystem"],
4255
path: "Sources/System",
43-
exclude: ["CMakeLists.txt"],
56+
exclude: filesToExclude,
4457
cSettings: cSettings,
4558
swiftSettings: swiftSettings),
4659
.testTarget(
4760
name: "SystemTests",
4861
dependencies: ["SystemPackage"],
62+
exclude: testsToExclude,
4963
cSettings: cSettings,
5064
swiftSettings: swiftSettings),
5165
])

Sources/CSystem/include/CSystemLinux.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@
2121
#include <pthread.h>
2222
#include <sched.h>
2323
#include <unistd.h>
24+
#include "io_uring.h"
2425
#endif
2526

Sources/CSystem/include/io_uring.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <unistd.h>
2+
#include <sys/syscall.h>
3+
#include <sys/uio.h>
4+
5+
#include <signal.h>
6+
#include <linux/io_uring.h>
7+
8+
#ifndef SWIFT_IORING_C_WRAPPER
9+
#define SWIFT_IORING_C_WRAPPER
10+
11+
# ifndef __NR_io_uring_setup
12+
# define __NR_io_uring_setup 425
13+
# endif
14+
# ifndef __NR_io_uring_enter
15+
# define __NR_io_uring_enter 426
16+
# endif
17+
# ifndef __NR_io_uring_register
18+
# define __NR_io_uring_register 427
19+
# endif
20+
21+
/*
22+
struct io_uring_getevents_arg {
23+
__u64 sigmask;
24+
__u32 sigmask_sz;
25+
__u32 min_wait_usec; //used to be called `pad`. This compatibility wrapper avoids dealing with that.
26+
__u64 ts;
27+
};
28+
*/
29+
struct swift_io_uring_getevents_arg {
30+
__u64 sigmask;
31+
__u32 sigmask_sz;
32+
__u32 min_wait_usec;
33+
__u64 ts;
34+
};
35+
36+
static inline int io_uring_register(int fd, unsigned int opcode, void *arg,
37+
unsigned int nr_args)
38+
{
39+
return syscall(__NR_io_uring_register, fd, opcode, arg, nr_args);
40+
}
41+
42+
static inline int io_uring_setup(unsigned int entries, struct io_uring_params *p)
43+
{
44+
return syscall(__NR_io_uring_setup, entries, p);
45+
}
46+
47+
static inline int io_uring_enter2(int fd, unsigned int to_submit, unsigned int min_complete,
48+
unsigned int flags, void *args, size_t sz)
49+
{
50+
return syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
51+
flags, args, _NSIG / 8);
52+
}
53+
54+
static inline int io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete,
55+
unsigned int flags, sigset_t *sig)
56+
{
57+
return io_uring_enter2(fd, to_submit, min_complete, flags, sig, _NSIG / 8);
58+
}
59+
60+
#endif
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#if compiler(>=6.2)
2+
#if os(Linux)
3+
4+
import CSystem
5+
6+
public extension IORing {
7+
struct Completion: ~Copyable {
8+
@inlinable init(rawValue inRawValue: io_uring_cqe) {
9+
rawValue = inRawValue
10+
}
11+
@usableFromInline let rawValue: io_uring_cqe
12+
}
13+
}
14+
15+
public extension IORing.Completion {
16+
struct Flags: OptionSet, Hashable, Codable {
17+
public let rawValue: UInt32
18+
19+
@inlinable public init(rawValue: UInt32) {
20+
self.rawValue = rawValue
21+
}
22+
23+
///`IORING_CQE_F_BUFFER` Indicates the buffer ID is stored in the upper 16 bits
24+
@inlinable public static var allocatedBuffer: Flags { Flags(rawValue: 1 << 0) }
25+
///`IORING_CQE_F_MORE` Indicates more completions will be generated from the request that generated this
26+
@inlinable public static var moreCompletions: Flags { Flags(rawValue: 1 << 1) }
27+
//`IORING_CQE_F_SOCK_NONEMPTY`, but currently unused
28+
//@inlinable public static var socketNotEmpty: Flags { Flags(rawValue: 1 << 2) }
29+
//`IORING_CQE_F_NOTIF`, but currently unused
30+
//@inlinable public static var isNotificationEvent: Flags { Flags(rawValue: 1 << 3) }
31+
//IORING_CQE_F_BUF_MORE will eventually be (1U << 4) if we add IOU_PBUF_RING_INC support
32+
}
33+
}
34+
35+
public extension IORing.Completion {
36+
@inlinable var context: UInt64 {
37+
get {
38+
rawValue.user_data
39+
}
40+
}
41+
42+
@inlinable var userPointer: UnsafeRawPointer? {
43+
get {
44+
UnsafeRawPointer(bitPattern: UInt(rawValue.user_data))
45+
}
46+
}
47+
48+
@inlinable var result: Int32 {
49+
get {
50+
rawValue.res
51+
}
52+
}
53+
54+
@inlinable var flags: IORing.Completion.Flags {
55+
get {
56+
Flags(rawValue: rawValue.flags & 0x0000FFFF)
57+
}
58+
}
59+
60+
@inlinable var bufferIndex: UInt16? {
61+
get {
62+
if self.flags.contains(.allocatedBuffer) {
63+
return UInt16(rawValue.flags >> 16)
64+
} else {
65+
return nil
66+
}
67+
}
68+
}
69+
}
70+
#endif
71+
#endif

0 commit comments

Comments
 (0)