1
This commit is contained in:
parent
1e0615b6e7
commit
c3280f8747
@ -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
98
r9/src/listheadlock.rs
Normal 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
51
r9/src/queuelock.rs
Normal 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()
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user