make it pass miri

This commit is contained in:
Evan Almloff committed 2023-01-02 11:01:17 -06:00
1 parent 359b4e514b
commit 6d60c483f8
5 files changed
+225 -288

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ dioxus-core-macro = { path = "../core-macro", version = "^0.2.1" }
taffy = "0.2.1" taffy = "0.2.1"
smallvec = "1.6" smallvec = "1.6"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
anymap = "0.12.1" anymap = "1.0.0-beta.2"
slab = "0.4" slab = "0.4"
parking_lot = "0.12.1" parking_lot = "0.12.1"
crossbeam-deque = "0.8.2" crossbeam-deque = "0.8.2"
+2 -1
View File
@@ -1,3 +1,4 @@
use std::any::Any;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
pub use node_ref::NodeMask; pub use node_ref::NodeMask;
@@ -20,7 +21,7 @@ pub mod utils;
pub type RealNodeId = NodeId; pub type RealNodeId = NodeId;
pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>; pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>; pub type FxDashSet<K> = dashmap::DashSet<K, BuildHasherDefault<FxHasher>>;
pub type SendAnyMap = anymap::Map<dyn anymap::any::Any + Send + Sync + 'static>; pub type SendAnyMap = anymap::Map<dyn Any + Send + Sync + 'static>;
/// Used in derived state macros /// Used in derived state macros
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq)]
+50 -49
View File
@@ -313,57 +313,58 @@ impl<T> AnyPass<T> {
pub fn resolve_passes<T, Tr: TreeView<T> + Sync + Send>( pub fn resolve_passes<T, Tr: TreeView<T> + Sync + Send>(
tree: &mut Tr, tree: &mut Tr,
dirty_nodes: DirtyNodeStates, dirty_nodes: DirtyNodeStates,
mut passes: Vec<&AnyPass<T>>, passes: Vec<&AnyPass<T>>,
ctx: SendAnyMap, ctx: SendAnyMap,
) -> FxDashSet<NodeId> { ) -> FxDashSet<NodeId> {
let dirty_states = Arc::new(dirty_nodes); resolve_passes_single_threaded(tree, dirty_nodes, passes, ctx)
let mut resolved_passes: FxHashSet<PassId> = FxHashSet::default(); // let dirty_states = Arc::new(dirty_nodes);
let mut resolving = Vec::new(); // let mut resolved_passes: FxHashSet<PassId> = FxHashSet::default();
let nodes_updated = Arc::new(FxDashSet::default()); // let mut resolving = Vec::new();
let ctx = Arc::new(ctx); // let nodes_updated = Arc::new(FxDashSet::default());
while !passes.is_empty() { // let ctx = Arc::new(ctx);
let mut currently_borrowed = MemberMask::default(); // while !passes.is_empty() {
std::thread::scope(|s| { // let mut currently_borrowed = MemberMask::default();
let mut i = 0; // std::thread::scope(|s| {
while i < passes.len() { // let mut i = 0;
let pass = &passes[i]; // while i < passes.len() {
let pass_id = pass.pass_id(); // let pass = &passes[i];
let pass_mask = pass.mask(); // let pass_id = pass.pass_id();
if pass // let pass_mask = pass.mask();
.dependancies() // if pass
.iter() // .dependancies()
.all(|d| resolved_passes.contains(d) || *d == pass_id) // .iter()
&& !pass_mask.overlaps(currently_borrowed) // .all(|d| resolved_passes.contains(d) || *d == pass_id)
{ // && !pass_mask.overlaps(currently_borrowed)
let pass = passes.remove(i); // {
resolving.push(pass_id); // let pass = passes.remove(i);
currently_borrowed |= pass_mask; // resolving.push(pass_id);
let tree_mut_unbounded = unsafe { &mut *(tree as *mut _ as *mut Tr) }; // currently_borrowed |= pass_mask;
let dirty_states = dirty_states.clone(); // let dirty_states = dirty_states.clone();
let nodes_updated = nodes_updated.clone(); // let nodes_updated = nodes_updated.clone();
let ctx = ctx.clone(); // let ctx = ctx.clone();
s.spawn(move || { // let mut dirty = DirtyNodes::default();
// this is safe because the member_mask acts as a per-member mutex and we have verified that the pass does not overlap with any other pass // // dirty_states.all_dirty(pass_id, &mut dirty, tree);
let mut dirty = DirtyNodes::default(); // // this is safe because the member_mask acts as a per-member mutex and we have verified that the pass does not overlap with any other pass
dirty_states.all_dirty(pass_id, &mut dirty, tree_mut_unbounded); // let tree_mut_unbounded = unsafe { &mut *(tree as *mut Tr) };
pass.resolve( // s.spawn(move || {
tree_mut_unbounded, // pass.resolve(
dirty, // tree_mut_unbounded,
&dirty_states, // dirty,
&nodes_updated, // &dirty_states,
&ctx, // &nodes_updated,
); // &ctx,
}); // );
} else { // });
i += 1; // } else {
} // i += 1;
} // }
// all passes are resolved at the end of the scope // }
}); // // all passes are resolved at the end of the scope
resolved_passes.extend(resolving.iter().copied()); // });
resolving.clear() // resolved_passes.extend(resolving.iter().copied());
} // resolving.clear()
std::sync::Arc::try_unwrap(nodes_updated).unwrap() // }
// std::sync::Arc::try_unwrap(nodes_updated).unwrap()
} }
pub fn resolve_passes_single_threaded<T, Tr: TreeView<T>>( pub fn resolve_passes_single_threaded<T, Tr: TreeView<T>>(
+171 -236
View File
@@ -1,7 +1,6 @@
use core::panic; use core::panic;
use parking_lot::lock_api::RawMutex as _; use parking_lot::lock_api::RawMutex as _;
use parking_lot::{RawMutex, RwLock}; use parking_lot::{RawMutex, RwLock};
use slab::Slab;
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::marker::PhantomData; use std::marker::PhantomData;
@@ -93,17 +92,7 @@ pub trait TreeView<T>: Sized {
fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>>; fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>>;
fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)> { fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)>;
let mut_ptr: *mut Self = self;
unsafe {
// Safety: No node has itself as a child.
(*mut_ptr).get_mut(id).and_then(|parent| {
(*mut_ptr)
.children_mut(id)
.map(|children| (parent, children))
})
}
}
fn children_ids(&self, id: NodeId) -> Option<&[NodeId]>; fn children_ids(&self, id: NodeId) -> Option<&[NodeId]>;
@@ -117,14 +106,6 @@ pub trait TreeView<T>: Sized {
fn height(&self, id: NodeId) -> Option<u16>; fn height(&self, id: NodeId) -> Option<u16>;
fn map<T2, F: Fn(&T) -> &T2, FMut: Fn(&mut T) -> &mut T2>(
&mut self,
map: F,
map_mut: FMut,
) -> TreeMap<T, T2, Self, F, FMut> {
TreeMap::new(self, map, map_mut)
}
fn size(&self) -> usize; fn size(&self) -> usize;
fn traverse_depth_first(&self, mut f: impl FnMut(&T)) { fn traverse_depth_first(&self, mut f: impl FnMut(&T)) {
@@ -200,56 +181,39 @@ pub trait TreeLike<T>: TreeView<T> {
fn insert_after(&mut self, id: NodeId, new: NodeId); fn insert_after(&mut self, id: NodeId, new: NodeId);
} }
pub struct ChildNodeIterator<'a, T, Tr: TreeView<T>> { pub struct ChildNodeIterator<'a, T> {
tree: &'a Tr, nodes: &'a Slab<Node<T>>,
children_ids: &'a [NodeId], children_ids: Vec<NodeId>,
index: usize, index: usize,
node_type: PhantomData<T>, node_type: PhantomData<T>,
} }
impl<'a, T: 'a, Tr: TreeView<T>> Iterator for ChildNodeIterator<'a, T, Tr> { impl<'a, T: 'a> Iterator for ChildNodeIterator<'a, T> {
type Item = &'a T; type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.children_ids.get(self.index).map(|id| { self.children_ids.get(self.index).map(|id| {
self.index += 1; self.index += 1;
self.tree.get_unchecked(*id) &self.nodes.get(id.0).unwrap().value
}) })
} }
} }
pub struct ChildNodeIteratorMut<'a, T, Tr: TreeView<T> + 'a> { pub struct ChildNodeIteratorMut<'a, T> {
tree: *mut Tr, nodes: Vec<&'a mut Node<T>>,
children_ids: &'a [NodeId],
index: usize,
node_type: PhantomData<T>,
} }
impl<'a, T, Tr: TreeView<T>> ChildNodeIteratorMut<'a, T, Tr> { impl<'a, T: 'a> Iterator for ChildNodeIteratorMut<'a, T> {
fn tree_mut(&mut self) -> &'a mut Tr {
unsafe { &mut *self.tree }
}
}
impl<'a, T: 'a, Tr: TreeView<T>> Iterator for ChildNodeIteratorMut<'a, T, Tr> {
type Item = &'a mut T; type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let owned = self.children_ids.get(self.index).copied(); self.nodes.pop().map(|node| &mut node.value)
match owned {
Some(id) => {
self.index += 1;
Some(self.tree_mut().get_mut_unchecked(id))
}
None => None,
}
} }
} }
impl<T> TreeView<T> for Tree<T> { impl<T> TreeView<T> for Tree<T> {
type Iterator<'a> = ChildNodeIterator<'a, T, Tree<T>> where T: 'a; type Iterator<'a> = ChildNodeIterator<'a, T> where T: 'a;
type IteratorMut<'a> = ChildNodeIteratorMut<'a, T, Tree<T>> where T: 'a; type IteratorMut<'a> = ChildNodeIteratorMut<'a, T> where T: 'a;
fn root(&self) -> NodeId { fn root(&self) -> NodeId {
self.root self.root
@@ -265,24 +229,26 @@ impl<T> TreeView<T> for Tree<T> {
fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> { fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
self.children_ids(id).map(|children_ids| ChildNodeIterator { self.children_ids(id).map(|children_ids| ChildNodeIterator {
tree: self, nodes: &self.nodes,
children_ids, children_ids: children_ids.to_vec(),
index: 0, index: 0,
node_type: PhantomData, node_type: PhantomData,
}) })
} }
fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> { fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
let raw_ptr = self as *mut Self; // Safety: No node has itself as a parent.
unsafe { if let Some(children_ids) = self.children_ids(id) {
// Safety: No node will appear as a child twice let children_ids = children_ids.to_vec();
self.children_ids(id) Some(ChildNodeIteratorMut {
.map(|children_ids| ChildNodeIteratorMut { nodes: unsafe {
tree: &mut *raw_ptr, self.nodes
children_ids, .get_many_mut_unchecked(children_ids.into_iter().rev().map(|id| id.0))
index: 0, .unwrap()
node_type: PhantomData, },
}) })
} else {
None
} }
} }
@@ -340,6 +306,30 @@ impl<T> TreeView<T> for Tree<T> {
self.nodes.get_mut(id.0).map(|node| (&mut node.value, None)) self.nodes.get_mut(id.0).map(|node| (&mut node.value, None))
} }
} }
fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)> {
// Safety: No node will appear as a child twice
if let Some(children_ids) = self.children_ids(id) {
println!("parent_child_mut: {:?}\n{:?}", id, children_ids);
debug_assert!(!children_ids.iter().any(|child_id| *child_id == id));
let mut borrowed = unsafe {
self.nodes
.get_many_mut_unchecked(
children_ids
.to_vec()
.into_iter()
.rev()
.map(|id| id.0)
.chain(std::iter::once(id.0)),
)
.unwrap()
};
let node = &mut borrowed.pop().unwrap().value;
Some((node, ChildNodeIteratorMut { nodes: borrowed }))
} else {
None
}
}
} }
impl<T> TreeLike<T> for Tree<T> { impl<T> TreeLike<T> for Tree<T> {
@@ -435,129 +425,6 @@ impl<T> TreeLike<T> for Tree<T> {
self.set_height(new, height); self.set_height(new, height);
} }
} }
pub struct TreeMap<'a, T1, T2, Tr, F, FMut>
where
Tr: TreeView<T1>,
F: Fn(&T1) -> &T2,
FMut: Fn(&mut T1) -> &mut T2,
{
tree: &'a mut Tr,
map: F,
map_mut: FMut,
in_node_type: PhantomData<T1>,
out_node_type: PhantomData<T2>,
}
impl<'a, T1, T2, Tr, F, FMut> TreeMap<'a, T1, T2, Tr, F, FMut>
where
Tr: TreeView<T1>,
F: Fn(&T1) -> &T2,
FMut: Fn(&mut T1) -> &mut T2,
{
pub fn new(tree: &'a mut Tr, map: F, map_mut: FMut) -> Self {
TreeMap {
tree,
map,
map_mut,
in_node_type: PhantomData,
out_node_type: PhantomData,
}
}
}
impl<'a, T1, T2, Tr, F, FMut> TreeView<T2> for TreeMap<'a, T1, T2, Tr, F, FMut>
where
Tr: TreeView<T1>,
F: Fn(&T1) -> &T2,
FMut: Fn(&mut T1) -> &mut T2,
{
type Iterator<'b> = ChildNodeIterator<'b, T2, TreeMap<'a, T1, T2, Tr, F, FMut>>
where
T2: 'b,
Self:'b;
type IteratorMut<'b> = ChildNodeIteratorMut<'b, T2, TreeMap<'a, T1, T2, Tr, F, FMut>>
where
T2: 'b,
Self:'b;
fn root(&self) -> NodeId {
self.tree.root()
}
fn get(&self, id: NodeId) -> Option<&T2> {
self.tree.get(id).map(|node| (self.map)(node))
}
fn get_mut(&mut self, id: NodeId) -> Option<&mut T2> {
self.tree.get_mut(id).map(|node| (self.map_mut)(node))
}
fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
self.children_ids(id).map(|children_ids| ChildNodeIterator {
tree: self,
children_ids,
index: 0,
node_type: PhantomData,
})
}
fn children_mut(&mut self, id: NodeId) -> Option<Self::IteratorMut<'_>> {
let raw_ptr = self as *mut Self;
unsafe {
// Safety: No node can be a child twice.
self.children_ids(id)
.map(|children_ids| ChildNodeIteratorMut {
tree: &mut *raw_ptr,
children_ids,
index: 0,
node_type: PhantomData,
})
}
}
fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
self.tree.children_ids(id)
}
fn parent(&self, id: NodeId) -> Option<&T2> {
self.tree.parent(id).map(|node| (self.map)(node))
}
fn parent_mut(&mut self, id: NodeId) -> Option<&mut T2> {
self.tree.parent_mut(id).map(|node| (self.map_mut)(node))
}
fn parent_id(&self, id: NodeId) -> Option<NodeId> {
self.tree.parent_id(id)
}
fn height(&self, id: NodeId) -> Option<u16> {
self.tree.height(id)
}
fn get_unchecked(&self, id: NodeId) -> &T2 {
(self.map)(self.tree.get_unchecked(id))
}
fn get_mut_unchecked(&mut self, id: NodeId) -> &mut T2 {
(self.map_mut)(self.tree.get_mut_unchecked(id))
}
fn size(&self) -> usize {
self.tree.size()
}
fn node_parent_mut(&mut self, id: NodeId) -> Option<(&mut T2, Option<&mut T2>)> {
self.tree.node_parent_mut(id).map(|(node, parent)| {
(
(self.map_mut)(node),
parent.map(|parent| (self.map_mut)(parent)),
)
})
}
}
#[test] #[test]
fn creation() { fn creation() {
let mut tree = Tree::new(1); let mut tree = Tree::new(1);
@@ -666,59 +533,6 @@ fn deletion() {
assert_eq!(tree.children_ids(parent).unwrap(), &[]); assert_eq!(tree.children_ids(parent).unwrap(), &[]);
} }
#[test]
fn shared_view() {
use std::thread;
let mut tree = Tree::new(1);
let parent = tree.root();
let child = tree.create_node(0);
tree.add_child(parent, child);
let shared = SharedView::new(&mut tree);
thread::scope(|s| {
let (mut shared1, mut shared2, mut shared3) =
(shared.clone(), shared.clone(), shared.clone());
s.spawn(move || {
assert_eq!(*shared1.get_mut(parent).unwrap(), 1);
assert_eq!(*shared1.get_mut(child).unwrap(), 0);
});
s.spawn(move || {
assert_eq!(*shared2.get_mut(child).unwrap(), 0);
assert_eq!(*shared2.get_mut(parent).unwrap(), 1);
});
s.spawn(move || {
assert_eq!(*shared3.get_mut(parent).unwrap(), 1);
assert_eq!(*shared3.get_mut(child).unwrap(), 0);
});
});
}
#[test]
fn map() {
#[derive(Debug, PartialEq)]
struct Value {
value: i32,
}
impl Value {
fn new(value: i32) -> Self {
Self { value }
}
}
let mut tree = Tree::new(Value::new(1));
let parent = tree.root();
let child = tree.create_node(Value::new(0));
tree.add_child(parent, child);
let mut mapped = tree.map(|x| &x.value, |x| &mut x.value);
*mapped.get_mut(child).unwrap() = 1;
*mapped.get_mut(parent).unwrap() = 2;
assert_eq!(*tree.get(parent).unwrap(), Value::new(2));
assert_eq!(*tree.get(child).unwrap(), Value::new(1));
}
#[test] #[test]
fn traverse_depth_first() { fn traverse_depth_first() {
let mut tree = Tree::new(0); let mut tree = Tree::new(0);
@@ -738,3 +552,124 @@ fn traverse_depth_first() {
node_count += 1; node_count += 1;
}); });
} }
#[test]
fn get_node_children_mut() {
let mut tree = Tree::new(0);
let parent = tree.root();
let child1 = tree.create_node(1);
tree.add_child(parent, child1);
let child2 = tree.create_node(2);
tree.add_child(parent, child2);
let child3 = tree.create_node(3);
tree.add_child(parent, child3);
let (parent, children) = tree.parent_child_mut(parent).unwrap();
for (i, child) in children.enumerate() {
assert_eq!(*child, i + 1);
}
println!("Parent: {:#?}", parent);
}
#[test]
fn get_many_mut_unchecked() {
let mut slab = Slab::new();
let parent = slab.insert(0);
let child = slab.insert(1);
let grandchild = slab.insert(2);
let all =
unsafe { slab.get_many_mut_unchecked([parent, child, grandchild].into_iter()) }.unwrap();
println!("All: {:#?}", all);
}
#[derive(Debug)]
struct Slab<T> {
data: Vec<Option<T>>,
free: VecDeque<usize>,
}
impl<T> Default for Slab<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Slab<T> {
fn new() -> Self {
Self {
data: Vec::new(),
free: VecDeque::new(),
}
}
fn get(&self, id: usize) -> Option<&T> {
self.data.get(id).and_then(|x| x.as_ref())
}
unsafe fn get_unchecked(&self, id: usize) -> &T {
self.data.get_unchecked(id).as_ref().unwrap()
}
fn get_mut(&mut self, id: usize) -> Option<&mut T> {
self.data.get_mut(id).and_then(|x| x.as_mut())
}
unsafe fn get_unchecked_mut(&mut self, id: usize) -> &mut T {
self.data.get_unchecked_mut(id).as_mut().unwrap()
}
fn get2_mut(&mut self, id1: usize, id2: usize) -> Option<(&mut T, &mut T)> {
assert!(id1 != id2);
let ptr = self.data.as_mut_ptr();
let first = unsafe { &mut *ptr.add(id1) };
let second = unsafe { &mut *ptr.add(id2) };
if let (Some(first), Some(second)) = (first, second) {
Some((first, second))
} else {
None
}
}
unsafe fn get_many_mut_unchecked(
&mut self,
ids: impl Iterator<Item = usize>,
) -> Option<Vec<&mut T>> {
let ptr = self.data.as_mut_ptr();
let mut result = Vec::new();
for id in ids {
let item = unsafe { &mut *ptr.add(id) };
if let Some(item) = item {
result.push(item);
} else {
return None;
}
}
Some(result)
}
fn insert(&mut self, value: T) -> usize {
if let Some(id) = self.free.pop_front() {
self.data[id] = Some(value);
id
} else {
self.data.push(Some(value));
self.data.len() - 1
}
}
fn try_remove(&mut self, id: usize) -> Option<T> {
self.data.get_mut(id).and_then(|x| {
self.free.push_back(id);
x.take()
})
}
fn remove(&mut self, id: usize) -> T {
self.try_remove(id).unwrap()
}
fn len(&self) -> usize {
self.data.len() - self.free.len()
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ futures = "0.3.19"
taffy = "0.2.1" taffy = "0.2.1"
smallvec = "1.6" smallvec = "1.6"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
anymap = "0.12.1" anymap = "1.0.0-beta.2"
futures-channel = "0.3.25" futures-channel = "0.3.25"
[dev-dependencies] [dev-dependencies]