mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
simplify FdSet using bitvec crate
This commit is contained in:
parent
c99b7a1aed
commit
c9a68634f5
7
kernel/Cargo.lock
generated
7
kernel/Cargo.lock
generated
@ -81,6 +81,11 @@ name = "bitvec"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.11.0"
|
||||
source = "git+https://github.com/myrrlyn/bitvec.git#f6e1fbed95061955d96617dfed6c112ffba45a7e"
|
||||
|
||||
[[package]]
|
||||
name = "bootloader"
|
||||
version = "0.4.0"
|
||||
@ -308,6 +313,7 @@ dependencies = [
|
||||
"bit-allocator 0.1.0",
|
||||
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)",
|
||||
"bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)",
|
||||
"buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -594,6 +600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum bcm2837 0.1.0 (git+https://github.com/rcore-os/bcm2837)" = "<none>"
|
||||
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
"checksum bitvec 0.11.0 (git+https://github.com/myrrlyn/bitvec.git)" = "<none>"
|
||||
"checksum bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfadef5c4e2c2e64067b9ecc061179f12ac7ec65ba613b1f60f3972bbada1f5b"
|
||||
"checksum bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)" = "<none>"
|
||||
"checksum buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed828f1e227d6e32b998d6375b67fd63ac5389d50b23f258ce151d22b6cc595"
|
||||
|
@ -42,6 +42,7 @@ bitflags = "1.0"
|
||||
bit_field = "0.9"
|
||||
volatile = "0.2"
|
||||
heapless = "0.4"
|
||||
bitvec = { git = "https://github.com/myrrlyn/bitvec.git", default-features = false, features = ["alloc"] }
|
||||
console-traits = "0.3"
|
||||
buddy_system_allocator = "0.1"
|
||||
pci = { git = "https://github.com/rcore-os/pci-rs" }
|
||||
|
@ -10,6 +10,8 @@ use crate::fs::*;
|
||||
use crate::memory::MemorySet;
|
||||
use crate::sync::Condvar;
|
||||
|
||||
use bitvec::{BitSlice, BitVec, LittleEndian};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult {
|
||||
@ -160,30 +162,30 @@ pub fn sys_select(
|
||||
loop {
|
||||
let proc = process();
|
||||
let mut events = 0;
|
||||
for (fd, file_like) in proc.files.iter() {
|
||||
if *fd < nfds {
|
||||
for (&fd, file_like) in proc.files.iter() {
|
||||
if fd < nfds {
|
||||
match file_like {
|
||||
FileLike::File(_) => {
|
||||
// FIXME: assume it is stdin for now
|
||||
if STDIN.can_read() {
|
||||
if read_fds.is_set(*fd) {
|
||||
read_fds.set(*fd);
|
||||
if read_fds.contains(fd) {
|
||||
read_fds.set(fd);
|
||||
events = events + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
FileLike::Socket(socket) => {
|
||||
let (input, output, err) = socket.poll();
|
||||
if err && err_fds.is_set(*fd) {
|
||||
err_fds.set(*fd);
|
||||
if err && err_fds.contains(fd) {
|
||||
err_fds.set(fd);
|
||||
events = events + 1;
|
||||
}
|
||||
if input && read_fds.is_set(*fd) {
|
||||
read_fds.set(*fd);
|
||||
if input && read_fds.contains(fd) {
|
||||
read_fds.set(fd);
|
||||
events = events + 1;
|
||||
}
|
||||
if output && write_fds.is_set(*fd) {
|
||||
write_fds.set(*fd);
|
||||
if output && write_fds.contains(fd) {
|
||||
write_fds.set(fd);
|
||||
events = events + 1;
|
||||
}
|
||||
}
|
||||
@ -1172,54 +1174,51 @@ const FD_PER_ITEM: usize = 8 * size_of::<u32>();
|
||||
const MAX_FDSET_SIZE: usize = 1024 / FD_PER_ITEM;
|
||||
|
||||
struct FdSet {
|
||||
addr: *mut u32,
|
||||
nfds: usize,
|
||||
saved: [u32; MAX_FDSET_SIZE],
|
||||
bitset: &'static mut BitSlice<LittleEndian, u32>,
|
||||
origin: BitVec<LittleEndian, u32>,
|
||||
}
|
||||
|
||||
impl FdSet {
|
||||
/// Initialize a `FdSet` from pointer and number of fds
|
||||
/// Check if the array is large enough
|
||||
fn new(vm: &MemorySet, addr: *mut u32, nfds: usize) -> Result<FdSet, SysError> {
|
||||
let mut saved = [0u32; MAX_FDSET_SIZE];
|
||||
if addr as usize != 0 {
|
||||
if addr.is_null() {
|
||||
Ok(FdSet {
|
||||
bitset: BitSlice::empty_mut(),
|
||||
origin: BitVec::new(),
|
||||
})
|
||||
} else {
|
||||
let len = (nfds + FD_PER_ITEM - 1) / FD_PER_ITEM;
|
||||
vm.check_write_array(addr, len)?;
|
||||
if len > MAX_FDSET_SIZE {
|
||||
return Err(SysError::EINVAL);
|
||||
}
|
||||
let slice = unsafe { slice::from_raw_parts_mut(addr, len) };
|
||||
let bitset: &'static mut BitSlice<LittleEndian, u32> = slice.into();
|
||||
|
||||
// save the fdset, and clear it
|
||||
for i in 0..len {
|
||||
saved[i] = slice[i];
|
||||
slice[i] = 0;
|
||||
}
|
||||
use alloc::prelude::ToOwned;
|
||||
let origin = bitset.to_owned();
|
||||
bitset.set_all(false);
|
||||
Ok(FdSet { bitset, origin })
|
||||
}
|
||||
|
||||
Ok(FdSet { addr, nfds, saved })
|
||||
}
|
||||
|
||||
/// Try to set fd in `FdSet`
|
||||
/// Return true when `FdSet` is valid, and false when `FdSet` is bad (i.e. null pointer)
|
||||
/// Fd should be less than nfds
|
||||
fn set(&mut self, fd: usize) -> bool {
|
||||
if self.addr as usize != 0 {
|
||||
assert!(fd < self.nfds);
|
||||
unsafe {
|
||||
*self.addr.add(fd / 8 / size_of::<u32>()) |= 1 << (fd % (8 * size_of::<u32>()));
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
if self.bitset.is_empty() {
|
||||
return false;
|
||||
}
|
||||
self.bitset.set(fd, true);
|
||||
true
|
||||
}
|
||||
|
||||
/// Check to see fd is see in original `FdSet`
|
||||
/// Check to see whether `fd` is in original `FdSet`
|
||||
/// Fd should be less than nfds
|
||||
fn is_set(&mut self, fd: usize) -> bool {
|
||||
assert!(fd < self.nfds);
|
||||
self.saved[fd / 8 / size_of::<u32>()] & (1 << (fd % (8 * size_of::<u32>()))) != 0
|
||||
fn contains(&self, fd: usize) -> bool {
|
||||
self.origin[fd]
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user