Skip to content

Commit

Permalink
Implement poll function for axlibc and posix_api
Browse files Browse the repository at this point in the history
  • Loading branch information
ken4647 committed Sep 13, 2023
1 parent 6a29b07 commit 2f51976
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 22 deletions.
1 change: 1 addition & 0 deletions api/arceos_posix_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ net = ["dep:axnet", "axfeat/net", "fd"]
pipe = ["fd"]
select = ["fd"]
epoll = ["fd"]
poll = ["fd"]

[dependencies]
# ArceOS modules
Expand Down
2 changes: 2 additions & 0 deletions api/arceos_posix_api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ typedef struct {{
"pthread_attr_t",
"pthread_mutex_t",
"pthread_mutexattr_t",
"pollfd",
"nfds_t",
"epoll_event",
"iovec",
"clockid_t",
Expand Down
1 change: 1 addition & 0 deletions api/arceos_posix_api/ctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <sys/epoll.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
Expand Down
4 changes: 4 additions & 0 deletions api/arceos_posix_api/src/imp/io_mpx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
mod epoll;
#[cfg(feature = "select")]
mod select;
#[cfg(feature = "poll")]
mod poll;

#[cfg(feature = "epoll")]
pub use self::epoll::{sys_epoll_create, sys_epoll_ctl, sys_epoll_wait};
#[cfg(feature = "select")]
pub use self::select::sys_select;
#[cfg(feature = "poll")]
pub use self::poll::sys_poll;
68 changes: 68 additions & 0 deletions api/arceos_posix_api/src/imp/io_mpx/poll.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::{
ctypes,
imp::fd_ops::get_file_like,
};
use axerrno::{LinuxError, LinuxResult};
use axhal::time::current_time;

use core::{ffi::c_int, time::Duration};

fn poll_all(fds: &mut [ctypes::pollfd]) -> LinuxResult<usize> {
let mut events_num = 0;

for pollfd_item in fds.iter_mut() {
let intfd = pollfd_item.fd;
let events = pollfd_item.events;
let revents = &mut pollfd_item.revents;
match get_file_like(intfd as c_int)?.poll() {
Err(_) => {
if (events & ctypes::EPOLLERR as i16) != 0 {
*revents |= ctypes::EPOLLERR as i16;
}
}
Ok(state) => {
if state.readable && (events & ctypes::EPOLLIN as i16 != 0) {
*revents |= ctypes::EPOLLIN as i16;
}

if state.writable && (events & ctypes::EPOLLOUT as i16 != 0) {
*revents |= ctypes::EPOLLOUT as i16;
}
}
}
events_num += 1;
}
Ok(events_num)
}

// used to monitor multiple file descriptors for events
pub unsafe fn sys_poll(
fds: *mut ctypes::pollfd,
nfds: ctypes::nfds_t,
timeout: c_int
) -> c_int{
debug!("ax_poll <= nfds: {} timeout: {}", nfds, timeout);

syscall_body!(ax_poll, {
if nfds <= 0 {
return Err(LinuxError::EINVAL);
}
let fds = core::slice::from_raw_parts_mut(fds, nfds as usize);
let deadline = (!timeout.is_negative())
.then(|| current_time() + Duration::from_millis(timeout as u64));
loop {
#[cfg(feature = "net")]
axnet::poll_interfaces();
let fds_num = poll_all(fds)?;
if fds_num > 0 {
return Ok(fds_num as c_int);
}

if deadline.map_or(false, |ddl| current_time() >= ddl) {
debug!(" timeout!");
return Ok(0);
}
crate::sys_sched_yield();
}
})
}
2 changes: 1 addition & 1 deletion api/arceos_posix_api/src/imp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub mod time;
pub mod fd_ops;
#[cfg(feature = "fs")]
pub mod fs;
#[cfg(any(feature = "select", feature = "epoll"))]
#[cfg(any(feature = "select", feature = "poll", feature = "epoll"))]
pub mod io_mpx;
#[cfg(feature = "net")]
pub mod net;
Expand Down
2 changes: 2 additions & 0 deletions api/arceos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub use imp::fs::{sys_fstat, sys_getcwd, sys_lseek, sys_lstat, sys_open, sys_ren
pub use imp::io_mpx::sys_select;
#[cfg(feature = "epoll")]
pub use imp::io_mpx::{sys_epoll_create, sys_epoll_ctl, sys_epoll_wait};
#[cfg(feature = "poll")]
pub use imp::io_mpx::sys_poll;
#[cfg(feature = "net")]
pub use imp::net::{
sys_accept, sys_bind, sys_connect, sys_freeaddrinfo, sys_getaddrinfo, sys_getpeername,
Expand Down
4 changes: 2 additions & 2 deletions scripts/make/features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
ifeq ($(APP_TYPE),c)
ax_feat_prefix := axfeat/
lib_feat_prefix := axlibc/
lib_features := fp_simd alloc multitask fs net fd pipe select epoll
lib_features := fp_simd alloc multitask fs net fd pipe select poll epoll
else
# TODO: it's better to use `axfeat/` as `ax_feat_prefix`, but all apps need to have `axfeat` as a dependency
ax_feat_prefix := axstd/
Expand All @@ -28,7 +28,7 @@ ifeq ($(APP_TYPE), c)
ifneq ($(wildcard $(APP)/features.txt),) # check features.txt exists
override FEATURES += $(shell cat $(APP)/features.txt)
endif
ifneq ($(filter fs net pipe select epoll,$(FEATURES)),)
ifneq ($(filter fs net pipe select poll epoll,$(FEATURES)),)
override FEATURES += fd
endif
endif
Expand Down
1 change: 1 addition & 0 deletions ulib/axlibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ net = ["arceos_posix_api/net", "fd"]
fd = []
pipe = ["arceos_posix_api/pipe"]
select = ["arceos_posix_api/select"]
poll = ["arceos_posix_api/poll"]
epoll = ["arceos_posix_api/epoll"]

[dependencies]
Expand Down
18 changes: 0 additions & 18 deletions ulib/axlibc/c/poll.c

This file was deleted.

File renamed without changes.
14 changes: 14 additions & 0 deletions ulib/axlibc/src/io_mpx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use core::ffi::c_int;

#[cfg(feature = "select")]
use arceos_posix_api::sys_select;
#[cfg(feature = "poll")]
use arceos_posix_api::sys_poll;
#[cfg(feature = "epoll")]
use arceos_posix_api::{sys_epoll_create, sys_epoll_ctl, sys_epoll_wait};

Expand Down Expand Up @@ -61,3 +63,15 @@ pub unsafe extern "C" fn select(
) -> c_int {
e(sys_select(nfds, readfds, writefds, exceptfds, timeout))
}


/// Monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation
#[cfg(feature = "poll")]
#[no_mangle]
pub unsafe extern "C" fn poll(
fds: *mut ctypes::pollfd,
nfds: ctypes::nfds_t,
timeout: c_int
) -> c_int {
e(sys_poll(fds, nfds, timeout))
}
4 changes: 3 additions & 1 deletion ulib/axlibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ mod utils;
mod fd_ops;
#[cfg(feature = "fs")]
mod fs;
#[cfg(any(feature = "select", feature = "epoll"))]
#[cfg(any(feature = "select", feature = "poll", feature = "epoll"))]
mod io_mpx;
#[cfg(feature = "alloc")]
mod malloc;
Expand Down Expand Up @@ -127,6 +127,8 @@ pub use self::pipe::pipe;

#[cfg(feature = "select")]
pub use self::io_mpx::select;
#[cfg(feature = "poll")]
pub use self::io_mpx::poll;
#[cfg(feature = "epoll")]
pub use self::io_mpx::{epoll_create, epoll_ctl, epoll_wait};

Expand Down

0 comments on commit 2f51976

Please sign in to comment.