crgc/
cr.rs

1use std::cell::RefCell;
2use std::ptr::NonNull;
3
4thread_local! {
5    static CRGC: RefCell<CycleRemover> = RefCell::new(CycleRemover::init());
6    static TEMP: RefCell<Vec<usize>> = RefCell::new(Vec::new());
7}
8
9pub trait Trace: 'static {
10    fn step1(&self);
11    fn step2(&self);
12}
13pub(crate) trait Tracer {
14    fn count(&self) -> usize;
15    fn index(&self) -> usize;
16    fn run_step1(&mut self);
17    fn run_step2(&mut self);
18    unsafe fn free(&mut self);
19}
20
21pub struct CycleRemover {
22    pub(crate) list: Vec<Option<NonNull<dyn Tracer>>>,
23    pub(crate) stack: Vec<usize>,
24}
25impl CycleRemover {
26    #[inline]
27    fn init() -> CycleRemover {
28        CycleRemover {
29            list: Vec::new(),
30            stack: Vec::new(),
31        }
32    }
33}
34impl CycleRemover {
35    #[inline]
36    fn append(&mut self, meta: NonNull<dyn Tracer>) -> usize {
37        if let Some(i) = self.stack.pop() {
38            self.list[i] = Some(meta);
39            return i;
40        } else {
41            let i = self.list.len();
42            self.list.push(Some(meta));
43            return i;
44        }
45    }
46    #[inline]
47    fn remove(&mut self, i: usize) {
48        self.list[i] = None;
49        self.stack.push(i);
50    }
51}
52impl CycleRemover {
53    #[inline]
54    fn temp(i: usize) {
55        TEMP.with(|temp| temp.borrow_mut().push(i));
56    }
57    #[inline]
58    fn collect(&mut self) {
59        let iter = self.list.iter();
60        for i in iter {
61            if let Some(a) = i {
62                unsafe {
63                    (*(*a).as_ptr()).run_step1();
64                }
65            }
66        }
67        TEMP.with(|tref| {
68            let mut temp = tref.borrow_mut();
69            temp.sort();
70
71            let mut titer = temp.iter();
72            let mut ti = titer.next();
73
74            let mut ci = 0;
75            let iter = self.list.iter();
76            for i in iter {
77                let step2 = || {
78                    if let Some(a) = i {
79                        unsafe {
80                            (*(*a).as_ptr()).run_step2();
81                        }
82                    }
83                };
84                if let Some(x) = ti {
85                    if *x != ci {
86                        step2();
87                    } else {
88                        ti = titer.next();
89                    }
90                } else {
91                    step2();
92                }
93                ci += 1;
94            }
95
96            let iter = temp.iter();
97            for i in iter {
98                if let Some(x) = self.list[*i] {
99                    unsafe {
100                        if (*x.as_ptr()).count() == 0 {
101                            self.remove((*x.as_ptr()).index());
102                            (*x.as_ptr()).free();
103                        }
104                    }
105                }
106            }
107            temp.clear();
108        });
109    }
110}
111
112pub fn collect() {
113    CRGC.with(|crgc| crgc.borrow_mut().collect())
114}
115pub(crate) fn append(meta: NonNull<dyn Tracer>) -> usize {
116    CRGC.with(|crgc| crgc.borrow_mut().append(meta))
117}
118pub(crate) fn remove(i: usize) {
119    CRGC.with(|crgc| crgc.borrow_mut().remove(i));
120}
121pub(crate) fn temp(i: usize) {
122    CycleRemover::temp(i);
123}