From 3b1626260dc764b98ba04c6a4a92073a5ac8cd6f Mon Sep 17 00:00:00 2001 From: yanglv Date: Tue, 26 Sep 2023 19:44:10 +0800 Subject: [PATCH] =?UTF-8?q?test:=E6=B5=8B=E8=AF=95=E6=95=B4=E7=90=86?= =?UTF-8?q?=EF=BC=8C=E6=8F=90=E5=8D=87=E6=B5=8B=E8=AF=95=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除不必要的derive(Clone), 不再pub mod util并删除util中未使用到的函数,同时将相关的测试从sdv中移动到具体目录下。 删除以前测试中多此一举的if let Err(e) = xxx{panic!} Signed-off-by: yanglv --- ylong_io/src/sys/linux/epoll.rs | 2 +- ylong_io/src/sys/windows/net.rs | 1 - ylong_runtime/Cargo.toml | 8 +- ylong_runtime/src/executor/async_pool.rs | 1 - ylong_runtime/src/executor/blocking_pool.rs | 1 - ylong_runtime/src/executor/netpoller.rs | 1 - ylong_runtime/src/lib.rs | 11 +- ylong_runtime/src/sync/error.rs | 2 +- ylong_runtime/src/sync/mutex.rs | 2 +- ylong_runtime/src/sync/wake_list.rs | 2 +- ylong_runtime/src/task/builder.rs | 1 - ylong_runtime/src/task/mod.rs | 1 - ylong_runtime/src/task/raw.rs | 10 +- ylong_runtime/src/time/wheel.rs | 2 +- ylong_runtime/src/util/bit.rs | 1455 ++++++++--------- ylong_runtime/src/util/core_affinity/linux.rs | 74 +- ylong_runtime/src/util/core_affinity/mod.rs | 1 + ylong_runtime/src/util/num_cpus/linux.rs | 17 +- ylong_runtime/src/util/num_cpus/mod.rs | 6 + ylong_runtime/src/util/slab.rs | 273 +++- ylong_runtime/src/util/slots.rs | 470 ++---- ylong_runtime/tests/core_affinity.rs | 50 - ylong_runtime/tests/entry.rs | 4 - ylong_runtime/tests/num_cpus.rs | 32 - ylong_runtime/tests/slab.rs | 289 ---- ylong_runtime/tests/slots.rs | 154 -- ylong_runtime/tests/task_cancel.rs | 19 +- ylong_runtime/tests/tcp_test.rs | 72 +- ylong_runtime/tests/udp_test.rs | 207 +-- 29 files changed, 1212 insertions(+), 1956 deletions(-) delete mode 100644 ylong_runtime/tests/core_affinity.rs delete mode 100644 ylong_runtime/tests/num_cpus.rs delete mode 100644 ylong_runtime/tests/slab.rs delete mode 100644 ylong_runtime/tests/slots.rs diff --git a/ylong_io/src/sys/linux/epoll.rs b/ylong_io/src/sys/linux/epoll.rs index a63a7c6..6d7de78 100644 --- a/ylong_io/src/sys/linux/epoll.rs +++ b/ylong_io/src/sys/linux/epoll.rs @@ -103,7 +103,7 @@ impl Selector { self.ep, libc::EPOLL_CTL_DEL, fd, - std::ptr::null_mut() as *mut libc::epoll_event + std::ptr::null_mut() )) { Ok(_) => Ok(()), Err(err) => Err(err), diff --git a/ylong_io/src/sys/windows/net.rs b/ylong_io/src/sys/windows/net.rs index cdc6e25..5b87865 100644 --- a/ylong_io/src/sys/windows/net.rs +++ b/ylong_io/src/sys/windows/net.rs @@ -113,7 +113,6 @@ impl NetState { } /// This structure used to re-register the socket when Err(WouldBlock) occurs -#[derive(Clone)] pub(crate) struct NetInner { selector: Arc, token: Token, diff --git a/ylong_runtime/Cargo.toml b/ylong_runtime/Cargo.toml index 34ea2b7..76811a9 100644 --- a/ylong_runtime/Cargo.toml +++ b/ylong_runtime/Cargo.toml @@ -8,7 +8,13 @@ repository = "https://gitee.com/openharmony/commonlibrary_rust_ylong_runtime" keywords = ["ylong", "runtime", "executor"] [features] -default = [] +default = [ + "net", + "sync", + "time", + "fs", + "macros", +] full = [ "net", diff --git a/ylong_runtime/src/executor/async_pool.rs b/ylong_runtime/src/executor/async_pool.rs index be68fdf..e9a008a 100644 --- a/ylong_runtime/src/executor/async_pool.rs +++ b/ylong_runtime/src/executor/async_pool.rs @@ -291,7 +291,6 @@ impl MultiThreadScheduler { ); } -#[derive(Clone)] pub(crate) struct AsyncPoolSpawner { pub(crate) inner: Arc, diff --git a/ylong_runtime/src/executor/blocking_pool.rs b/ylong_runtime/src/executor/blocking_pool.rs index 1cd83d1..e7d2618 100644 --- a/ylong_runtime/src/executor/blocking_pool.rs +++ b/ylong_runtime/src/executor/blocking_pool.rs @@ -28,7 +28,6 @@ use crate::{task, JoinHandle}; pub(crate) const BLOCKING_THREAD_QUIT_WAIT_TIME: Duration = Duration::from_secs(3); -#[derive(Clone)] pub(crate) struct BlockPoolSpawner { inner: Arc, } diff --git a/ylong_runtime/src/executor/netpoller.rs b/ylong_runtime/src/executor/netpoller.rs index 4bad258..3f92cfb 100644 --- a/ylong_runtime/src/executor/netpoller.rs +++ b/ylong_runtime/src/executor/netpoller.rs @@ -22,7 +22,6 @@ use crate::time::TimeDriver; const NET_POLL_INTERVAL_TIME: std::time::Duration = std::time::Duration::from_millis(10); /// Net poller thread creation and management -#[derive(Clone)] pub(crate) struct NetLooper { inner: Arc, } diff --git a/ylong_runtime/src/lib.rs b/ylong_runtime/src/lib.rs index b3dfd19..6cd5095 100644 --- a/ylong_runtime/src/lib.rs +++ b/ylong_runtime/src/lib.rs @@ -38,19 +38,18 @@ use crate::task::{JoinHandle, Task, TaskBuilder}; pub mod builder; pub mod error; pub mod executor; +pub mod futures; +pub mod io; +pub mod iter; #[cfg(feature = "ffrt")] pub(crate) mod ffrt; #[cfg(feature = "fs")] pub mod fs; -pub mod futures; -pub mod io; -pub mod iter; #[cfg(feature = "macros")] mod select; #[cfg(feature = "macros")] pub use ylong_runtime_macros::tuple_form; -pub(crate) mod spawn; #[cfg(feature = "sync")] pub mod sync; pub mod task; @@ -59,7 +58,9 @@ cfg_time! { pub mod time; } -pub mod util; +mod spawn; +mod util; + cfg_metrics!( mod metrics; pub use metrics::Metrics; diff --git a/ylong_runtime/src/sync/error.rs b/ylong_runtime/src/sync/error.rs index e0137e3..5b0cd06 100644 --- a/ylong_runtime/src/sync/error.rs +++ b/ylong_runtime/src/sync/error.rs @@ -61,7 +61,7 @@ impl Display for TrySendError { impl Error for TrySendError {} /// Error returned by `try_recv`. -#[derive(Debug, Eq, PartialEq, Clone)] +#[derive(Debug, Eq, PartialEq)] pub enum TryRecvError { /// sender has not sent a value yet. Empty, diff --git a/ylong_runtime/src/sync/mutex.rs b/ylong_runtime/src/sync/mutex.rs index 5cef039..c9e6e82 100644 --- a/ylong_runtime/src/sync/mutex.rs +++ b/ylong_runtime/src/sync/mutex.rs @@ -43,7 +43,7 @@ unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} /// Error of Mutex -#[derive(Debug, Eq, PartialEq, Clone)] +#[derive(Debug, Eq, PartialEq)] pub struct LockError; impl Display for LockError { diff --git a/ylong_runtime/src/sync/wake_list.rs b/ylong_runtime/src/sync/wake_list.rs index 283c2a9..ac5749a 100644 --- a/ylong_runtime/src/sync/wake_list.rs +++ b/ylong_runtime/src/sync/wake_list.rs @@ -185,7 +185,7 @@ mod tests { let wakelist = WakerList::new(); assert_eq!(wakelist.flag.load(Ordering::SeqCst), 0); unsafe { - assert_eq!((*wakelist.inner.get()).wake_list.len(), 0); + assert_eq!((*wakelist.inner.get()).wake_list.len, 0); } } } diff --git a/ylong_runtime/src/task/builder.rs b/ylong_runtime/src/task/builder.rs index 6d543c9..0b44d7b 100644 --- a/ylong_runtime/src/task/builder.rs +++ b/ylong_runtime/src/task/builder.rs @@ -25,7 +25,6 @@ use crate::task::Qos; use crate::JoinHandle; /// Tasks attribute -#[derive(Clone)] pub struct TaskBuilder { pub(crate) name: Option, pub(crate) qos: Option, diff --git a/ylong_runtime/src/task/mod.rs b/ylong_runtime/src/task/mod.rs index 88b989b..6e3d6ff 100644 --- a/ylong_runtime/src/task/mod.rs +++ b/ylong_runtime/src/task/mod.rs @@ -64,7 +64,6 @@ pub enum Qos { pub use ylong_ffrt::Qos; #[repr(transparent)] -#[derive(Clone)] pub(crate) struct Task(pub(crate) RawTask); unsafe impl Send for Task {} diff --git a/ylong_runtime/src/task/raw.rs b/ylong_runtime/src/task/raw.rs index bc569c2..bd5677f 100644 --- a/ylong_runtime/src/task/raw.rs +++ b/ylong_runtime/src/task/raw.rs @@ -55,7 +55,7 @@ pub(crate) struct Header { pub(crate) vtable: &'static TaskVirtualTable, } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, Clone, Copy)] pub(crate) struct RawTask { pub(crate) ptr: NonNull
, } @@ -114,14 +114,6 @@ impl RawTask { } } -impl Copy for RawTask {} - -impl Clone for RawTask { - fn clone(&self) -> Self { - RawTask { ptr: self.ptr } - } -} - pub(crate) enum Stage { Executing(T), Executed, diff --git a/ylong_runtime/src/time/wheel.rs b/ylong_runtime/src/time/wheel.rs index 5fe671a..1cabe7b 100644 --- a/ylong_runtime/src/time/wheel.rs +++ b/ylong_runtime/src/time/wheel.rs @@ -126,7 +126,7 @@ impl Wheel { if expiration <= self.elapsed() { // This means that the timeout period has passed, // and the time should be triggered immediately. - return Err(Error::default()); + return Err(Error); } let level = self.find_level(expiration); diff --git a/ylong_runtime/src/util/bit.rs b/ylong_runtime/src/util/bit.rs index a14a85b..7d55e74 100644 --- a/ylong_runtime/src/util/bit.rs +++ b/ylong_runtime/src/util/bit.rs @@ -232,754 +232,737 @@ impl Bit { pub fn get_by_mask(&self, mask: Mask) -> usize { (self.0 & mask.mask) >> mask.shift } - - /// Sets bit to a new usize value. - /// - /// # Example - /// ```not run - /// use ylong_runtime::util::bit::{Mask, Bit}; - /// - /// let base = 0x0usize; - /// let mut bits = Bit::from_usize(base); - /// bits.set(0xffff_ffff_ffff_ffff); - /// assert_eq!(bits.as_usize(), 0xffff_ffff_ffff_ffff); - /// ``` - pub fn set(&mut self, val: usize) { - self.0 = val; - } - - /// Clear bit to 0usize - /// - /// # Example - /// ```rust - /// use ylong_runtime::util::bit::{Bit, Mask}; - /// - /// let base = 0xffffusize; - /// let mut bits = Bit::from_usize(base); - /// bits.clear(); - /// assert_eq!(bits.as_usize(), 0x0); - /// ``` - pub fn clear(&mut self) { - self.0 = 0; - } } -/// UT test cases for mask new function -/// -/// # Brief -/// 1. pass in the parameters, and create the Mask. -/// 2. Check return value. -#[cfg(target_pointer_width = "32")] -#[test] -fn ut_mask_new_bit32() { - assert_eq!( - Mask::new(0, 0), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(0, 16), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(0, 32), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(0, 64), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(1, 0), - Mask { - mask: 0x1, - shift: 0 - } - ); - assert_eq!( - Mask::new(1, 16), - Mask { - mask: 0x1_0000, - shift: 16 - } - ); - assert_eq!( - Mask::new(1, 31), - Mask { - mask: 0x8000_0000, - shift: 31 - } - ); - assert_eq!( - Mask::new(1, 32), - Mask { - mask: 0x8000_0000, - shift: 31 - } - ); - assert_eq!( - Mask::new(1, 128), - Mask { - mask: 0x8000_0000, - shift: 31 - } - ); - assert_eq!( - Mask::new(4, 0), - Mask { - mask: 0xf, - shift: 0 - } - ); - assert_eq!( - Mask::new(4, 16), - Mask { - mask: 0xf_0000, - shift: 16 - } - ); - assert_eq!( - Mask::new(4, 28), - Mask { - mask: 0xf000_0000, - shift: 28 - } - ); - assert_eq!( - Mask::new(4, 32), - Mask { - mask: 0xf000_0000, - shift: 28 - } - ); - assert_eq!( - Mask::new(4, 64), - Mask { - mask: 0xf000_0000, - shift: 28 - } - ); - assert_eq!( - Mask::new(16, 0), - Mask { - mask: 0xffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(16, 16), - Mask { - mask: 0xffff_0000, - shift: 16 - } - ); - assert_eq!( - Mask::new(16, 32), - Mask { - mask: 0xffff_0000, - shift: 16 - } - ); - assert_eq!( - Mask::new(16, 64), - Mask { - mask: 0xffff_0000, - shift: 16 - } - ); - assert_eq!( - Mask::new(32, 0), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(32, 16), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(32, 32), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(32, 64), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 0), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 16), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 32), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 64), - Mask { - mask: 0xffff_ffff, - shift: 0 - } - ); -} - -/// UT test cases for mask new function -/// -/// # Brief -/// 1. pass in the parameters, and create the Mask. -/// 2. Check return value. -#[cfg(target_pointer_width = "64")] -#[test] -fn ut_mask_new_bit64() { - assert_eq!( - Mask::new(0, 0), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(0, 32), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(0, 64), - Mask { - mask: 0x0, - shift: 0 - } - ); - assert_eq!( - Mask::new(0, 128), - Mask { - mask: 0x0, - shift: 0 - } - ); - - assert_eq!( - Mask::new(1, 0), - Mask { - mask: 0x1, - shift: 0 - } - ); - assert_eq!( - Mask::new(1, 32), - Mask { - mask: 0x1_0000_0000, - shift: 32 +#[cfg(test)] +mod test { + use super::*; + impl Bit { + fn set(&mut self, val: usize) { + self.0 = val; } - ); - assert_eq!( - Mask::new(1, 63), - Mask { - mask: 0x8000_0000_0000_0000, - shift: 63 - } - ); - assert_eq!( - Mask::new(1, 64), - Mask { - mask: 0x8000_0000_0000_0000, - shift: 63 - } - ); - assert_eq!( - Mask::new(1, 128), - Mask { - mask: 0x8000_0000_0000_0000, - shift: 63 - } - ); - assert_eq!( - Mask::new(4, 0), - Mask { - mask: 0xf, - shift: 0 - } - ); - assert_eq!( - Mask::new(4, 32), - Mask { - mask: 0xf_0000_0000, - shift: 32 - } - ); - assert_eq!( - Mask::new(4, 60), - Mask { - mask: 0xf000_0000_0000_0000, - shift: 60 - } - ); - assert_eq!( - Mask::new(4, 64), - Mask { - mask: 0xf000_0000_0000_0000, - shift: 60 - } - ); - assert_eq!( - Mask::new(4, 128), - Mask { - mask: 0xf000_0000_0000_0000, - shift: 60 - } - ); - - assert_eq!( - Mask::new(32, 0), - Mask { - mask: 0xffff_ffff, - shift: 0 + fn clear(&mut self) { + self.0 = 0; } - ); - assert_eq!( - Mask::new(32, 32), - Mask { - mask: 0xffff_ffff_0000_0000, - shift: 32 - } - ); - assert_eq!( - Mask::new(32, 64), - Mask { - mask: 0xffff_ffff_0000_0000, - shift: 32 - } - ); - assert_eq!( - Mask::new(32, 128), - Mask { - mask: 0xffff_ffff_0000_0000, - shift: 32 - } - ); - - assert_eq!( - Mask::new(64, 0), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 32), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 64), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(64, 128), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); + } + /// UT test cases for mask new function + /// + /// # Brief + /// 1. pass in the parameters, and create the Mask. + /// 2. Check return value. + #[cfg(target_pointer_width = "32")] + #[test] + fn ut_mask_new_bit32() { + assert_eq!( + Mask::new(0, 0), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(0, 16), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(0, 32), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(0, 64), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(1, 0), + Mask { + mask: 0x1, + shift: 0 + } + ); + assert_eq!( + Mask::new(1, 16), + Mask { + mask: 0x1_0000, + shift: 16 + } + ); + assert_eq!( + Mask::new(1, 31), + Mask { + mask: 0x8000_0000, + shift: 31 + } + ); + assert_eq!( + Mask::new(1, 32), + Mask { + mask: 0x8000_0000, + shift: 31 + } + ); + assert_eq!( + Mask::new(1, 128), + Mask { + mask: 0x8000_0000, + shift: 31 + } + ); + assert_eq!( + Mask::new(4, 0), + Mask { + mask: 0xf, + shift: 0 + } + ); + assert_eq!( + Mask::new(4, 16), + Mask { + mask: 0xf_0000, + shift: 16 + } + ); + assert_eq!( + Mask::new(4, 28), + Mask { + mask: 0xf000_0000, + shift: 28 + } + ); + assert_eq!( + Mask::new(4, 32), + Mask { + mask: 0xf000_0000, + shift: 28 + } + ); + assert_eq!( + Mask::new(4, 64), + Mask { + mask: 0xf000_0000, + shift: 28 + } + ); + assert_eq!( + Mask::new(16, 0), + Mask { + mask: 0xffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(16, 16), + Mask { + mask: 0xffff_0000, + shift: 16 + } + ); + assert_eq!( + Mask::new(16, 32), + Mask { + mask: 0xffff_0000, + shift: 16 + } + ); + assert_eq!( + Mask::new(16, 64), + Mask { + mask: 0xffff_0000, + shift: 16 + } + ); + assert_eq!( + Mask::new(32, 0), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(32, 16), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(32, 32), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(32, 64), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 0), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 16), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 32), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 64), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + } - assert_eq!( - Mask::new(128, 0), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(128, 32), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(128, 64), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); - assert_eq!( - Mask::new(128, 128), - Mask { - mask: 0xffff_ffff_ffff_ffff, - shift: 0 - } - ); -} + /// UT test cases for mask new function + /// + /// # Brief + /// 1. pass in the parameters, and create the Mask. + /// 2. Check return value. + #[cfg(target_pointer_width = "64")] + #[test] + fn ut_mask_new_bit64() { + assert_eq!( + Mask::new(0, 0), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(0, 32), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(0, 64), + Mask { + mask: 0x0, + shift: 0 + } + ); + assert_eq!( + Mask::new(0, 128), + Mask { + mask: 0x0, + shift: 0 + } + ); + + assert_eq!( + Mask::new(1, 0), + Mask { + mask: 0x1, + shift: 0 + } + ); + assert_eq!( + Mask::new(1, 32), + Mask { + mask: 0x1_0000_0000, + shift: 32 + } + ); + assert_eq!( + Mask::new(1, 63), + Mask { + mask: 0x8000_0000_0000_0000, + shift: 63 + } + ); + assert_eq!( + Mask::new(1, 64), + Mask { + mask: 0x8000_0000_0000_0000, + shift: 63 + } + ); + assert_eq!( + Mask::new(1, 128), + Mask { + mask: 0x8000_0000_0000_0000, + shift: 63 + } + ); + + assert_eq!( + Mask::new(4, 0), + Mask { + mask: 0xf, + shift: 0 + } + ); + assert_eq!( + Mask::new(4, 32), + Mask { + mask: 0xf_0000_0000, + shift: 32 + } + ); + assert_eq!( + Mask::new(4, 60), + Mask { + mask: 0xf000_0000_0000_0000, + shift: 60 + } + ); + assert_eq!( + Mask::new(4, 64), + Mask { + mask: 0xf000_0000_0000_0000, + shift: 60 + } + ); + assert_eq!( + Mask::new(4, 128), + Mask { + mask: 0xf000_0000_0000_0000, + shift: 60 + } + ); + + assert_eq!( + Mask::new(32, 0), + Mask { + mask: 0xffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(32, 32), + Mask { + mask: 0xffff_ffff_0000_0000, + shift: 32 + } + ); + assert_eq!( + Mask::new(32, 64), + Mask { + mask: 0xffff_ffff_0000_0000, + shift: 32 + } + ); + assert_eq!( + Mask::new(32, 128), + Mask { + mask: 0xffff_ffff_0000_0000, + shift: 32 + } + ); + + assert_eq!( + Mask::new(64, 0), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 32), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 64), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(64, 128), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + + assert_eq!( + Mask::new(128, 0), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(128, 32), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(128, 64), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + assert_eq!( + Mask::new(128, 128), + Mask { + mask: 0xffff_ffff_ffff_ffff, + shift: 0 + } + ); + } -/// UT test cases for bit from_usize function -/// -/// # Brief -/// 1. Pass in any usize, call from_usize, and check the return value. -#[test] -fn ut_bit_from_usize() { - const USIZE_MAX: usize = 0usize.wrapping_sub(1); - const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; - - assert_eq!(Bit::from_usize(0), Bit(0)); - assert_eq!(Bit::from_usize(USIZE_MAX_HALF), Bit(USIZE_MAX_HALF)); - assert_eq!(Bit::from_usize(USIZE_MAX), Bit(USIZE_MAX)); -} + /// UT test cases for bit from_usize function + /// + /// # Brief + /// 1. Pass in any usize, call from_usize, and check the return value. + #[test] + fn ut_bit_from_usize() { + const USIZE_MAX: usize = 0usize.wrapping_sub(1); + const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; + + assert_eq!(Bit::from_usize(0), Bit(0)); + assert_eq!(Bit::from_usize(USIZE_MAX_HALF), Bit(USIZE_MAX_HALF)); + assert_eq!(Bit::from_usize(USIZE_MAX), Bit(USIZE_MAX)); + } -/// UT test cases for bit as_usize function -/// -/// # Brief -/// 1. Creating a Bit Instance. -/// 2. Call as_usize. -/// 3. Check return value. -#[test] -fn ut_bit_as_usize() { - const USIZE_MAX: usize = 0usize.wrapping_sub(1); - const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; - - assert_eq!(Bit::from_usize(0).as_usize(), 0); - assert_eq!(Bit::from_usize(USIZE_MAX_HALF).as_usize(), USIZE_MAX_HALF); - assert_eq!(Bit::from_usize(USIZE_MAX).as_usize(), USIZE_MAX); -} + /// UT test cases for bit as_usize function + /// + /// # Brief + /// 1. Creating a Bit Instance. + /// 2. Call as_usize. + /// 3. Check return value. + #[test] + fn ut_bit_as_usize() { + const USIZE_MAX: usize = 0usize.wrapping_sub(1); + const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; + + assert_eq!(Bit::from_usize(0).as_usize(), 0); + assert_eq!(Bit::from_usize(USIZE_MAX_HALF).as_usize(), USIZE_MAX_HALF); + assert_eq!(Bit::from_usize(USIZE_MAX).as_usize(), USIZE_MAX); + } -/// UT test cases for bit set function -/// -/// # Brief -/// 1. Creating a Bit Instance. -/// 2. Call the set function and pass in a new usize. -/// 3. Check return value. -#[test] -fn ut_bit_set() { - const USIZE_MAX: usize = 0usize.wrapping_sub(1); - const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; - - let mut b = Bit::from_usize(0); - b.set(0xf0f0); - assert_eq!(b.as_usize(), 0xf0f0); - - let mut b = Bit::from_usize(USIZE_MAX_HALF); - b.set(0xf0f0); - assert_eq!(b.as_usize(), 0xf0f0); - - let mut b = Bit::from_usize(USIZE_MAX); - b.set(0xf0f0); - assert_eq!(b.as_usize(), 0xf0f0); -} + /// UT test cases for bit set function + /// + /// # Brief + /// 1. Creating a Bit Instance. + /// 2. Call the set function and pass in a new usize. + /// 3. Check return value. + #[test] + fn ut_bit_set() { + const USIZE_MAX: usize = 0usize.wrapping_sub(1); + const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; + + let mut b = Bit::from_usize(0); + b.set(0xf0f0); + assert_eq!(b.as_usize(), 0xf0f0); + + let mut b = Bit::from_usize(USIZE_MAX_HALF); + b.set(0xf0f0); + assert_eq!(b.as_usize(), 0xf0f0); + + let mut b = Bit::from_usize(USIZE_MAX); + b.set(0xf0f0); + assert_eq!(b.as_usize(), 0xf0f0); + } -/// UT test cases for bit clear function -/// -/// # Brief -/// 1. Creating a Bit Instance. -/// 2. Call clear(). -/// 3. Calibrate the instance. -#[test] -fn ut_bit_clear() { - const USIZE_MAX: usize = 0usize.wrapping_sub(1); - const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; - - let mut b = Bit::from_usize(0); - b.clear(); - assert_eq!(b.as_usize(), 0); - - let mut b = Bit::from_usize(USIZE_MAX_HALF); - b.clear(); - assert_eq!(b.as_usize(), 0); - - let mut b = Bit::from_usize(USIZE_MAX); - b.clear(); - assert_eq!(b.as_usize(), 0); -} + /// UT test cases for bit clear function + /// + /// # Brief + /// 1. Creating a Bit Instance. + /// 2. Call clear(). + /// 3. Calibrate the instance. + #[test] + fn ut_bit_clear() { + const USIZE_MAX: usize = 0usize.wrapping_sub(1); + const USIZE_MAX_HALF: usize = 0usize.wrapping_sub(1) / 2; + + let mut b = Bit::from_usize(0); + b.clear(); + assert_eq!(b.as_usize(), 0); + + let mut b = Bit::from_usize(USIZE_MAX_HALF); + b.clear(); + assert_eq!(b.as_usize(), 0); + + let mut b = Bit::from_usize(USIZE_MAX); + b.clear(); + assert_eq!(b.as_usize(), 0); + } -/// UT test cases for bit set_by_mask function -/// -/// # Brief -/// 1. Create a Bit instance, create a Mask instance. -/// 2. Call set_by_mask(). -/// 3. Verify the Bit instance. -#[cfg(target_pointer_width = "32")] -#[test] -fn ut_bit_set_by_mask_bit32() { - let val = 0x0usize; - let mut bit = Bit::from_usize(val); - bit.set_by_mask(Mask::new(0, 0), 0x0); - assert_eq!(bit, Bit::from_usize(0x0)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 0), 0xf); - assert_eq!(bit, Bit::from_usize(0xf)); - - bit.clear(); - bit.set_by_mask(Mask::new(8, 0), 0xff); - assert_eq!(bit, Bit::from_usize(0xff)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 4), 0xf); - assert_eq!(bit, Bit::from_usize(0xf0)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 28), 0xf); - assert_eq!(bit, Bit::from_usize(0xf000_0000)); - - bit.clear(); - bit.set_by_mask(Mask::new(0, 0), 0xffff_ffff); - assert_eq!(bit, Bit::from_usize(0x0)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 0), 0xffff_ffff); - assert_eq!(bit, Bit::from_usize(0xf)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 4), 0xffff_ffff); - assert_eq!(bit, Bit::from_usize(0xf0)); - - let val = 0xffff_ffff; - let mut bit = Bit::from_usize(val); - bit.set_by_mask(Mask::new(0, 0), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_ffff)); - - bit.set(val); - bit.set_by_mask(Mask::new(4, 0), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_fff0)); - - bit.set(val); - bit.set_by_mask(Mask::new(4, 4), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_ff0f)); - - bit.set(val); - bit.set_by_mask(Mask::new(4, 8), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_f0ff)); - - bit.set(val); - bit.set_by_mask(Mask::new(4, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_fffd)); - - bit.set(val); - bit.set_by_mask(Mask::new(8, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_ffcd)); - - bit.set(val); - bit.set_by_mask(Mask::new(16, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_abcd)); - - bit.set(val); - bit.set_by_mask(Mask::new(16, 16), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xabcd_ffff)); - - bit.set(val); - bit.set_by_mask(Mask::new(32, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0x0000_abcd)); -} + /// UT test cases for bit set_by_mask function + /// + /// # Brief + /// 1. Create a Bit instance, create a Mask instance. + /// 2. Call set_by_mask(). + /// 3. Verify the Bit instance. + #[cfg(target_pointer_width = "32")] + #[test] + fn ut_bit_set_by_mask_bit32() { + let val = 0x0usize; + let mut bit = Bit::from_usize(val); + bit.set_by_mask(Mask::new(0, 0), 0x0); + assert_eq!(bit, Bit::from_usize(0x0)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 0), 0xf); + assert_eq!(bit, Bit::from_usize(0xf)); + + bit.clear(); + bit.set_by_mask(Mask::new(8, 0), 0xff); + assert_eq!(bit, Bit::from_usize(0xff)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 4), 0xf); + assert_eq!(bit, Bit::from_usize(0xf0)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 28), 0xf); + assert_eq!(bit, Bit::from_usize(0xf000_0000)); + + bit.clear(); + bit.set_by_mask(Mask::new(0, 0), 0xffff_ffff); + assert_eq!(bit, Bit::from_usize(0x0)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 0), 0xffff_ffff); + assert_eq!(bit, Bit::from_usize(0xf)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 4), 0xffff_ffff); + assert_eq!(bit, Bit::from_usize(0xf0)); + + let val = 0xffff_ffff; + let mut bit = Bit::from_usize(val); + bit.set_by_mask(Mask::new(0, 0), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_ffff)); + + bit.set(val); + bit.set_by_mask(Mask::new(4, 0), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_fff0)); + + bit.set(val); + bit.set_by_mask(Mask::new(4, 4), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_ff0f)); + + bit.set(val); + bit.set_by_mask(Mask::new(4, 8), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_f0ff)); + + bit.set(val); + bit.set_by_mask(Mask::new(4, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_fffd)); + + bit.set(val); + bit.set_by_mask(Mask::new(8, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_ffcd)); + + bit.set(val); + bit.set_by_mask(Mask::new(16, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_abcd)); + + bit.set(val); + bit.set_by_mask(Mask::new(16, 16), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xabcd_ffff)); + + bit.set(val); + bit.set_by_mask(Mask::new(32, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0x0000_abcd)); + } -/// UT test cases for bit set_by_mask function -/// -/// # Brief -/// 1. Create a Bit instance, create a Mask instance. -/// 2. Call set_by_mask(). -/// 3. Verify the Bit instance. -#[cfg(target_pointer_width = "64")] -#[test] -fn ut_bit_set_by_mask_bit64() { - let val = 0x0usize; - let mut bit = Bit::from_usize(val); - bit.set_by_mask(Mask::new(0, 0), 0x0); - assert_eq!(bit, Bit::from_usize(0x0)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 0), 0xf); - assert_eq!(bit, Bit::from_usize(0xf)); - - bit.clear(); - bit.set_by_mask(Mask::new(8, 0), 0xff); - assert_eq!(bit, Bit::from_usize(0xff)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 4), 0xf); - assert_eq!(bit, Bit::from_usize(0xf0)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 32), 0xf); - assert_eq!(bit, Bit::from_usize(0xf_0000_0000)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 0), 0xffff_ffff_ffff_ffff); - assert_eq!(bit, Bit::from_usize(0xf)); - - bit.clear(); - bit.set_by_mask(Mask::new(4, 4), 0xffff_ffff_ffff_ffff); - assert_eq!(bit, Bit::from_usize(0xf0)); - - bit.clear(); - bit.set_by_mask(Mask::new(0, 0), 0xffff_ffff_ffff_ffff); - assert_eq!(bit, Bit::from_usize(0)); - - let val = 0xffff_ffff_ffff_ffffusize; - let mut bit = Bit::from_usize(val); - bit.set_by_mask(Mask::new(0, 0), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_ffff)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(4, 0), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_fff0)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(4, 4), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_ff0f)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(4, 32), 0x0); - assert_eq!(bit, Bit::from_usize(0xffff_fff0_ffff_ffff)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(4, 60), 0x0); - assert_eq!(bit, Bit::from_usize(0x0fff_ffff_ffff_ffff)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(16, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_abcd)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(32, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_0000_abcd)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(12, 0), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_fbcd)); - - bit.set(0xffff_ffff_ffff_ffff); - bit.set_by_mask(Mask::new(16, 8), 0xabcd); - assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffab_cdff)); -} + /// UT test cases for bit set_by_mask function + /// + /// # Brief + /// 1. Create a Bit instance, create a Mask instance. + /// 2. Call set_by_mask(). + /// 3. Verify the Bit instance. + #[cfg(target_pointer_width = "64")] + #[test] + fn ut_bit_set_by_mask_bit64() { + let val = 0x0usize; + let mut bit = Bit::from_usize(val); + bit.set_by_mask(Mask::new(0, 0), 0x0); + assert_eq!(bit, Bit::from_usize(0x0)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 0), 0xf); + assert_eq!(bit, Bit::from_usize(0xf)); + + bit.clear(); + bit.set_by_mask(Mask::new(8, 0), 0xff); + assert_eq!(bit, Bit::from_usize(0xff)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 4), 0xf); + assert_eq!(bit, Bit::from_usize(0xf0)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 32), 0xf); + assert_eq!(bit, Bit::from_usize(0xf_0000_0000)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 0), 0xffff_ffff_ffff_ffff); + assert_eq!(bit, Bit::from_usize(0xf)); + + bit.clear(); + bit.set_by_mask(Mask::new(4, 4), 0xffff_ffff_ffff_ffff); + assert_eq!(bit, Bit::from_usize(0xf0)); + + bit.clear(); + bit.set_by_mask(Mask::new(0, 0), 0xffff_ffff_ffff_ffff); + assert_eq!(bit, Bit::from_usize(0)); + + let val = 0xffff_ffff_ffff_ffffusize; + let mut bit = Bit::from_usize(val); + bit.set_by_mask(Mask::new(0, 0), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_ffff)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(4, 0), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_fff0)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(4, 4), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_ff0f)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(4, 32), 0x0); + assert_eq!(bit, Bit::from_usize(0xffff_fff0_ffff_ffff)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(4, 60), 0x0); + assert_eq!(bit, Bit::from_usize(0x0fff_ffff_ffff_ffff)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(16, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_abcd)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(32, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_0000_abcd)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(12, 0), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffff_fbcd)); + + bit.set(0xffff_ffff_ffff_ffff); + bit.set_by_mask(Mask::new(16, 8), 0xabcd); + assert_eq!(bit, Bit::from_usize(0xffff_ffff_ffab_cdff)); + } -/// UT test cases for bit get_by_mask function -/// -/// # Brief -/// 1. Create a Bit instance, create a Mask instance. -/// 2. Call get_by_mask(). -/// 3. Check return value. -#[cfg(target_pointer_width = "32")] -#[test] -fn ut_bit_get_by_mask_bit32() { - let val = 0x0usize; - let bit = Bit::from_usize(val); - assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(16, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x0); - - let val = 0xffff_ffffusize; - let bit = Bit::from_usize(val); - assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x1); - assert_eq!(bit.get_by_mask(Mask::new(16, 0)), 0xffff); - assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0xffff_ffff); - - let val = 0x1234_cdefusize; - let bit = Bit::from_usize(val); - assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(4, 0)), 0xf); - assert_eq!(bit.get_by_mask(Mask::new(8, 0)), 0xef); - assert_eq!(bit.get_by_mask(Mask::new(12, 0)), 0xdef); - assert_eq!(bit.get_by_mask(Mask::new(16, 0)), 0xcdef); - assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x1234_cdef); - assert_eq!(bit.get_by_mask(Mask::new(4, 4)), 0xe); - assert_eq!(bit.get_by_mask(Mask::new(8, 4)), 0xde); - assert_eq!(bit.get_by_mask(Mask::new(12, 4)), 0xcde); - assert_eq!(bit.get_by_mask(Mask::new(4, 16)), 0x4); - assert_eq!(bit.get_by_mask(Mask::new(8, 16)), 0x34); - assert_eq!(bit.get_by_mask(Mask::new(12, 16)), 0x234); - assert_eq!(bit.get_by_mask(Mask::new(3, 0)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(3, 4)), 0x6); - assert_eq!(bit.get_by_mask(Mask::new(3, 8)), 0x5); - assert_eq!(bit.get_by_mask(Mask::new(3, 16)), 0x4); - assert_eq!(bit.get_by_mask(Mask::new(3, 20)), 0x3); - assert_eq!(bit.get_by_mask(Mask::new(3, 24)), 0x2); - assert_eq!(bit.get_by_mask(Mask::new(3, 1)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(3, 5)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(3, 9)), 0x6); -} + /// UT test cases for bit get_by_mask function + /// + /// # Brief + /// 1. Create a Bit instance, create a Mask instance. + /// 2. Call get_by_mask(). + /// 3. Check return value. + #[cfg(target_pointer_width = "32")] + #[test] + fn ut_bit_get_by_mask_bit32() { + let val = 0x0usize; + let bit = Bit::from_usize(val); + assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(16, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x0); + + let val = 0xffff_ffffusize; + let bit = Bit::from_usize(val); + assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x1); + assert_eq!(bit.get_by_mask(Mask::new(16, 0)), 0xffff); + assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0xffff_ffff); + + let val = 0x1234_cdefusize; + let bit = Bit::from_usize(val); + assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(4, 0)), 0xf); + assert_eq!(bit.get_by_mask(Mask::new(8, 0)), 0xef); + assert_eq!(bit.get_by_mask(Mask::new(12, 0)), 0xdef); + assert_eq!(bit.get_by_mask(Mask::new(16, 0)), 0xcdef); + assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x1234_cdef); + assert_eq!(bit.get_by_mask(Mask::new(4, 4)), 0xe); + assert_eq!(bit.get_by_mask(Mask::new(8, 4)), 0xde); + assert_eq!(bit.get_by_mask(Mask::new(12, 4)), 0xcde); + assert_eq!(bit.get_by_mask(Mask::new(4, 16)), 0x4); + assert_eq!(bit.get_by_mask(Mask::new(8, 16)), 0x34); + assert_eq!(bit.get_by_mask(Mask::new(12, 16)), 0x234); + assert_eq!(bit.get_by_mask(Mask::new(3, 0)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(3, 4)), 0x6); + assert_eq!(bit.get_by_mask(Mask::new(3, 8)), 0x5); + assert_eq!(bit.get_by_mask(Mask::new(3, 16)), 0x4); + assert_eq!(bit.get_by_mask(Mask::new(3, 20)), 0x3); + assert_eq!(bit.get_by_mask(Mask::new(3, 24)), 0x2); + assert_eq!(bit.get_by_mask(Mask::new(3, 1)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(3, 5)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(3, 9)), 0x6); + } -/// UT test cases for bit get_by_mask function -/// -/// # Brief -/// 1. Create a Bit instance, create a Mask instance. -/// 2. Call get_by_mask(). -/// 3. Check return value. -#[cfg(target_pointer_width = "64")] -#[test] -fn ut_bit_get_by_mask_bit64() { - let val = 0x0usize; - let bit = Bit::from_usize(val); - assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(64, 0)), 0x0); - - let val = 0xffff_ffff_ffff_ffffusize; - let bit = Bit::from_usize(val); - assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x1); - assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0xffff_ffff); - assert_eq!(bit.get_by_mask(Mask::new(64, 0)), 0xffff_ffff_ffff_ffff); - - let val = 0x0123_4567_89ab_cdefusize; - let bit = Bit::from_usize(val); - assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); - assert_eq!(bit.get_by_mask(Mask::new(4, 0)), 0xf); - assert_eq!(bit.get_by_mask(Mask::new(8, 0)), 0xef); - assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x89ab_cdef); - assert_eq!(bit.get_by_mask(Mask::new(64, 0)), 0x0123_4567_89ab_cdef); - assert_eq!(bit.get_by_mask(Mask::new(4, 4)), 0xe); - assert_eq!(bit.get_by_mask(Mask::new(8, 4)), 0xde); - assert_eq!(bit.get_by_mask(Mask::new(12, 4)), 0xcde); - assert_eq!(bit.get_by_mask(Mask::new(60, 4)), 0x0012_3456_789a_bcde); - assert_eq!(bit.get_by_mask(Mask::new(4, 32)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(8, 32)), 0x67); - assert_eq!(bit.get_by_mask(Mask::new(12, 32)), 0x567); - assert_eq!(bit.get_by_mask(Mask::new(3, 0)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(3, 4)), 0x6); - assert_eq!(bit.get_by_mask(Mask::new(3, 8)), 0x5); - assert_eq!(bit.get_by_mask(Mask::new(3, 1)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(3, 5)), 0x7); - assert_eq!(bit.get_by_mask(Mask::new(3, 9)), 0x6); + /// UT test cases for bit get_by_mask function + /// + /// # Brief + /// 1. Create a Bit instance, create a Mask instance. + /// 2. Call get_by_mask(). + /// 3. Check return value. + #[cfg(target_pointer_width = "64")] + #[test] + fn ut_bit_get_by_mask_bit64() { + let val = 0x0usize; + let bit = Bit::from_usize(val); + assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(64, 0)), 0x0); + + let val = 0xffff_ffff_ffff_ffffusize; + let bit = Bit::from_usize(val); + assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(1, 0)), 0x1); + assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0xffff_ffff); + assert_eq!(bit.get_by_mask(Mask::new(64, 0)), 0xffff_ffff_ffff_ffff); + + let val = 0x0123_4567_89ab_cdefusize; + let bit = Bit::from_usize(val); + assert_eq!(bit.get_by_mask(Mask::new(0, 0)), 0x0); + assert_eq!(bit.get_by_mask(Mask::new(4, 0)), 0xf); + assert_eq!(bit.get_by_mask(Mask::new(8, 0)), 0xef); + assert_eq!(bit.get_by_mask(Mask::new(32, 0)), 0x89ab_cdef); + assert_eq!(bit.get_by_mask(Mask::new(64, 0)), 0x0123_4567_89ab_cdef); + assert_eq!(bit.get_by_mask(Mask::new(4, 4)), 0xe); + assert_eq!(bit.get_by_mask(Mask::new(8, 4)), 0xde); + assert_eq!(bit.get_by_mask(Mask::new(12, 4)), 0xcde); + assert_eq!(bit.get_by_mask(Mask::new(60, 4)), 0x0012_3456_789a_bcde); + assert_eq!(bit.get_by_mask(Mask::new(4, 32)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(8, 32)), 0x67); + assert_eq!(bit.get_by_mask(Mask::new(12, 32)), 0x567); + assert_eq!(bit.get_by_mask(Mask::new(3, 0)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(3, 4)), 0x6); + assert_eq!(bit.get_by_mask(Mask::new(3, 8)), 0x5); + assert_eq!(bit.get_by_mask(Mask::new(3, 1)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(3, 5)), 0x7); + assert_eq!(bit.get_by_mask(Mask::new(3, 9)), 0x6); + } } diff --git a/ylong_runtime/src/util/core_affinity/linux.rs b/ylong_runtime/src/util/core_affinity/linux.rs index 2f703ab..6061d81 100644 --- a/ylong_runtime/src/util/core_affinity/linux.rs +++ b/ylong_runtime/src/util/core_affinity/linux.rs @@ -16,9 +16,7 @@ use std::io::{Error, Result}; use std::mem::{size_of, zeroed}; -use libc::{cpu_set_t, sched_getaffinity, sched_setaffinity, CPU_ISSET, CPU_SET}; - -use crate::util::num_cpus::get_cpu_num; +use libc::{cpu_set_t, sched_setaffinity, CPU_SET}; /// Sets the tied core cpu of the current thread. /// @@ -42,77 +40,7 @@ pub fn set_current_affinity(cpu: usize) -> Result<()> { } } -/// Gets the cores tied to the current thread, -/// or returns all available cpu's if no cores have been tied. -/// -/// sched_setaffinity function under linux -/// # Example 1 -/// -/// ```rust -/// use ylong_runtime::util::core_affinity; -/// -/// let cpus: Vec = core_affinity::get_current_affinity(); -/// assert!(cpus.len() > 0); -/// ``` -/// # Example 2 -/// -/// ```rust -/// use ylong_runtime::util::core_affinity; -/// -/// let ret = core_affinity::set_current_affinity(0).is_ok(); -/// assert!(ret); -/// let cpus: Vec = core_affinity::get_current_affinity(); -/// assert_eq!(cpus.len(), 1); -/// ``` -pub fn get_current_affinity() -> Vec { - unsafe { - let mut vec = vec![]; - let cpus = get_cpu_num() as usize; - let mut set = new_cpu_set(); - sched_getaffinity(0, size_of::(), &mut set); - for i in 0..cpus { - if CPU_ISSET(i, &set) { - vec.push(i); - } - } - vec - } -} - -/// Gets the cores bound to the specified thread, or return all available cpu's -/// if no cores are bound -/// -/// sched_setaffinity function under linux -pub fn get_other_thread_affinity(pid: i32) -> Vec { - unsafe { - let mut vec = vec![]; - let cpus = get_cpu_num() as usize; - let mut set = new_cpu_set(); - sched_getaffinity(pid, size_of::(), &mut set); - for i in 0..cpus { - if CPU_ISSET(i, &set) { - vec.push(i); - } - } - vec - } -} - /// Returns an empty cpu set fn new_cpu_set() -> cpu_set_t { unsafe { zeroed::() } } - -#[cfg(test)] -mod test { - /// UT test cases for get_other_thread_affinity usage - /// - /// # Brief - /// 1. Uses get_other_thread_affinity() to get thread affinity. - /// 2. Returns all available cpu's because no cores are bound. - #[test] - fn ut_core_affinity_other_thread() { - let cpus: Vec = crate::util::core_affinity::get_other_thread_affinity(0); - assert!(!cpus.is_empty()); - } -} diff --git a/ylong_runtime/src/util/core_affinity/mod.rs b/ylong_runtime/src/util/core_affinity/mod.rs index 8ad365e..3d45cfd 100644 --- a/ylong_runtime/src/util/core_affinity/mod.rs +++ b/ylong_runtime/src/util/core_affinity/mod.rs @@ -20,5 +20,6 @@ pub use linux::*; #[cfg(target_os = "windows")] pub mod windows; + #[cfg(target_os = "windows")] pub use windows::*; diff --git a/ylong_runtime/src/util/num_cpus/linux.rs b/ylong_runtime/src/util/num_cpus/linux.rs index dd61065..2ff7121 100644 --- a/ylong_runtime/src/util/num_cpus/linux.rs +++ b/ylong_runtime/src/util/num_cpus/linux.rs @@ -15,7 +15,7 @@ use std::os::raw::c_long; -use libc::{sysconf, _SC_NPROCESSORS_CONF, _SC_NPROCESSORS_ONLN}; +use libc::{sysconf, _SC_NPROCESSORS_ONLN}; /// Gets the number of CPU cores via linux syscall /// @@ -30,18 +30,3 @@ use libc::{sysconf, _SC_NPROCESSORS_CONF, _SC_NPROCESSORS_ONLN}; pub fn get_cpu_num_online() -> c_long { unsafe { sysconf(_SC_NPROCESSORS_ONLN) } } - -/// Gets the number of CPU cores via linux syscall, including disabled cpu -/// states -/// -/// # Example 2 -/// -/// ```rust -/// use ylong_runtime::util::num_cpus; -/// -/// #[cfg(target_os = "linux")] -/// let cpus = num_cpus::linux::get_cpu_num_configured(); -/// ``` -pub fn get_cpu_num_configured() -> c_long { - unsafe { sysconf(_SC_NPROCESSORS_CONF) } -} diff --git a/ylong_runtime/src/util/num_cpus/mod.rs b/ylong_runtime/src/util/num_cpus/mod.rs index fa82caa..1eb916f 100644 --- a/ylong_runtime/src/util/num_cpus/mod.rs +++ b/ylong_runtime/src/util/num_cpus/mod.rs @@ -42,3 +42,9 @@ use crate::util::num_cpus::windows::get_cpu_num_online; pub fn get_cpu_num() -> c_long { get_cpu_num_online() } + +#[test] +fn ut_num_cpus_test() { + let cpus = get_cpu_num(); + assert!(cpus > 0); +} diff --git a/ylong_runtime/src/util/slab.rs b/ylong_runtime/src/util/slab.rs index a1562a9..e0967c4 100644 --- a/ylong_runtime/src/util/slab.rs +++ b/ylong_runtime/src/util/slab.rs @@ -464,9 +464,30 @@ impl Value { mod test { use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; + use std::sync::{Arc, Mutex}; + use std::thread; - use crate::util::slab::{Address, Entry, Slab, NUM_PAGES, PAGE_INITIAL_SIZE}; + use super::*; + struct TestEntry { + cnt: AtomicUsize, + id: AtomicUsize, + } + + impl Default for TestEntry { + fn default() -> TestEntry { + TestEntry { + cnt: AtomicUsize::new(0), + id: AtomicUsize::new(0), + } + } + } + + impl Entry for TestEntry { + fn reset(&self) { + self.cnt.fetch_add(1, SeqCst); + } + } struct Foo { cnt: AtomicUsize, id: AtomicUsize, @@ -593,4 +614,254 @@ mod test { assert!(!slab.pages[1].allocated.load(SeqCst)); } } + + /// SDV test cases for Slab + /// + /// # Brief + /// 1. Inserting large amounts of data into a container. + /// 2. Make changes to these inserted data. + /// 3. Modified data by address verification. + /// 4. Multiplexing mechanism after calibration is released. + #[test] + fn sdv_slab_insert_move() { + let mut slab = Slab::::new(); + let alloc = slab.handle(); + + unsafe { + // Find the first available `slot` and return its `addr` and `Ref` + let (addr1, test_entry1) = alloc.allocate().unwrap(); + // Modify the current `id` + slab.get(addr1).unwrap().id.store(1, SeqCst); + // The `reset` function has not been called yet, so `cnt` remains unchanged + assert_eq!(0, slab.get(addr1).unwrap().cnt.load(SeqCst)); + + // Find the second available `slot` and return its `addr` and `Ref` + let (addr2, test_entry2) = alloc.allocate().unwrap(); + slab.get(addr2).unwrap().id.store(2, SeqCst); + assert_eq!(0, slab.get(addr2).unwrap().cnt.load(SeqCst)); + + // This verifies that the function of finding data based on `addr` is working + assert_eq!(1, slab.get(addr1).unwrap().id.load(SeqCst)); + assert_eq!(2, slab.get(addr2).unwrap().id.load(SeqCst)); + + // Active destruct, the `slot` will be reused + drop(test_entry1); + + assert_eq!(1, slab.get(addr1).unwrap().id.load(SeqCst)); + + // Allocate again, but then the allocated `slot` should use the previously + // destructured `slot` + let (addr3, test_entry3) = alloc.allocate().unwrap(); + // Comparison, equal is successful + assert_eq!(addr3, addr1); + assert_eq!(1, slab.get(addr3).unwrap().cnt.load(SeqCst)); + slab.get(addr3).unwrap().id.store(3, SeqCst); + assert_eq!(3, slab.get(addr3).unwrap().id.load(SeqCst)); + + drop(test_entry2); + drop(test_entry3); + + // Cleaned regularly, but the first `page` is never cleaned + slab.compact(); + assert!(slab.get(addr1).is_some()); + assert!(slab.get(addr2).is_some()); + assert!(slab.get(addr3).is_some()); + } + } + + /// SDV test cases for Slab + /// + /// # Brief + /// 1. Inserting large amounts of data into a container + /// 2. Verify by address that the data is in the correct location + #[test] + fn sdv_slab_insert_many() { + unsafe { + // Verify that `page` is being allocated properly in the case of a large number + // of inserts. + let mut slab = Slab::::new(); + let alloc = slab.handle(); + let mut entries = vec![]; + + for i in 0..10_000 { + let (addr, val) = alloc.allocate().unwrap(); + val.id.store(i, SeqCst); + entries.push((addr, val)); + } + + for (i, (addr, v)) in entries.iter().enumerate() { + assert_eq!(i, v.id.load(SeqCst)); + assert_eq!(i, slab.get(*addr).unwrap().id.load(SeqCst)); + } + + entries.clear(); + + for i in 0..10_000 { + let (addr, val) = alloc.allocate().unwrap(); + val.id.store(10_000 - i, SeqCst); + entries.push((addr, val)); + } + + for (i, (addr, v)) in entries.iter().enumerate() { + assert_eq!(10_000 - i, v.id.load(SeqCst)); + assert_eq!(10_000 - i, slab.get(*addr).unwrap().id.load(SeqCst)); + } + } + } + + /// SDV test cases for Slab + /// + /// # Brief + /// 1. Inserting large amounts of data into a container + /// 2. Verify by address that the data is in the correct location + #[test] + fn sdv_slab_insert_drop_reverse() { + unsafe { + let mut slab = Slab::::new(); + let alloc = slab.handle(); + let mut entries = vec![]; + + for i in 0..10_000 { + let (addr, val) = alloc.allocate().unwrap(); + val.id.store(i, SeqCst); + entries.push((addr, val)); + } + + for _ in 0..10 { + for _ in 0..1_000 { + entries.pop(); + } + + for (i, (addr, v)) in entries.iter().enumerate() { + assert_eq!(i, v.id.load(SeqCst)); + assert_eq!(i, slab.get(*addr).unwrap().id.load(SeqCst)); + } + } + } + } + + /// SDV test cases for Slab + /// + /// # Brief + /// 1. Multi-threaded allocation of container space, inserting data into it, + /// and verifying that the function is correct + #[test] + fn sdv_slab_multi_allocate() { + // Multi-threaded either allocating space, or modifying values. + // finally comparing the values given by the acquired address to be equal. + let mut slab = Slab::::new(); + let thread_one_alloc = slab.handle(); + let thread_two_alloc = slab.handle(); + let thread_three_alloc = slab.handle(); + + let capacity = 3001; + let free_queue = Arc::new(Mutex::new(Vec::with_capacity(capacity))); + let free_queue_2 = free_queue.clone(); + let free_queue_3 = free_queue.clone(); + let free_queue_4 = free_queue.clone(); + + unsafe { + let thread_one = thread::spawn(move || { + for i in 0..10_00 { + let (addr, test_entry) = thread_one_alloc.allocate().unwrap(); + test_entry.id.store(i, SeqCst); + free_queue.lock().unwrap().push((addr, test_entry, i)); + } + }); + + let thread_two = thread::spawn(move || { + for i in 10_00..20_00 { + let (addr, test_entry) = thread_two_alloc.allocate().unwrap(); + test_entry.id.store(i, SeqCst); + free_queue_2.lock().unwrap().push((addr, test_entry, i)); + } + }); + + let thread_three = thread::spawn(move || { + for i in 20_00..30_00 { + let (addr, test_entry) = thread_three_alloc.allocate().unwrap(); + test_entry.id.store(i, SeqCst); + free_queue_3.lock().unwrap().push((addr, test_entry, i)); + } + }); + + thread_one + .join() + .expect("Couldn't join on the associated thread"); + thread_two + .join() + .expect("Couldn't join on the associated thread"); + thread_three + .join() + .expect("Couldn't join on the associated thread"); + } + + for _ in 0..30_00 { + let temp = free_queue_4.clone().lock().unwrap().pop().unwrap(); + assert_eq!(slab.get(temp.0).unwrap().id.load(SeqCst), temp.2); + } + } + + /// SDV test cases for Slab + /// + /// # Brief + /// 1. Multi-threaded allocation of container space, inserting data into it, + /// and verifying that the function is correct + /// 2. Free up some of the data space and check if the data is reused in the + /// multi-threaded case + #[test] + fn sdv_slab_multi_allocate_drop() { + // allocate space and free the used `slot` in the multi-threaded case. + // retaining the address of the freed `slot` and allocating it again. + // the address after reallocation is the same as the address of the previously + // freed `slot`. + let slab = Slab::::new(); + let thread_one_alloc = slab.handle(); + let thread_two_alloc = slab.handle(); + + let capacity = 2001; + let free_queue_one = Arc::new(Mutex::new(Vec::with_capacity(capacity))); + let free_queue_one_2 = free_queue_one.clone(); + + let free_queue_two = Arc::new(Mutex::new(Vec::with_capacity(capacity))); + let free_queue_two_2 = free_queue_two.clone(); + + unsafe { + let thread_one = thread::spawn(move || { + for i in 0..1000 { + let (addr, test_entry) = thread_one_alloc.allocate().unwrap(); + test_entry.id.store(i, SeqCst); + drop(test_entry); + + free_queue_one.lock().unwrap().push(addr); + } + }); + + thread_one + .join() + .expect("Couldn't join on the associated thread"); + + let thread_two = thread::spawn(move || { + thread::park(); + for i in 0..1000 { + let (addr, test_entry) = thread_two_alloc.allocate().unwrap(); + test_entry.id.store(i, SeqCst); + + free_queue_two.lock().unwrap().push(addr); + } + }); + + thread_two.thread().unpark(); + thread_two + .join() + .expect("Couldn't join on the associated thread"); + + for _ in 0..1000 { + assert_eq!( + free_queue_one_2.clone().lock().unwrap().pop().unwrap(), + free_queue_two_2.lock().unwrap().pop().unwrap() + ); + } + } + } } diff --git a/ylong_runtime/src/util/slots.rs b/ylong_runtime/src/util/slots.rs index f60c276..edf54a8 100644 --- a/ylong_runtime/src/util/slots.rs +++ b/ylong_runtime/src/util/slots.rs @@ -22,7 +22,6 @@ use std::{fmt, ops}; // isize::MAX bytes. const NULL: usize = usize::MAX; -#[derive(Debug, Eq, PartialEq)] struct Entry { data: Option, prev: usize, @@ -47,17 +46,16 @@ pub struct SlotsIter<'a, T: 'a> { } /// An entry for the slots. -#[derive(Eq, PartialEq)] pub struct Slots { entries: Vec>, - len: usize, + pub len: usize, head: usize, tail: usize, next: usize, } /// The index of slot to remove is invalid. -#[derive(Debug, Eq, PartialEq, Clone)] +#[derive(Debug, Eq, PartialEq)] pub struct SlotsError; impl Display for SlotsError { @@ -69,84 +67,10 @@ impl Display for SlotsError { impl Error for SlotsError {} impl Slots { - /// Construct a new 'Slots' container with initial values of 0. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let slots: Slots = Slots::new(); - /// ``` pub fn new() -> Slots { Slots::with_capacity(0) } - /// Returns the current number of elements in the container. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// for i in 0..3 { - /// slots.push_back(i); - /// } - /// assert_eq!(3, slots.len()); - /// ``` - pub fn len(&self) -> usize { - self.len - } - - /// Empty the container. - /// - /// # Examples - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// for i in 0..3 { - /// slots.push_back(i); - /// } - /// slots.clear(); - /// assert_eq!(slots.len(), 0); - /// ``` - pub fn clear(&mut self) { - self.entries.clear(); - self.len = 0; - self.head = NULL; - self.tail = NULL; - self.next = 0; - } - - /// Insert an element to the end of the list of container. - /// - /// Two situations: - /// - /// 1. The next slot is exactly the next position of the array. Insert the - /// data into the vector, increase the length, and calculate the next - /// insertion position. - /// 2. The next slot is the recycled slot. Update the index of `next` and - /// then insert the data. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// let zero = slots.push_back("zero"); - /// let one = slots.push_back("one"); - /// assert_eq!(zero, 0); - /// assert_eq!(one, 1); - /// - /// let temp = slots.remove(zero); - /// assert_eq!(temp, Ok("zero")); - /// - /// let two = slots.push_back("two"); - /// assert_eq!(two, zero); - /// ``` pub fn push_back(&mut self, val: T) -> usize { let key = self.next; let tail = self.tail; @@ -179,19 +103,6 @@ impl Slots { key } - /// Pop item from the container head. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// let zero = slots.push_back("zero"); - /// - /// assert_eq!(slots.pop_front(), Some("zero")); - /// assert!(!slots.contains(zero)); - /// ``` pub fn pop_front(&mut self) -> Option { let curr = self.head; if let Some(entry) = self.entries.get_mut(curr) { @@ -216,19 +127,6 @@ impl Slots { None } - /// Delete an element in container. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// let zero = slots.push_back("zero"); - /// - /// assert_eq!(slots.remove(zero), Ok("zero")); - /// assert!(!slots.contains(zero)); - /// ``` pub fn remove(&mut self, key: usize) -> Result { if let Some(entry) = self.entries.get_mut(key) { if let Some(val) = entry.data.take() { @@ -266,127 +164,10 @@ impl Slots { Err(SlotsError) } - /// Get the reference of the element in the container according to the - /// index. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// let key = slots.push_back("key"); - /// - /// assert_eq!(slots.get(key), Some(&"key")); - /// assert_eq!(slots.get(123), None); - /// ``` - pub fn get(&self, key: usize) -> Option<&T> { - match self.entries.get(key) { - Some(entry) => match entry.data.as_ref() { - Some(val) => Some(val), - None => None, - }, - None => None, - } - } - - /// Get the mutable reference of the element in the container according to - /// the index. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// let key = slots.push_back("key"); - /// - /// *slots.get_mut(key).unwrap() = "change_key"; - /// assert_eq!(*slots.get(key).unwrap(), "change_key"); - /// assert_eq!(slots.get(123), None); - /// ``` - pub fn get_mut(&mut self, key: usize) -> Option<&mut T> { - match self.entries.get_mut(key) { - Some(entry) => match entry.data.as_mut() { - Some(val) => Some(val), - None => None, - }, - None => None, - } - } - - /// Check whether the index is valid and whether there is an element at the - /// index in the container. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// let key = slots.push_back("key"); - /// - /// assert!(slots.contains(key)); - /// assert!(!slots.contains(123)); - /// ``` - pub fn contains(&self, key: usize) -> bool { - match self.entries.get(key) { - Some(entry) => entry.data.is_some(), - None => false, - } - } - - /// Create an immutable iterator for the container to poll all elements int - /// the order of insertion. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// for i in 0..3 { - /// slots.push_back(i); - /// } - /// - /// for (key, element) in slots.iter() { - /// assert_eq!(slots.get(key).unwrap(), element); - /// } - /// ``` - pub fn iter(&self) -> SlotsIter { - SlotsIter { - entries: &self.entries, - len: self.len, - head: self.head, - } - } - - /// Check whether the container is empty. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots = Slots::new(); - /// assert!(slots.is_empty()); - /// - /// slots.push_back(1); - /// assert!(!slots.is_empty()); - /// ``` pub fn is_empty(&self) -> bool { self.len == 0 } - /// Construct a new 'Slots' container with a capacity. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let slots: Slots = Slots::with_capacity(0); - /// ``` pub fn with_capacity(capacity: usize) -> Slots { Slots { entries: Vec::with_capacity(capacity), @@ -396,20 +177,6 @@ impl Slots { len: 0, } } - - /// Get the capacity of the container. - /// - /// # Examples - /// - /// ``` - /// use ylong_runtime::util::slots::Slots; - /// - /// let mut slots: Slots = Slots::new(); - /// assert_eq!(slots.capacity(), 0); - /// ``` - pub fn capacity(&self) -> usize { - self.entries.capacity() - } } impl Default for Slots { @@ -483,7 +250,17 @@ impl<'a, T> Iterator for SlotsIter<'a, T> { #[cfg(test)] mod test { use crate::util::slots::Slots; - + impl Slots { + fn get(&self, key: usize) -> Option<&T> { + match self.entries.get(key) { + Some(entry) => match entry.data.as_ref() { + Some(val) => Some(val), + None => None, + }, + None => None, + } + } + } #[derive(Debug, Eq, PartialEq)] struct Data { inner: i32, @@ -495,63 +272,6 @@ mod test { } } - /// UT test cases for Slots::new(). - /// - /// # Brief - /// 1. Verify the parameters after initialization, which should be - /// consistent with the initial value. - #[test] - fn ut_slots_new() { - let slots: Slots = Slots::new(); - assert_eq!(slots.len, 0); - assert_eq!(slots.next, 0); - assert_eq!(slots.entries, Vec::with_capacity(0)); - } - - /// UT test cases for Slots::with_capacity(). - /// - /// # Brief - /// 1. Verify the parameters after initialization, which should be - /// consistent with the initial value. - #[test] - fn ut_slots_with_capacity() { - let slots_new: Slots = Slots::new(); - let slots_with_capacity: Slots = Slots::with_capacity(0); - assert_eq!(slots_new, slots_with_capacity); - } - - /// UT test cases for Slots::len(). - /// - /// # Brief - /// 1. Inserting a certain number of data into the container. - #[test] - fn ut_slots_len() { - let mut slots = Slots::new(); - assert_eq!(slots.len(), 0_usize); - - for i in 0..1000 { - slots.push_back(i); - } - assert_eq!(slots.len(), 1000); - } - - /// UT test cases for Slots::clear(). - /// - /// # Brief - /// 1. Empty the container to make it exactly the same as the initialized - /// container. - #[test] - fn ut_slots_clear() { - let mut slots = Slots::new(); - for i in 0..1000 { - slots.push_back(i); - } - assert_ne!(slots, Slots::new()); - - slots.clear(); - assert_eq!(slots, Slots::new()); - } - /// UT test cases for Slots::insert(). /// /// # Brief @@ -628,7 +348,7 @@ mod test { assert_eq!(slots.pop_front(), Some(index)); assert_eq!(slots.get(index), None); } - assert_eq!(slots.len(), 50); + assert_eq!(slots.len, 50); for data in 100..150 { slots.push_back(data); @@ -637,7 +357,7 @@ mod test { assert_eq!(slots.pop_front(), Some(target)); } assert_eq!(slots.pop_front(), None); - assert_eq!(slots.len(), 0); + assert_eq!(slots.len, 0); } /// UT test cases for Slots::remove(). @@ -658,98 +378,158 @@ mod test { assert_eq!(slots.remove(0), Ok(0)); } - /// UT test cases for Slots::get(). + /// UT test cases for Slots::is_empty(). /// /// # Brief - /// 1. Enter the location that stores data. - /// 2. Enter the location that doesn't store data. + /// 1. Verify empty container, the result is true. + /// 2. Verify non-empty container, the result is false. #[test] - fn ut_slots_get() { + fn ut_slots_is_empty() { let mut slots = Slots::new(); - let key = slots.push_back("key"); + assert!(slots.is_empty()); - assert_eq!(slots.get(key), Some(&"key")); - assert_eq!(slots.get(123), None); + slots.push_back(1); + assert!(!slots.is_empty()); } - /// UT test cases for Slots::get_mut(). + /// SDV test cases for Slots /// /// # Brief - /// 1. Enter the location that stores data. - /// 2. Enter the location that doesn't store data. + /// 1. Push a large amount of data into the initialized container. + /// 2. Check the correctness of inserted data iteratively. #[test] - fn ut_slots_get_mut() { + fn sdv_slots_huge_data_push_back() { let mut slots = Slots::new(); - let key = slots.push_back("key"); + let mut keys = Vec::new(); + + for data in 0..10000 { + let key = slots.push_back(data); + keys.push(key); + } - *slots.get_mut(key).unwrap() = "change_key"; - assert_eq!(*slots.get(key).unwrap(), "change_key"); - assert_eq!(slots.get(123), None); + for (index, key) in keys.iter().enumerate() { + assert_eq!(slots[*key], index); + } } - /// UT test cases for Slots::contains(). + /// SDV test cases for Slots /// /// # Brief - /// 1. The container exists the location and there are data at that - /// location. - /// 2. The container exists the location and there are no data at that - /// location. - /// 3. The container doesn't exist the location. + /// 1. Push a large amount of data into the initialized container. + /// 2. Remove the first half of the container. + /// 3. Push new data into the container again. + /// 4. Check the correctness of data sequence and values. #[test] - fn ut_slots_contains() { + fn sdv_slots_huge_data_remove() { let mut slots = Slots::new(); - let key = slots.push_back("key"); + let mut keys = Vec::new(); + + for data in 0..10000 { + let key = slots.push_back(data); + keys.push(key); + } + + for remove_index in 0..5000 { + let res = slots.remove(remove_index); + assert!(res.is_ok()); + } - assert!(slots.contains(key)); - assert!(!slots.contains(123)); + for data in 10000..15000 { + slots.push_back(data); + } - let res = slots.remove(key); - assert!(res.is_ok()); - assert!(!slots.contains(key)); + let mut cnt = 14999; + for key in 0..5000 { + assert_eq!(slots[key], cnt); + cnt -= 1; + } } - /// UT test cases for Slots::iter(). + /// SDV test cases for Slots /// /// # Brief - /// 1. Validate elements through iterators. + /// 1. Push data into the initialized container. + /// 2. Remove slots that have been popped. + /// 3. Remove slots at wrong index. + /// 4. Pop the remaining data. #[test] - fn ut_slots_iter() { + fn sdv_slots_remove_and_pop() { let mut slots = Slots::new(); - for i in 0..3 { - slots.push_back(i); + for data in 0..100 { + slots.push_back(data); + } + + for index in 0..10 { + slots.pop_front(); + let res = slots.remove(index); + assert!(res.is_err()); + } + + for remove_index in 100..150 { + let res = slots.remove(remove_index); + assert!(res.is_err()); } - for (key, element) in slots.iter() { - assert_eq!(slots.get(key).unwrap(), element); + for remove_index in 10..20 { + let res = slots.remove(remove_index); + assert!(res.is_ok()); } + + for index in 20..100 { + assert_eq!(slots.pop_front(), Some(index)); + } + assert!(slots.pop_front().is_none()); } - /// UT test cases for Slots::is_empty(). + /// SDV test cases for Slots /// /// # Brief - /// 1. Verify empty container, the result is true. - /// 2. Verify non-empty container, the result is false. + /// 1. Push a large amount of data into the initialized container. + /// 2. Find data through key-value pairs. #[test] - fn ut_slots_is_empty() { + fn sdv_slots_huge_data_find() { let mut slots = Slots::new(); - assert!(slots.is_empty()); + let mut keys = Vec::new(); - slots.push_back(1); - assert!(!slots.is_empty()); + for data in 0..10000 { + let key = slots.push_back(data); + keys.push(key); + } + + for key in keys { + assert_eq!(slots[key], key); + } } - /// UT test cases for Slots::capacity(). + /// SDV test cases for Slots /// /// # Brief - /// 1. Verify the container that is initialized. - /// 2. Verify the container that is initialized with specific capacity. + /// 1. Push a large amount of data into the initialized container. + /// 2. Pop the first half of the container. + /// 3. Push new data into the container again. + /// 4. Pop all of the data and check correctness of data sequence and + /// values. #[test] - fn ut_slots_capacity() { - let slots: Slots = Slots::new(); - assert_eq!(slots.capacity(), 0); + fn sdv_slots_huge_data_pop_front() { + let mut slots = Slots::new(); - let slots: Slots = Slots::with_capacity(10); - assert_eq!(slots.capacity(), 10); + for data in 0..10000 { + slots.push_back(data); + } + + for _ in 0..5000 { + slots.pop_front(); + } + + for data in 10000..15000 { + slots.push_back(data); + } + + let mut cnt = 14999; + for key in 0..5000 { + assert_eq!(slots[key], cnt); + cnt -= 1; + } } } diff --git a/ylong_runtime/tests/core_affinity.rs b/ylong_runtime/tests/core_affinity.rs deleted file mode 100644 index 78bc0e1..0000000 --- a/ylong_runtime/tests/core_affinity.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2023 Huawei Device Co., Ltd. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![cfg(target_os = "linux")] -use std::thread; - -use ylong_runtime::util::core_affinity::linux::{get_current_affinity, set_current_affinity}; -use ylong_runtime::util::num_cpus::get_cpu_num; - -#[test] -fn sdv_affinity_set() { - let cpus = get_current_affinity(); - assert!(!cpus.is_empty()); - - let ret = set_current_affinity(0).is_ok(); - assert!(ret); - - let cpus = get_current_affinity(); - assert_eq!(cpus.len(), 1); -} - -#[test] -fn sdv_affinity_core() { - let cpus = get_cpu_num() as usize; - let handle = thread::spawn(move || { - set_current_affinity(0 % cpus).unwrap(); - let core_ids = get_current_affinity(); - for coreid in core_ids.iter() { - assert_eq!(*coreid, 0_usize); - } - }); - let _ = handle.join(); - thread::spawn(move || { - set_current_affinity(1 % cpus).unwrap(); - let core_ids = get_current_affinity(); - for coreid in core_ids.iter() { - assert_eq!(*coreid, 1_usize); - } - }); -} diff --git a/ylong_runtime/tests/entry.rs b/ylong_runtime/tests/entry.rs index 7142db3..edef8bf 100644 --- a/ylong_runtime/tests/entry.rs +++ b/ylong_runtime/tests/entry.rs @@ -21,16 +21,12 @@ mod async_pool; mod async_read; mod block_on; mod builder; -mod core_affinity; mod join_set; mod mpsc_test; mod mutex; -mod num_cpus; mod par_iter; mod semaphore_test; mod singleton_runtime; -mod slab; -mod slots; mod spawn; mod spawn_blocking; mod sync; diff --git a/ylong_runtime/tests/num_cpus.rs b/ylong_runtime/tests/num_cpus.rs deleted file mode 100644 index 3182961..0000000 --- a/ylong_runtime/tests/num_cpus.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2023 Huawei Device Co., Ltd. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use ylong_runtime::util::num_cpus::get_cpu_num; - -#[cfg(target_os = "linux")] -#[test] -fn sdv_num_cpus_linux_test() { - use ylong_runtime::util::num_cpus::linux::get_cpu_num_configured; - - let cpus = get_cpu_num(); - assert!(cpus > 0); - let cpus = get_cpu_num_configured(); - assert!(cpus > 0); -} - -#[cfg(target_os = "windows")] -#[test] -fn sdv_num_cpus_windows_test() { - let cpus = get_cpu_num(); - assert!(cpus > 0); -} diff --git a/ylong_runtime/tests/slab.rs b/ylong_runtime/tests/slab.rs deleted file mode 100644 index 2aa329b..0000000 --- a/ylong_runtime/tests/slab.rs +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright (c) 2023 Huawei Device Co., Ltd. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering::SeqCst; -use std::sync::{Arc, Mutex}; -use std::thread; - -use ylong_runtime::util::slab::{Entry, Slab}; - -struct TestEntry { - cnt: AtomicUsize, - id: AtomicUsize, -} - -impl Default for TestEntry { - fn default() -> TestEntry { - TestEntry { - cnt: AtomicUsize::new(0), - id: AtomicUsize::new(0), - } - } -} - -impl Entry for TestEntry { - fn reset(&self) { - self.cnt.fetch_add(1, SeqCst); - } -} - -/// SDV test cases for Slab -/// -/// # Brief -/// 1. Inserting large amounts of data into a container. -/// 2. Make changes to these inserted data. -/// 3. Modified data by address verification. -/// 4. Multiplexing mechanism after calibration is released. -#[test] -fn sdv_slab_insert_move() { - let mut slab = Slab::::new(); - let alloc = slab.handle(); - - unsafe { - // Find the first available `slot` and return its `addr` and `Ref` - let (addr1, test_entry1) = alloc.allocate().unwrap(); - // Modify the current `id` - slab.get(addr1).unwrap().id.store(1, SeqCst); - // The `reset` function has not been called yet, so `cnt` remains unchanged - assert_eq!(0, slab.get(addr1).unwrap().cnt.load(SeqCst)); - - // Find the second available `slot` and return its `addr` and `Ref` - let (addr2, test_entry2) = alloc.allocate().unwrap(); - slab.get(addr2).unwrap().id.store(2, SeqCst); - assert_eq!(0, slab.get(addr2).unwrap().cnt.load(SeqCst)); - - // This verifies that the function of finding data based on `addr` is working - assert_eq!(1, slab.get(addr1).unwrap().id.load(SeqCst)); - assert_eq!(2, slab.get(addr2).unwrap().id.load(SeqCst)); - - // Active destruct, the `slot` will be reused - drop(test_entry1); - - assert_eq!(1, slab.get(addr1).unwrap().id.load(SeqCst)); - - // Allocate again, but then the allocated `slot` should use the previously - // destructured `slot` - let (addr3, test_entry3) = alloc.allocate().unwrap(); - // Comparison, equal is successful - assert_eq!(addr3, addr1); - assert_eq!(1, slab.get(addr3).unwrap().cnt.load(SeqCst)); - slab.get(addr3).unwrap().id.store(3, SeqCst); - assert_eq!(3, slab.get(addr3).unwrap().id.load(SeqCst)); - - drop(test_entry2); - drop(test_entry3); - - // Cleaned regularly, but the first `page` is never cleaned - slab.compact(); - assert!(slab.get(addr1).is_some()); - assert!(slab.get(addr2).is_some()); - assert!(slab.get(addr3).is_some()); - } -} - -/// SDV test cases for Slab -/// -/// # Brief -/// 1. Inserting large amounts of data into a container -/// 2. Verify by address that the data is in the correct location -#[test] -fn sdv_slab_insert_many() { - unsafe { - // Verify that `page` is being allocated properly in the case of a large number - // of inserts. - let mut slab = Slab::::new(); - let alloc = slab.handle(); - let mut entries = vec![]; - - for i in 0..10_000 { - let (addr, val) = alloc.allocate().unwrap(); - val.id.store(i, SeqCst); - entries.push((addr, val)); - } - - for (i, (addr, v)) in entries.iter().enumerate() { - assert_eq!(i, v.id.load(SeqCst)); - assert_eq!(i, slab.get(*addr).unwrap().id.load(SeqCst)); - } - - entries.clear(); - - for i in 0..10_000 { - let (addr, val) = alloc.allocate().unwrap(); - val.id.store(10_000 - i, SeqCst); - entries.push((addr, val)); - } - - for (i, (addr, v)) in entries.iter().enumerate() { - assert_eq!(10_000 - i, v.id.load(SeqCst)); - assert_eq!(10_000 - i, slab.get(*addr).unwrap().id.load(SeqCst)); - } - } -} - -/// SDV test cases for Slab -/// -/// # Brief -/// 1. Inserting large amounts of data into a container -/// 2. Verify by address that the data is in the correct location -#[test] -fn sdv_slab_insert_drop_reverse() { - unsafe { - let mut slab = Slab::::new(); - let alloc = slab.handle(); - let mut entries = vec![]; - - for i in 0..10_000 { - let (addr, val) = alloc.allocate().unwrap(); - val.id.store(i, SeqCst); - entries.push((addr, val)); - } - - for _ in 0..10 { - for _ in 0..1_000 { - entries.pop(); - } - - for (i, (addr, v)) in entries.iter().enumerate() { - assert_eq!(i, v.id.load(SeqCst)); - assert_eq!(i, slab.get(*addr).unwrap().id.load(SeqCst)); - } - } - } -} - -/// SDV test cases for Slab -/// -/// # Brief -/// 1. Multi-threaded allocation of container space, inserting data into it, and -/// verifying that the function is correct -#[test] -fn sdv_slab_multi_allocate() { - // Multi-threaded either allocating space, or modifying values. - // finally comparing the values given by the acquired address to be equal. - let mut slab = Slab::::new(); - let thread_one_alloc = slab.handle(); - let thread_two_alloc = slab.handle(); - let thread_three_alloc = slab.handle(); - - let capacity = 3001; - let free_queue = Arc::new(Mutex::new(Vec::with_capacity(capacity))); - let free_queue_2 = free_queue.clone(); - let free_queue_3 = free_queue.clone(); - let free_queue_4 = free_queue.clone(); - - unsafe { - let thread_one = thread::spawn(move || { - for i in 0..10_00 { - let (addr, test_entry) = thread_one_alloc.allocate().unwrap(); - test_entry.id.store(i, SeqCst); - free_queue.lock().unwrap().push((addr, test_entry, i)); - } - }); - - let thread_two = thread::spawn(move || { - for i in 10_00..20_00 { - let (addr, test_entry) = thread_two_alloc.allocate().unwrap(); - test_entry.id.store(i, SeqCst); - free_queue_2.lock().unwrap().push((addr, test_entry, i)); - } - }); - - let thread_three = thread::spawn(move || { - for i in 20_00..30_00 { - let (addr, test_entry) = thread_three_alloc.allocate().unwrap(); - test_entry.id.store(i, SeqCst); - free_queue_3.lock().unwrap().push((addr, test_entry, i)); - } - }); - - thread_one - .join() - .expect("Couldn't join on the associated thread"); - thread_two - .join() - .expect("Couldn't join on the associated thread"); - thread_three - .join() - .expect("Couldn't join on the associated thread"); - } - - for _ in 0..30_00 { - let temp = free_queue_4.clone().lock().unwrap().pop().unwrap(); - assert_eq!(slab.get(temp.0).unwrap().id.load(SeqCst), temp.2); - } -} - -/// SDV test cases for Slab -/// -/// # Brief -/// 1. Multi-threaded allocation of container space, inserting data into it, and -/// verifying that the function is correct -/// 2. Free up some of the data space and check if the data is reused in the -/// multi-threaded case -#[test] -fn sdv_slab_multi_allocate_drop() { - // allocate space and free the used `slot` in the multi-threaded case. - // retaining the address of the freed `slot` and allocating it again. - // the address after reallocation is the same as the address of the previously - // freed `slot`. - let slab = Slab::::new(); - let thread_one_alloc = slab.handle(); - let thread_two_alloc = slab.handle(); - - let capacity = 2001; - let free_queue_one = Arc::new(Mutex::new(Vec::with_capacity(capacity))); - let free_queue_one_2 = free_queue_one.clone(); - - let free_queue_two = Arc::new(Mutex::new(Vec::with_capacity(capacity))); - let free_queue_two_2 = free_queue_two.clone(); - - unsafe { - let thread_one = thread::spawn(move || { - for i in 0..1000 { - let (addr, test_entry) = thread_one_alloc.allocate().unwrap(); - test_entry.id.store(i, SeqCst); - drop(test_entry); - - free_queue_one.lock().unwrap().push(addr); - } - }); - - thread_one - .join() - .expect("Couldn't join on the associated thread"); - - let thread_two = thread::spawn(move || { - thread::park(); - for i in 0..1000 { - let (addr, test_entry) = thread_two_alloc.allocate().unwrap(); - test_entry.id.store(i, SeqCst); - - free_queue_two.lock().unwrap().push(addr); - } - }); - - thread_two.thread().unpark(); - thread_two - .join() - .expect("Couldn't join on the associated thread"); - - for _ in 0..1000 { - assert_eq!( - free_queue_one_2.clone().lock().unwrap().pop().unwrap(), - free_queue_two_2.lock().unwrap().pop().unwrap() - ); - } - } -} diff --git a/ylong_runtime/tests/slots.rs b/ylong_runtime/tests/slots.rs deleted file mode 100644 index 981f2ae..0000000 --- a/ylong_runtime/tests/slots.rs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2023 Huawei Device Co., Ltd. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use ylong_runtime::util::slots::Slots; - -/// SDV test cases for Slots -/// -/// # Brief -/// 1. Push a large amount of data into the initialized container. -/// 2. Check the correctness of inserted data iteratively. -#[test] -fn sdv_slots_huge_data_push_back() { - let mut slots = Slots::new(); - let mut keys = Vec::new(); - - for data in 0..10000 { - let key = slots.push_back(data); - keys.push(key); - } - - for (index, key) in keys.iter().enumerate() { - assert_eq!(slots[*key], index); - } -} - -/// SDV test cases for Slots -/// -/// # Brief -/// 1. Push a large amount of data into the initialized container. -/// 2. Remove the first half of the container. -/// 3. Push new data into the container again. -/// 4. Check the correctness of data sequence and values. -#[test] -fn sdv_slots_huge_data_remove() { - let mut slots = Slots::new(); - let mut keys = Vec::new(); - - for data in 0..10000 { - let key = slots.push_back(data); - keys.push(key); - } - - for remove_index in 0..5000 { - let res = slots.remove(remove_index); - assert!(res.is_ok()); - } - - for data in 10000..15000 { - slots.push_back(data); - } - - let mut cnt = 14999; - for key in 0..5000 { - assert_eq!(slots[key], cnt); - cnt -= 1; - } -} - -/// SDV test cases for Slots -/// -/// # Brief -/// 1. Push data into the initialized container. -/// 2. Remove slots that have been popped. -/// 3. Remove slots at wrong index. -/// 4. Pop the remaining data. -#[test] -fn sdv_slots_remove_and_pop() { - let mut slots = Slots::new(); - - for data in 0..100 { - slots.push_back(data); - } - - for index in 0..10 { - slots.pop_front(); - let res = slots.remove(index); - assert!(res.is_err()); - } - - for remove_index in 100..150 { - let res = slots.remove(remove_index); - assert!(res.is_err()); - } - - for remove_index in 10..20 { - let res = slots.remove(remove_index); - assert!(res.is_ok()); - } - - for index in 20..100 { - assert_eq!(slots.pop_front(), Some(index)); - } - assert!(slots.pop_front().is_none()); -} - -/// SDV test cases for Slots -/// -/// # Brief -/// 1. Push a large amount of data into the initialized container. -/// 2. Find data through key-value pairs. -#[test] -fn sdv_slots_huge_data_find() { - let mut slots = Slots::new(); - let mut keys = Vec::new(); - - for data in 0..10000 { - let key = slots.push_back(data); - keys.push(key); - } - - for key in keys { - assert_eq!(slots[key], key); - } -} - -/// SDV test cases for Slots -/// -/// # Brief -/// 1. Push a large amount of data into the initialized container. -/// 2. Pop the first half of the container. -/// 3. Push new data into the container again. -/// 4. Pop all of the data and check correctness of data sequence and values. -#[test] -fn sdv_slots_huge_data_pop_front() { - let mut slots = Slots::new(); - - for data in 0..10000 { - slots.push_back(data); - } - - for _ in 0..5000 { - slots.pop_front(); - } - - for data in 10000..15000 { - slots.push_back(data); - } - - let mut cnt = 14999; - for key in 0..5000 { - assert_eq!(slots[key], cnt); - cnt -= 1; - } -} diff --git a/ylong_runtime/tests/task_cancel.rs b/ylong_runtime/tests/task_cancel.rs index e2ca9a8..6e86637 100644 --- a/ylong_runtime/tests/task_cancel.rs +++ b/ylong_runtime/tests/task_cancel.rs @@ -63,23 +63,14 @@ fn sdv_task_cancel_failed() { ylong_runtime::block_on(handle).unwrap(); } -#[derive(Default)] -struct TestFuture { - flag: usize, -} +struct TestFuture; impl Future for TestFuture { type Output = u8; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.get_mut(); - if this.flag < 1000000 { - this.flag += 1; - cx.waker().wake_by_ref(); - Poll::Pending - } else { - Poll::Ready(1) - } + cx.waker().wake_by_ref(); + Poll::Pending } } @@ -93,9 +84,7 @@ fn sdv_task_cancel_multiple() { for _ in 0..1000 { ylong_runtime::block_on(async move { let handle = ylong_runtime::spawn(async move { - TestFuture::default().await; - sleep(Duration::from_secs(1000000)); - 1 + TestFuture.await; }); handle.cancel(); let res = handle.await; diff --git a/ylong_runtime/tests/tcp_test.rs b/ylong_runtime/tests/tcp_test.rs index 794fc27..11b9814 100644 --- a/ylong_runtime/tests/tcp_test.rs +++ b/ylong_runtime/tests/tcp_test.rs @@ -20,31 +20,20 @@ use ylong_runtime::net::{TcpListener, TcpStream}; fn test_tcp_client() { let mut recv_buf = [0_u8; 12]; + let addr = "127.0.0.1:8081"; let handle = ylong_runtime::spawn(async move { loop { - let addr = "127.0.0.1:8081"; if let Ok(mut client) = TcpStream::connect(addr).await { - match client.write(b"hello server").await { - Ok(n) => { - assert_eq!(n, "hello server".len()); - } - Err(e) => { - assert_eq!(0, 1, "client send failed {e}"); - } - } - match client.read(&mut recv_buf).await { - Ok(n) => { - assert_eq!( - std::str::from_utf8(&recv_buf).unwrap(), - "hello client".to_string() - ); - assert_eq!(n, "hello client".len()); - break; - } - Err(e) => { - assert_eq!(0, 1, "client recv failed {e}"); - } - } + assert_eq!( + client.write(b"hello server").await.unwrap(), + "hello server".len() + ); + assert_eq!( + client.read(&mut recv_buf).await.unwrap(), + "hello client".len() + ); + assert_eq!(&recv_buf[.."hello client".len()], "hello client".as_bytes()); + break; }; } }); @@ -57,42 +46,19 @@ fn sdv_tcp_global_runtime() { thread::spawn(test_tcp_client); let addr = "127.0.0.1:8081"; let handle = ylong_runtime::spawn(async move { - let listener = TcpListener::bind(addr).await; - if let Err(e) = listener { - assert_eq!(0, 1, "Bind Listener Failed {e}"); - return; - } + let listener = TcpListener::bind(addr).await.unwrap(); - let listener = listener.unwrap(); - let mut socket = match listener.accept().await { - Ok((socket, _)) => socket, - Err(e) => { - assert_eq!(0, 1, "Bind accept Failed {e}"); - return; - } - }; + let mut socket = listener.accept().await.unwrap().0; loop { let mut buf = [0_u8; 12]; - let _ = match socket.read(&mut buf).await { - Ok(n) if n == 0 => break, - Ok(n) => { - assert_eq!( - std::str::from_utf8(&buf).unwrap(), - "hello server".to_string() - ); - assert_eq!(n, "hello server".len()); - n - } - Err(e) => { - assert_eq!(0, 1, "recv Failed {e}"); - break; - } - }; - - if let Err(e) = socket.write(b"hello client").await { - assert_eq!(0, 1, "failed to write to socket {e}"); + let n = socket.read(&mut buf).await.unwrap(); + if n == 0 { break; } + assert_eq!(&buf[..], "hello server".as_bytes()); + assert_eq!(n, "hello server".len()); + + socket.write(b"hello client").await.unwrap(); } }); ylong_runtime::block_on(handle).expect("block_on failed"); diff --git a/ylong_runtime/tests/udp_test.rs b/ylong_runtime/tests/udp_test.rs index 6361466..377cd61 100644 --- a/ylong_runtime/tests/udp_test.rs +++ b/ylong_runtime/tests/udp_test.rs @@ -29,41 +29,18 @@ fn sdv_udp_send_recv() { let sender_addr = "127.0.0.1:8081"; let receiver_addr = "127.0.0.1:8082"; let handle = ylong_runtime::spawn(async move { - let sender = match UdpSocket::bind(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let receiver = match UdpSocket::bind(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let connected_sender = match sender.connect(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; - let connected_receiver = match receiver.connect(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; - - match connected_sender.send(b"Hello").await { - Ok(n) => { - assert_eq!(n, "Hello".len()); - } - Err(e) => { - panic!("Sender Send Failed {}", e); - } - } + let sender = UdpSocket::bind(sender_addr).await.unwrap(); + + let receiver = UdpSocket::bind(receiver_addr).await.unwrap(); + + let connected_sender = sender.connect(receiver_addr).await.unwrap(); + + let connected_receiver = receiver.connect(sender_addr).await.unwrap(); + + assert_eq!( + connected_sender.send(b"Hello").await.unwrap(), + "Hello".len() + ); let mut recv_buf = [0_u8; 12]; let len = connected_receiver.recv(&mut recv_buf[..]).await.unwrap(); @@ -85,28 +62,11 @@ fn sdv_udp_send_to_recv_from() { let sender_addr = "127.0.0.1:8085"; let receiver_addr = "127.0.0.1:8086"; let handle = ylong_runtime::spawn(async move { - let sender = match UdpSocket::bind(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let receiver = match UdpSocket::bind(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - match sender.send_to(b"Hello", receiver_addr).await { - Ok(n) => { - assert_eq!(n, "Hello".len()); - } - Err(e) => { - panic!("Sender Send Failed {}", e); - } - } + let sender = UdpSocket::bind(sender_addr).await.unwrap(); + + let receiver = UdpSocket::bind(receiver_addr).await.unwrap(); + + sender.send_to(b"Hello", receiver_addr).await.unwrap(); let mut recv_buf = [0_u8; 12]; let (len, addr) = receiver.recv_from(&mut recv_buf[..]).await.unwrap(); @@ -120,28 +80,14 @@ fn sdv_udp_send() { let sender_addr = "127.0.0.1:8089"; let receiver_addr = "127.0.0.1:8090"; let handle = ylong_runtime::spawn(async move { - let sender = match UdpSocket::bind(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let connected_sender = match sender.connect(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; - - match connected_sender.send(b"Hello").await { - Ok(n) => { - assert_eq!(n, "Hello".len()); - } - Err(e) => { - panic!("Sender Send Failed {}", e); - } - } + let sender = UdpSocket::bind(sender_addr).await.unwrap(); + + let connected_sender = sender.connect(receiver_addr).await.unwrap(); + + assert_eq!( + connected_sender.send(b"Hello").await.unwrap(), + "Hello".len() + ); }); ylong_runtime::block_on(handle).expect("block_on failed"); } @@ -159,19 +105,9 @@ fn sdv_udp_recv() { let sender_addr = "127.0.0.1:8089"; let receiver_addr = "127.0.0.1:8090"; let handle = ylong_runtime::spawn(async move { - let receiver = match UdpSocket::bind(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let connected_receiver = match receiver.connect(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; + let receiver = UdpSocket::bind(receiver_addr).await.unwrap(); + + let connected_receiver = receiver.connect(sender_addr).await.unwrap(); thread::spawn(sdv_udp_send); let mut recv_buf = [0_u8; 12]; let len = connected_receiver.recv(&mut recv_buf[..]).await.unwrap(); @@ -194,28 +130,15 @@ fn sdv_udp_try_recv_from() { let sender_addr = "127.0.0.1:8091"; let receiver_addr = "127.0.0.1:8092"; let handle = ylong_runtime::spawn(async move { - let sender = match UdpSocket::bind(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let receiver = match UdpSocket::bind(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; + let sender = UdpSocket::bind(sender_addr).await.unwrap(); + + let receiver = UdpSocket::bind(receiver_addr).await.unwrap(); sender.writable().await.unwrap(); let mut ret = sender.try_send_to(b"Hello", receiver_addr.parse().unwrap()); while let Err(ref e) = ret { - if e.kind() == io::ErrorKind::WouldBlock { - ret = sender.try_send_to(b"Hello", receiver_addr.parse().unwrap()); - } else { - panic!("try_send_to failed: {}", e); - } + assert_eq!(e.kind(), io::ErrorKind::WouldBlock); + ret = sender.try_send_to(b"Hello", receiver_addr.parse().unwrap()); } assert_eq!(ret.unwrap(), 5); @@ -224,11 +147,8 @@ fn sdv_udp_try_recv_from() { receiver.readable().await.unwrap(); let mut ret = receiver.try_recv_from(&mut recv_buf[..]); while let Err(ref e) = ret { - if e.kind() == io::ErrorKind::WouldBlock { - ret = receiver.try_recv_from(&mut recv_buf[..]); - } else { - panic!("try_send_to failed: {}", e); - } + assert_eq!(e.kind(), io::ErrorKind::WouldBlock); + ret = receiver.try_recv_from(&mut recv_buf[..]); } let (len, peer_addr) = ret.unwrap(); assert_eq!(&recv_buf[..len], b"Hello"); @@ -239,29 +159,12 @@ fn sdv_udp_try_recv_from() { fn sdv_udp_try_send(sender_addr: String, receiver_addr: String) { let handle = ylong_runtime::spawn(async move { - let sender = match UdpSocket::bind(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let connected_sender = match sender.connect(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; + let sender = UdpSocket::bind(sender_addr).await.unwrap(); + + let connected_sender = sender.connect(receiver_addr).await.unwrap(); connected_sender.writable().await.unwrap(); - match connected_sender.try_send(b"Hello") { - Ok(n) => { - assert_eq!(n, "Hello".len()); - } - Err(e) => { - panic!("Sender Send Failed {}", e); - } - } + assert_eq!(connected_sender.try_send(b"Hello").unwrap(), "Hello".len()); }); ylong_runtime::block_on(handle).expect("block_on failed"); } @@ -281,19 +184,9 @@ fn sdv_udp_try_recv() { let sender_addr = "127.0.0.1:8093"; let receiver_addr = "127.0.0.1:8094"; let handle = ylong_runtime::spawn(async move { - let receiver = match UdpSocket::bind(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let connected_receiver = match receiver.connect(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; + let receiver = UdpSocket::bind(receiver_addr).await.unwrap(); + + let connected_receiver = receiver.connect(sender_addr).await.unwrap(); thread::spawn(|| { sdv_udp_try_send("127.0.0.1:8093".to_string(), "127.0.0.1:8094".to_string()) }); @@ -322,19 +215,9 @@ fn sdv_block_on_udp_try_recv() { let sender_addr = "127.0.0.1:8110"; let receiver_addr = "127.0.0.1:8111"; ylong_runtime::block_on(async move { - let receiver = match UdpSocket::bind(receiver_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Bind Socket Failed {}", e); - } - }; - - let connected_receiver = match receiver.connect(sender_addr).await { - Ok(socket) => socket, - Err(e) => { - panic!("Connect Socket Failed {}", e); - } - }; + let receiver = UdpSocket::bind(receiver_addr).await.unwrap(); + + let connected_receiver = receiver.connect(sender_addr).await.unwrap(); thread::spawn(|| { sdv_udp_try_send("127.0.0.1:8110".to_string(), "127.0.0.1:8111".to_string()) }); -- Gitee