This commit is contained in:
azw 2024-05-12 12:57:59 +08:00
parent 1e0615b6e7
commit c3280f8747
5 changed files with 180 additions and 0 deletions

View File

@ -1,7 +1,11 @@
pub mod xtimer;
pub mod listhead;
pub mod queue;
pub mod listheadlock;
pub mod queuelock;
pub use xtimer::XTimer;
pub use listhead::ListHead;
pub use queue::Queue;
pub use listheadlock::*;
pub use queuelock::*;

98
r9/src/listheadlock.rs Normal file
View File

@ -0,0 +1,98 @@
use std::sync::{Arc, Weak, Mutex};
use std::ptr;
use r9_macro::SharedFromSelfLock;
use r9_macro_derive::SharedFromSelfLock;
#[derive(Default)]
#[derive(SharedFromSelfLock)]
pub struct ListHeadLock<T> {
prev: Weak::<Mutex::<Self>>,
next: Weak::<Mutex::<Self>>,
data: Weak::<Mutex::<T>>,
_self_wp: Weak::<Mutex::<Self>>,
}
unsafe impl<T> Send for ListHeadLock<T> {}
unsafe impl<T> Sync for ListHeadLock<T> {}
impl<T> ListHeadLock<T> {
fn new(data: Weak::<Mutex::<T>>) -> Arc::<Mutex::<Self>> {
let this = Arc::new(Mutex::new(Self{
prev: Default::default(),
next: Default::default(),
data: data,
_self_wp: Default::default(),
}));
this.lock().unwrap()._self_wp = Arc::downgrade(&this);
this.lock().unwrap().init();
return this;
}
pub fn new_head() -> Arc::<Mutex::<Self>> {
return Self::new(Default::default());
}
pub fn new_node(data: Weak::<Mutex::<T>>) -> Arc::<Mutex::<Self>> {
return Self::new(data);
}
fn init(&mut self) {
self.prev = Arc::downgrade(&self.shared_from_self_lock());
self.next = Arc::downgrade(&self.shared_from_self_lock());
}
pub fn data(&self) -> Weak::<Mutex::<T>> {
return self.data.clone();
}
pub fn del_init(&mut self) {
self.next.upgrade().unwrap().lock().unwrap()._self_wp = self.prev.clone();
self.prev.upgrade().unwrap().lock().unwrap().next = self.next.clone();
self.init();
}
pub fn empty(&self) -> bool {
return ptr::eq(self.next.as_ptr(),Arc::as_ptr(&self.shared_from_self_lock()));
}
pub fn add_tail(head: &Arc::<Mutex::<Self>>, pnew: &Arc::<Mutex::<Self>>) {
let prev = &head.lock().unwrap().prev.clone();
let next = head;
next.lock().unwrap().prev = Arc::downgrade(pnew);
pnew.lock().unwrap().next = Arc::downgrade(&next);
pnew.lock().unwrap().prev = prev.clone();
prev.upgrade().unwrap().lock().unwrap().next = Arc::downgrade(pnew);
}
pub fn first_entry(&self) -> Weak::<Mutex::<T>> {
if self.empty() {
panic!("");
}
return self.next.upgrade().unwrap().lock().unwrap().data();
}
pub fn replace_init(head: &Arc::<Mutex::<Self>>, pnew: &Arc::<Mutex::<Self>>) {
if head.lock().unwrap().empty() {
return;
}
pnew.lock().unwrap().next = head.lock().unwrap().next.clone();
pnew.lock().unwrap().next.upgrade().unwrap().lock().unwrap().prev = Arc::downgrade(pnew);
pnew.lock().unwrap().prev = head.lock().unwrap().prev.clone();
pnew.lock().unwrap().prev.upgrade().unwrap().lock().unwrap().next = Arc::downgrade(pnew);
head.lock().unwrap().init();
}
pub fn for_each(&self, cb: fn (&Weak::<Mutex::<T>>) -> bool) {
let mut pos = self.next.clone();
let self_weak = Arc::downgrade(&self.shared_from_self_lock());
while !Weak::ptr_eq(&pos, &self_weak) {
if !cb(&pos.upgrade().unwrap().lock().unwrap().data()) {
break;
}
pos = pos.upgrade().unwrap().lock().unwrap().next.clone();
}
}
}

51
r9/src/queuelock.rs Normal file
View File

@ -0,0 +1,51 @@
use std::sync::Mutex;
use std::sync::Arc;
use r9_macro::SharedFromSelf;
use r9_macro_derive::SharedFromSelf;
use std::default::Default;
pub struct QueueLock<T> {
msg_list: Mutex<Arc::<Mutex::<crate::ListHeadLock<T>>>>,
pub work_list: Mutex<Arc::<Mutex::<crate::ListHeadLock<T>>>>,
}
unsafe impl<T> Send for QueueLock<T> {}
unsafe impl<T> Sync for QueueLock<T> {}
impl<T> QueueLock<T> {
pub fn new() -> Arc::<Mutex::<Self>> {
let this = Arc::new(Mutex::new(Self{
msg_list: Mutex::new(crate::ListHeadLock::<T>::new_head()),
work_list: Mutex::new(crate::ListHeadLock::<T>::new_head()),
}));
return this;
}
pub fn new_ex() -> Arc::<Mutex::<Self>> {
let this = Arc::new(Mutex::new(Self{
msg_list: Mutex::new(crate::ListHeadLock::<T>::new_head()),
work_list: Mutex::new(crate::ListHeadLock::<T>::new_head()),
}));
return this;
}
pub fn push(&self, node: &Arc::<Mutex::<crate::ListHeadLock<T>>>) {
crate::ListHeadLock::<T>::add_tail(&self.msg_list.lock().unwrap(), node);
}
pub fn fetch(&self) {
if !self.msg_list.lock().unwrap().lock().unwrap().empty() &&
self.work_list.lock().unwrap().lock().unwrap().empty() {
crate::ListHeadLock::replace_init(&self.msg_list.lock().unwrap(), &self.work_list.lock().unwrap());
}
}
pub fn empty(&self) -> bool {
if !self.work_list.lock().unwrap().lock().unwrap().empty() {
return false
}
return self.msg_list.lock().unwrap().lock().unwrap().empty()
}
}

View File

@ -1,4 +1,6 @@
use std::rc::Rc;
use std::sync::Arc;
use std::sync::Mutex;
use std::cell::RefCell;
#[cfg(test)]
@ -14,5 +16,9 @@ pub trait SharedFromSelf {
fn shared_from_self(&self) -> Rc::<RefCell::<Self>>;
}
pub trait SharedFromSelfLock {
fn shared_from_self_lock(&self) -> Arc::<Mutex::<Self>>;
}
pub trait Singleton {
}

View File

@ -32,6 +32,27 @@ fn impl_shared_from_self_macro(ast: &syn::DeriveInput) -> TokenStream {
gen.into()
}
#[proc_macro_derive(SharedFromSelfLock, attributes(helper))]
pub fn shared_from_self_lock_derive(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap();
// Build the trait implementation
crate::impl_shared_from_self_lock_macro(&ast)
}
fn impl_shared_from_self_lock_macro(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let (impl_generics, _, _) = ast.generics.split_for_impl();
let gen = quote! {
impl #impl_generics SharedFromSelfLock for #name #impl_generics {
fn shared_from_self_lock(&self) -> Arc::<Mutex::<Self>> {
return self._self_wp.upgrade().unwrap();
}
}
};
gen.into()
}
#[proc_macro_derive(Singleton)]
pub fn singleton_derive(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap();