Skip to content

Commit fae6fb3

Browse files
authored
Merge pull request #216 from vibe-d/io_uring
Revive for io_uring support on Linux
2 parents a0fc8ac + 26afa57 commit fae6fb3

File tree

8 files changed

+677
-29
lines changed

8 files changed

+677
-29
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@ jobs:
1818
os: [ubuntu-latest, windows-latest, macos-13]
1919
dc: [dmd-latest, ldc-latest, dmd-2.087.1, ldc-1.17.0]
2020
arch: [x86_64]
21-
config: [select, epoll, cfrunloop, winapi]
21+
config: [select, epoll, cfrunloop, winapi, uring]
2222
exclude:
2323
- {os: ubuntu-latest, config: cfrunloop}
2424
- {os: ubuntu-latest, config: winapi}
2525
- {os: macos-13, config: epoll}
26+
- {os: macos-13, config: uring}
2627
- {os: macos-13, config: winapi}
2728
- {os: windows-latest, config: cfrunloop}
2829
- {os: windows-latest, config: epoll}
30+
- {os: windows-latest, config: uring}
2931
- {os: macos-13, dc: dmd-2.087.1}
3032
- {os: windows-latest, dc: ldc-1.17.0}
3133
- {os: ubuntu-latest, dc: ldc-1.17.0}
34+
- {os: ubuntu-latest, dc: dmd-2.087.1, config: uring}
3235
include:
3336
- {os: windows-latest, dc: ldc-latest, arch: x86, config: winapi}
3437
- {os: windows-latest, dc: dmd-latest, arch: x86_mscoff, config: winapi}

README.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ WinAPIEventDriver | — | yes | — | — | — | —
2222
KqueueEventDriver | — | — | yes | yes¹ | — | yes
2323
CFRunloopEventDriver | — | — | yes | — | — | yes
2424
LibasyncEventDriver | —¹| —¹| —¹| —¹| — | —
25+
UringEventDriver | yes² | no | no | no | unknown | no
2526

2627
¹ planned, but not currenly implemented
28+
² experimental
2729

2830

2931
Supported compilers
@@ -40,20 +42,20 @@ The following compilers are tested and supported:
4042
Driver development status
4143
-------------------------
4244

43-
Feature \ EventDriver | Select | Epoll | WinAPI | Kqueue | CFRunloop | Libasync
44-
----------------------|--------|-------|---------|---------|-----------|----------
45-
TCP Sockets | yes | yes | yes | yes | yes | —
46-
UDP Sockets | yes | yes | yes | yes | yes | —
47-
USDS | yes | yes | — | yes | yes | —
48-
DNS | yes | yes | yes | yes | yes | —
49-
Timers | yes | yes | yes | yes | yes | —
50-
Events | yes | yes | yes | yes | yes | —
51-
Unix Signals | yes² | yes | — | — | — | —
52-
Files | yes | yes | yes | yes | yes | —
53-
UI Integration | yes¹ | yes¹ | yes | yes¹ | yes¹ | —
54-
File watcher | yes² | yes | yes | yes² | yes² | —
55-
Pipes | yes | yes | — | yes | yes | —
56-
Processes | yes | yes | — | yes | yes | —
45+
Feature \ EventDriver | Select | Epoll | WinAPI | Kqueue | CFRunloop | Libasync | Uring
46+
----------------------|--------|-------|---------|---------|-----------|----------|-------
47+
TCP Sockets | yes | yes | yes | yes | yes | — | —
48+
UDP Sockets | yes | yes | yes | yes | yes | — | —
49+
USDS | yes | yes | — | yes | yes | — | —
50+
DNS | yes | yes | yes | yes | yes | — | —
51+
Timers | yes | yes | yes | yes | yes | — | —
52+
Events | yes | yes | yes | yes | yes | — | —
53+
Unix Signals | yes² | yes | — | — | — | — | —
54+
Files | yes | yes | yes | yes | yes | — | yes
55+
UI Integration | yes¹ | yes¹ | yes | yes¹ | yes¹ | — | yes?
56+
File watcher | yes² | yes | yes | yes² | yes² | — | —
57+
Pipes | yes | yes | — | yes | yes | — | —
58+
Processes | yes | yes | — | yes | yes | — | —
5759

5860
¹ Manually, by adopting the X11 display connection socket
5961

dub.sdl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name "eventcore"
22
description "Pro-actor based abstraction layer over operating system asynchronous I/O facilities."
33
license "MIT"
44
copyright "Copyright © 2016-2018 Sönke Ludwig"
5-
5+
dependency "during" version="~>0.3.0"
66
targetType "library"
77

88
libs "ws2_32" "user32" platform="windows-dmd"
@@ -51,6 +51,11 @@ configuration "select" {
5151
versions "EventcoreLibasyncDriver"
5252
}*/
5353

54+
configuration "uring" {
55+
platforms "linux"
56+
versions "EventcoreUringDriver"
57+
}
58+
5459
configuration "generic" {
5560
// Defines eventDriver as the generic EventDriver interface. Setup must be done manually.
5661
}

source/eventcore/core.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import eventcore.drivers.posix.cfrunloop;
66
import eventcore.drivers.posix.epoll;
77
import eventcore.drivers.posix.kqueue;
88
import eventcore.drivers.posix.select;
9+
import eventcore.drivers.posix.uring;
910
import eventcore.drivers.libasync;
1011
import eventcore.drivers.winapi.driver;
1112
import eventcore.internal.utils : mallocT, freeT;
1213

1314
version (EventcoreEpollDriver) alias NativeEventDriver = EpollEventDriver;
15+
else version (EventcoreUringDriver) alias NativeEventDriver = UringEventDriver;
1416
else version (EventcoreCFRunLoopDriver) alias NativeEventDriver = CFRunLoopEventDriver;
1517
else version (EventcoreKqueueDriver) alias NativeEventDriver = KqueueEventDriver;
1618
else version (EventcoreWinAPIDriver) alias NativeEventDriver = WinAPIEventDriver;

source/eventcore/drivers/posix/driver.d

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import eventcore.drivers.posix.sockets;
1414
import eventcore.drivers.posix.watchers;
1515
import eventcore.drivers.posix.processes;
1616
import eventcore.drivers.posix.pipes;
17+
import eventcore.drivers.posix.uring;
1718
import eventcore.drivers.timer;
1819
import eventcore.drivers.threadedfile;
1920
import eventcore.internal.consumablequeue : ConsumableQueue;
@@ -37,10 +38,13 @@ private long currStdTime()
3738
return Clock.currStdTime;
3839
}
3940

41+
version(EventcoreEpollUsesUring) {
42+
version (EventcoreEpollDriver) {}
43+
else { static assert(false, "uring only supported together with epoll for now"); }
44+
}
45+
4046
final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver {
4147
@safe: /*@nogc:*/ nothrow:
42-
43-
4448
private {
4549
alias CoreDriver = PosixEventDriverCore!(Loop, TimerDriver, EventsDriver, ProcessDriver);
4650
alias EventsDriver = PosixEventDriverEvents!(Loop, SocketsDriver);
@@ -51,7 +55,8 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver {
5155
version (Windows) alias DNSDriver = EventDriverDNS_GHBN!(EventsDriver, SignalsDriver);
5256
else version (EventcoreUseGAIA) alias DNSDriver = EventDriverDNS_GAIA!(EventsDriver, SignalsDriver);
5357
else alias DNSDriver = EventDriverDNS_GAI!(EventsDriver, SignalsDriver);
54-
alias FileDriver = ThreadedFileEventDriver!(EventsDriver, CoreDriver);
58+
version (EventcoreEpollUsesUring) alias FileDriver = UringDriverFiles;
59+
else alias FileDriver = ThreadedFileEventDriver!(EventsDriver, CoreDriver);
5560
version (Posix) alias PipeDriver = PosixEventDriverPipes!Loop;
5661
else alias PipeDriver = DummyEventDriverPipes!Loop;
5762
version (linux) alias WatcherDriver = InotifyEventDriverWatchers!EventsDriver;
@@ -78,6 +83,8 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver {
7883
this()
7984
@nogc @trusted {
8085
m_loop = mallocT!Loop;
86+
version (EventcoreEpollUsesUring)
87+
m_uring = mallocT!UringCore;
8188
m_sockets = mallocT!SocketsDriver(m_loop);
8289
m_events = mallocT!EventsDriver(m_loop, m_sockets);
8390
m_signals = mallocT!SignalsDriver(m_loop);
@@ -86,7 +93,8 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver {
8693
m_processes = mallocT!ProcessDriver(m_loop, this);
8794
m_core = mallocT!CoreDriver(m_loop, m_timers, m_events, m_processes);
8895
m_dns = mallocT!DNSDriver(m_events, m_signals);
89-
m_files = mallocT!FileDriver(m_events, m_core);
96+
version (EventcoreEpollUsesUring) m_files = mallocT!FileDriver(m_uring);
97+
else m_files = mallocT!FileDriver(m_events, m_core);
9098
m_watchers = mallocT!WatcherDriver(m_events);
9199
}
92100

@@ -174,7 +182,8 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver {
174182
}
175183

176184

177-
final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTimers, Events : EventDriverEvents, Processes : EventDriverProcesses) : EventDriverCore {
185+
final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTimers, Events : EventDriverEvents, Processes : EventDriverProcesses)
186+
: EventDriverCore {
178187
@safe nothrow:
179188
import core.atomic : atomicLoad, atomicStore;
180189
import core.sync.mutex : Mutex;
@@ -208,6 +217,7 @@ final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTime
208217
m_threadCallbackMutex = mallocT!(shared(Mutex));
209218
m_threadCallbacks = mallocT!(ConsumableQueue!ThreadCallbackEntry);
210219
m_threadCallbacks.reserve(1000);
220+
// m_loop.registerEventID(m_wakeupEvent);
211221
}
212222

213223
final void dispose()
@@ -221,7 +231,9 @@ final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTime
221231
} catch (Exception e) assert(false, e.msg);
222232
}
223233

224-
@property size_t waiterCount() const { return m_loop.m_waiterCount + m_timers.pendingCount + m_processes.pendingCount; }
234+
@property size_t waiterCount() const {
235+
return m_loop.m_waiterCount + m_timers.pendingCount + m_processes.pendingCount;
236+
}
225237

226238
@property Loop loop() { return m_loop; }
227239

@@ -239,12 +251,11 @@ final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTime
239251
if (!waiterCount) {
240252
return ExitReason.outOfWaiters;
241253
}
242-
243254
bool got_events;
244-
245255
if (timeout <= 0.seconds) {
246256
got_events = m_loop.doProcessEvents(0.seconds);
247257
m_timers.process(MonoTime.currTime);
258+
version (EventcoreEpollUsesUring) got_events |= m_uring.doProcessEvents(0.seconds);
248259
} else {
249260
auto now = MonoTime.currTime;
250261
do {
@@ -253,6 +264,7 @@ final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTime
253264
auto prev_step = now;
254265
now = MonoTime.currTime;
255266
got_events |= m_timers.process(now);
267+
version(EventcoreEpollUsesUring) got_events |= m_uring.doProcessEvents(0.seconds);
256268
if (timeout != Duration.max)
257269
timeout -= now - prev_step;
258270
} while (timeout > 0.seconds && !m_exit && !got_events);
@@ -343,7 +355,7 @@ package class PosixEventLoop {
343355
import core.time : Duration;
344356

345357
package {
346-
AlgebraicChoppedVector!(FDSlot, StreamSocketSlot, StreamListenSocketSlot, DgramSocketSlot, DNSSlot, WatcherSlot, EventSlot, SignalSlot, PipeSlot) m_fds;
358+
AlgebraicChoppedVector!(FDSlot, StreamSocketSlot, StreamListenSocketSlot, DgramSocketSlot, DNSSlot, WatcherSlot, EventSlot, SignalSlot, PipeSlot, UringSlot) m_fds;
347359
size_t m_handleCount = 0;
348360
size_t m_waiterCount = 0;
349361
}
@@ -385,8 +397,8 @@ package class PosixEventLoop {
385397
del(FD(i, m_fds[i].common.validationCounter));
386398
}
387399

388-
package(eventcore.drivers) final void addWaiter() { m_waiterCount++; }
389-
package(eventcore.drivers) final void removeWaiter() { m_waiterCount--; }
400+
package(eventcore.drivers) final void addWaiter() @nogc { m_waiterCount++; }
401+
package(eventcore.drivers) final void removeWaiter() @nogc { m_waiterCount--; }
390402

391403
package void setNotifyCallback(EventType evt)(FD fd, FDSlotCallback callback)
392404
{

source/eventcore/drivers/posix/epoll.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ alias EpollEventDriver = PosixEventDriver!EpollEventLoop;
2121
static if (!is(typeof(SOCK_CLOEXEC)))
2222
enum SOCK_CLOEXEC = 0x80000;
2323

24-
final class EpollEventLoop : PosixEventLoop {
24+
class EpollEventLoop : PosixEventLoop {
2525
@safe nothrow:
2626

2727
private {

0 commit comments

Comments
 (0)