Skip to content

Commit 1880f3b

Browse files
authored
Expose io_uring_enter flags using bitflags! macro. (#364)
1 parent 8a753aa commit 1880f3b

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

src/submit.rs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,43 @@ use crate::sys;
77
use crate::types::{CancelBuilder, Timespec};
88
use crate::util::{cast_ptr, OwnedFd};
99
use crate::Parameters;
10+
use bitflags::bitflags;
1011

1112
use crate::register::Restriction;
1213

1314
use crate::types;
1415

16+
bitflags!(
17+
/// See man page for complete description:
18+
/// https://man7.org/linux/man-pages/man2/io_uring_enter.2.html
19+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
20+
pub struct EnterFlags: u32 {
21+
/// Wait for at least `min_complete` events to complete.
22+
const GETEVENTS = sys::IORING_ENTER_GETEVENTS;
23+
24+
/// If the kernel thread is sleeping, wake it up.
25+
const SQ_WAKEUP = sys::IORING_ENTER_SQ_WAKEUP;
26+
27+
/// Wait for at least one submission queue entry to be available.
28+
const SQ_WAIT = sys::IORING_ENTER_SQ_WAIT;
29+
30+
/// Use the extended argument structure.
31+
const EXT_ARG = sys::IORING_ENTER_EXT_ARG;
32+
33+
/// Submit using registered submission queue ring.
34+
const REGISTERED_RING = sys::IORING_ENTER_REGISTERED_RING;
35+
36+
/// Timeout argument interpreted as absolute time.
37+
const ABS_TIMER = sys::IORING_ENTER_ABS_TIMER;
38+
39+
/// Arg is offset into an area of wait regions previously registered.
40+
const EXT_ARG_REG = sys::IORING_ENTER_EXT_ARG_REG;
41+
42+
/// Don't mark waiting task as being in iowait in certain cases.
43+
const NO_IOWAIT = sys::IORING_ENTER_NO_IOWAIT;
44+
}
45+
);
46+
1547
/// Interface for submitting submission queue events in an io_uring instance to the kernel for
1648
/// executing and registering files or buffers with the instance.
1749
///
@@ -113,7 +145,7 @@ impl<'a> Submitter<'a> {
113145
/// completion events to complete.
114146
pub fn submit_and_wait(&self, want: usize) -> io::Result<usize> {
115147
let len = self.sq_len();
116-
let mut flags = 0;
148+
let mut flags = EnterFlags::empty();
117149

118150
// This logic suffers from the fact the sq_cq_overflow and sq_need_wakeup
119151
// each cause an atomic load of the same variable, self.sq_flags.
@@ -135,14 +167,14 @@ impl<'a> Submitter<'a> {
135167
let need_syscall_for_overflow = sq_cq_overflow && self.params.is_feature_nodrop();
136168

137169
if want > 0 || self.params.is_setup_iopoll() || sq_cq_overflow {
138-
flags |= sys::IORING_ENTER_GETEVENTS;
170+
flags.insert(EnterFlags::GETEVENTS);
139171
}
140172

141173
if self.params.is_setup_sqpoll() {
142174
// See discussion in [`SubmissionQueue::need_wakeup`].
143175
atomic::fence(atomic::Ordering::SeqCst);
144176
if self.sq_need_wakeup() {
145-
flags |= sys::IORING_ENTER_SQ_WAKEUP;
177+
flags.insert(EnterFlags::SQ_WAKEUP);
146178
} else if want == 0 && !need_syscall_for_overflow {
147179
// The kernel thread is polling and hasn't fallen asleep, so we don't need to tell
148180
// it to process events or wake it up
@@ -153,7 +185,7 @@ impl<'a> Submitter<'a> {
153185
}
154186
}
155187

156-
unsafe { self.enter::<libc::sigset_t>(len as _, want as _, flags, None) }
188+
unsafe { self.enter::<libc::sigset_t>(len as _, want as _, flags.bits(), None) }
157189
}
158190

159191
/// Submit all queued submission queue events to the kernel and wait for at least `want`
@@ -167,33 +199,33 @@ impl<'a> Submitter<'a> {
167199
args: &types::SubmitArgs<'_, '_>,
168200
) -> io::Result<usize> {
169201
let len = self.sq_len();
170-
let mut flags = sys::IORING_ENTER_EXT_ARG;
202+
let mut flags = EnterFlags::EXT_ARG;
171203

172204
let sq_cq_overflow = self.sq_cq_overflow();
173205
let need_syscall = sq_cq_overflow & self.params.is_feature_nodrop();
174206

175207
if want > 0 || self.params.is_setup_iopoll() || sq_cq_overflow {
176-
flags |= sys::IORING_ENTER_GETEVENTS;
208+
flags.insert(EnterFlags::GETEVENTS);
177209
}
178210

179211
if self.params.is_setup_sqpoll() {
180212
// See discussion in [`SubmissionQueue::need_wakeup`].
181213
atomic::fence(atomic::Ordering::SeqCst);
182214
if self.sq_need_wakeup() {
183-
flags |= sys::IORING_ENTER_SQ_WAKEUP;
215+
flags.insert(EnterFlags::SQ_WAKEUP);
184216
} else if want == 0 && !need_syscall {
185217
// The kernel thread is polling and hasn't fallen asleep, so we don't need to tell
186218
// it to process events or wake it up
187219
return Ok(len);
188220
}
189221
}
190222

191-
unsafe { self.enter(len as _, want as _, flags, Some(args)) }
223+
unsafe { self.enter(len as _, want as _, flags.bits(), Some(args)) }
192224
}
193225

194226
/// Wait for the submission queue to have free entries.
195227
pub fn squeue_wait(&self) -> io::Result<usize> {
196-
unsafe { self.enter::<libc::sigset_t>(0, 0, sys::IORING_ENTER_SQ_WAIT, None) }
228+
unsafe { self.enter::<libc::sigset_t>(0, 0, EnterFlags::SQ_WAIT.bits(), None) }
197229
}
198230

199231
/// Register in-memory fixed buffers for I/O with the kernel. You can use these buffers with the

0 commit comments

Comments
 (0)