-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathsyscall.rs
101 lines (94 loc) · 2.48 KB
/
syscall.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#![allow(unused)]
use std::{convert::TryFrom, io};
use libc::{c_int, c_long, c_uint, syscall};
use super::io_uring_params;
const SETUP: c_long = 425;
const ENTER: c_long = 426;
const REGISTER: c_long = 427;
pub(crate) fn setup(
entries: c_uint,
p: *mut io_uring_params,
) -> io::Result<c_int> {
assert!(
(1..=4096).contains(&entries),
"entries must be between 1 and 4096 (inclusive)"
);
assert_eq!(
entries.count_ones(),
1,
"entries must be a power of 2"
);
#[allow(unsafe_code)]
let ret = unsafe {
syscall(SETUP, i64::from(entries), p as c_long)
};
if ret < 0 {
let mut err = io::Error::last_os_error();
if let Some(12) = err.raw_os_error() {
err = io::Error::new(
io::ErrorKind::Other,
"Not enough lockable memory. You probably \
need to raise the memlock rlimit, which \
often defaults to a pretty low number.",
);
}
return Err(err);
}
Ok(i32::try_from(ret).unwrap())
}
pub(crate) fn enter(
fd: c_int,
to_submit: c_uint,
min_complete: c_uint,
flags: c_uint,
sig: *mut libc::sigset_t,
) -> io::Result<c_int> {
loop {
// this is strapped into an interruption
// diaper loop because it's the one that
// might actually block a lot
#[allow(unsafe_code)]
let ret = unsafe {
syscall(
ENTER,
i64::from(fd),
i64::from(to_submit),
i64::from(min_complete),
i64::from(flags),
sig as c_long,
core::mem::size_of::<libc::sigset_t>()
as c_long,
)
};
if ret < 0 {
let err = io::Error::last_os_error();
if err.kind() == io::ErrorKind::Interrupted {
continue;
}
return Err(err);
} else {
return Ok(i32::try_from(ret).unwrap());
}
}
}
pub(crate) fn register(
fd: c_int,
opcode: c_uint,
arg: *const libc::c_void,
nr_args: c_uint,
) -> io::Result<c_int> {
#[allow(unsafe_code)]
let ret = unsafe {
syscall(
REGISTER,
i64::from(fd),
i64::from(opcode),
arg as c_long,
i64::from(nr_args),
)
};
if ret < 0 {
return Err(io::Error::last_os_error());
}
Ok(i32::try_from(ret).unwrap())
}