Skip to content

Commit

Permalink
Start porting tokio/mio.
Browse files Browse the repository at this point in the history
Things look promising: a simple test (sys/mio-test) works.

Still a lot of work to do.
  • Loading branch information
lasiotus committed Dec 8, 2024
1 parent c7c0dff commit 732bcce
Show file tree
Hide file tree
Showing 16 changed files with 1,384 additions and 118 deletions.
20 changes: 20 additions & 0 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ dependencies = [
"mdbg_debug",
"rnetbench_debug",
"systest_debug",
"mio_test_debug",
"make_img_debug",
]

Expand All @@ -78,6 +79,7 @@ dependencies = [
"mdbg_release",
"rnetbench_release",
"systest_release",
"mio_test_release",
"make_img_release",
]

Expand All @@ -99,6 +101,7 @@ dependencies = [
"mdbg_debug",
"rnetbench_debug",
"systest_debug",
"mio_test_debug",
"make_img_debug",
]

Expand All @@ -120,6 +123,7 @@ dependencies = [
"mdbg_release",
"rnetbench_release",
"systest_release",
"mio_test_release",
"make_img_release",
]

Expand Down Expand Up @@ -294,6 +298,22 @@ cargo +dev-x86_64-unknown-moturus clippy --release --target x86_64-unknown-motur
cp "${CARGO_TARGET_DIR}/x86_64-unknown-moturus/release/systest" "${MOTO_BIN}/systest"
'''

[tasks.mio_test_debug]
cwd = "./src/sys/tests/mio-test"
script = '''
cargo +dev-x86_64-unknown-moturus build --target x86_64-unknown-moturus
cargo +dev-x86_64-unknown-moturus clippy --target x86_64-unknown-moturus
strip -o "${MOTO_BIN}/mio-test" "${CARGO_TARGET_DIR}/x86_64-unknown-moturus/debug/mio-test"
'''

[tasks.mio_test_release]
cwd = "./src/sys/tests/mio-test"
script = '''
cargo +dev-x86_64-unknown-moturus build --release --target x86_64-unknown-moturus
cargo +dev-x86_64-unknown-moturus clippy --release --target x86_64-unknown-moturus
cp "${CARGO_TARGET_DIR}/x86_64-unknown-moturus/release/mio-test" "${MOTO_BIN}/mio-test"
'''

[tasks.rush_debug]
cwd = "./src/bin/rush"
script = '''
Expand Down
4 changes: 2 additions & 2 deletions src/imager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::io::{self, Seek, SeekFrom};
const SECTOR_SIZE: u32 = 512;

// For the "full" image.
static BIN_FULL: [&str; 10] = [
static BIN_FULL: [&str; 11] = [
"bin/httpd",
"bin/kibim",
"bin/rush",
Expand All @@ -31,7 +31,7 @@ static BIN_FULL: [&str; 10] = [
"sys/sys-tty",
"sys/sysbox",
"sys/systest",
// "sys/mio-test",
"sys/mio-test",
];

// For the "web" image.
Expand Down
51 changes: 38 additions & 13 deletions src/sys/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ members = [
"tools/sysbox",

# tests
"tests/mio-test",
"tests/systest",
]
resolver = "2"
Expand Down
21 changes: 21 additions & 0 deletions src/sys/lib/moto-ipc/src/io_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,17 @@ impl RawChannel {
}
}

fn may_alloc_page(&self, subchannel: SubChannel) -> bool {
let (bitmap_ref, subchannel_mask) = match subchannel {
SubChannel::Client(mask) => (&self.client_pages_in_use, mask),
SubChannel::Server(mask) => (&self.server_pages_in_use, mask),
};

let bitmap = bitmap_ref.load(Ordering::Relaxed);
let ones = (bitmap | !subchannel_mask).trailing_ones();
ones != 64
}

fn alloc_page(&self, subchannel: SubChannel) -> Result<RawIoPage, ErrorCode> {
let (bitmap_ref, subchannel_mask) = match subchannel {
SubChannel::Client(mask) => (&self.client_pages_in_use, mask),
Expand Down Expand Up @@ -535,6 +546,11 @@ impl ClientConnection {
}
}

pub fn may_alloc_page(&self, subchannel_mask: u64) -> bool {
self.raw_channel()
.may_alloc_page(SubChannel::Client(subchannel_mask))
}

pub fn get_page(&self, page_idx: u16) -> Result<IoPage, ErrorCode> {
if page_idx & !IoPage::SERVER_FLAG > (CHANNEL_PAGE_COUNT as u16) {
Err(moto_rt::E_INVALID_ARGUMENT)
Expand Down Expand Up @@ -744,6 +760,11 @@ impl ServerConnection {
}
}

pub fn may_alloc_page(&self, subchannel_mask: u64) -> bool {
self.raw_channel()
.may_alloc_page(SubChannel::Server(subchannel_mask))
}

pub fn get_page(&self, page_idx: u16) -> Result<IoPage, ErrorCode> {
if page_idx & !IoPage::SERVER_FLAG > (CHANNEL_PAGE_COUNT as u16) {
Err(moto_rt::E_INVALID_ARGUMENT)
Expand Down
10 changes: 10 additions & 0 deletions src/sys/lib/moto-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ pub mod net;
#[allow(nonstandard_style)]
pub mod netc;

#[cfg(not(feature = "base"))]
pub mod poll;
#[cfg(not(feature = "base"))]
pub mod process;
#[cfg(not(feature = "base"))]
Expand Down Expand Up @@ -199,6 +201,7 @@ pub struct RtVdsoVtableV1 {
// Networking.
pub dns_lookup: AtomicU64,
pub net_bind: AtomicU64,
pub net_listen: AtomicU64,
pub net_accept: AtomicU64,
pub net_tcp_connect: AtomicU64,
pub net_udp_connect: AtomicU64,
Expand All @@ -210,6 +213,13 @@ pub struct RtVdsoVtableV1 {
pub net_udp_recv_from: AtomicU64,
pub net_udp_peek_from: AtomicU64,
pub net_udp_send_to: AtomicU64,

// Polling.
pub poll_new: AtomicU64,
pub poll_add: AtomicU64,
pub poll_set: AtomicU64,
pub poll_del: AtomicU64,
pub poll_wait: AtomicU64,
}

#[cfg(not(feature = "base"))]
Expand Down
33 changes: 26 additions & 7 deletions src/sys/lib/moto-rt/src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub const SO_SNDTIMEO: u64 = 2;
pub const SO_SHUTDOWN: u64 = 3;
pub const SO_NODELAY: u64 = 4;
pub const SO_TTL: u64 = 5;
pub const SO_NONBLOCKING: u64 = 6;

fn setsockopt(rt_fd: RtFd, opt: u64, ptr: usize, len: usize) -> Result<(), ErrorCode> {
let vdso_setsockopt: extern "C" fn(RtFd, u64, usize, usize) -> ErrorCode = unsafe {
Expand Down Expand Up @@ -52,6 +53,16 @@ pub fn bind(proto: u8, addr: &netc::sockaddr) -> Result<RtFd, ErrorCode> {
to_result!(vdso_bind(proto, addr))
}

pub fn listen(rt_fd: RtFd, max_backlog: u32) -> Result<(), ErrorCode> {
let vdso_listen: extern "C" fn(RtFd, u32) -> ErrorCode = unsafe {
core::mem::transmute(
RtVdsoVtableV1::get().net_listen.load(Ordering::Relaxed) as usize as *const (),
)
};

ok_or_error(vdso_listen(rt_fd, max_backlog))
}

pub fn accept(rt_fd: RtFd) -> Result<(RtFd, netc::sockaddr), ErrorCode> {
let vdso_accept: extern "C" fn(RtFd, *mut netc::sockaddr) -> RtFd = unsafe {
core::mem::transmute(
Expand All @@ -68,6 +79,9 @@ pub fn accept(rt_fd: RtFd) -> Result<(RtFd, netc::sockaddr), ErrorCode> {
Ok((res, addr))
}

/// Create a TCP stream by connecting to a remote addr.
///
/// If timeout.is_zero(), the connect is nonblocking.
pub fn tcp_connect(addr: &netc::sockaddr, timeout: Duration) -> Result<RtFd, ErrorCode> {
let vdso_tcp_connect: extern "C" fn(*const netc::sockaddr, u64) -> RtFd = unsafe {
core::mem::transmute(
Expand Down Expand Up @@ -100,9 +114,7 @@ pub fn socket_addr(_rt_fd: RtFd) -> Result<netc::sockaddr, ErrorCode> {
pub fn peer_addr(rt_fd: RtFd) -> Result<netc::sockaddr, ErrorCode> {
let vdso_peer_addr: extern "C" fn(RtFd, *mut netc::sockaddr) -> ErrorCode = unsafe {
core::mem::transmute(
RtVdsoVtableV1::get()
.net_peer_addr
.load(Ordering::Relaxed) as usize as *const (),
RtVdsoVtableV1::get().net_peer_addr.load(Ordering::Relaxed) as usize as *const (),
)
};

Expand Down Expand Up @@ -135,11 +147,12 @@ pub fn only_v6(_rt_fd: RtFd) -> Result<bool, ErrorCode> {

pub fn take_error(_rt_fd: RtFd) -> Result<ErrorCode, ErrorCode> {
// getsockopt
Err(crate::E_NOT_IMPLEMENTED)
todo!()
}

pub fn set_nonblocking(_rt_fd: RtFd, _nonblocking: bool) -> Result<(), ErrorCode> {
todo!()
pub fn set_nonblocking(rt_fd: RtFd, nonblocking: bool) -> Result<(), ErrorCode> {
let nonblocking: u8 = if nonblocking { 1 } else { 0 };
setsockopt(rt_fd, SO_NONBLOCKING, &nonblocking as *const _ as usize, 1)
}

pub fn peek(_rt_fd: RtFd, _buf: &mut [u8]) -> Result<usize, ErrorCode> {
Expand All @@ -153,6 +166,7 @@ pub fn set_read_timeout(rt_fd: RtFd, timeout: Option<Duration>) -> Result<(), Er
};

if timeout == 0 {
// See TcpStream::set_read_timeout() doc in Rust stdlib.
return Err(crate::E_INVALID_ARGUMENT);
}

Expand Down Expand Up @@ -187,6 +201,11 @@ pub fn set_write_timeout(rt_fd: RtFd, timeout: Option<Duration>) -> Result<(), E
None => u64::MAX,
};

if timeout == 0 {
// See TcpStream::set_write_timeout() doc in Rust stdlib.
return Err(crate::E_INVALID_ARGUMENT);
}

setsockopt(
rt_fd,
SO_SNDTIMEO,
Expand Down Expand Up @@ -229,7 +248,7 @@ pub fn linger(_rt_fd: RtFd) -> Result<Option<Duration>, ErrorCode> {
}

pub fn set_nodelay(rt_fd: RtFd, nodelay: bool) -> Result<(), ErrorCode> {
let nodelay = if nodelay { 1 } else { 0 };
let nodelay: u8 = if nodelay { 1 } else { 0 };
setsockopt(rt_fd, SO_NODELAY, &nodelay as *const _ as usize, 1)
}

Expand Down
Loading

0 comments on commit 732bcce

Please sign in to comment.