linked-listed job queue executor stuff

This commit is contained in:
Janis 2025-02-20 15:20:46 +01:00
parent 5547bf7df7
commit 5cd7f43f45
4 changed files with 1349 additions and 1 deletions

View file

@ -102,7 +102,35 @@ fn join_melange(b: &mut Bencher) {
} }
b.iter(move || { b.iter(move || {
assert_ne!(sum(&tree, tree.root().unwrap(), &mut scope), 0); let sum = sum(&tree, tree.root().unwrap(), &mut scope);
//eprintln!("{sum}");
assert_ne!(sum, 0);
});
}
#[bench]
fn join_praetor(b: &mut Bencher) {
use executor::praetor::Scope;
let pool = executor::praetor::ThreadPool::new();
let tree = tree::Tree::new(TREE_SIZE, 1u32);
fn sum(tree: &tree::Tree<u32>, node: usize) -> u32 {
let node = tree.get(node);
Scope::with(|s| {
let (l, r) = s.join(
|| node.left.map(|node| sum(tree, node)).unwrap_or_default(),
|| node.right.map(|node| sum(tree, node)).unwrap_or_default(),
);
node.leaf + l + r
})
}
b.iter(move || {
let sum = pool.scope(|_| sum(&tree, tree.root().unwrap()));
// eprintln!("{sum}");
assert_ne!(sum, 0);
}); });
} }

View file

@ -387,6 +387,7 @@ pub mod latch {
} }
pub mod melange; pub mod melange;
pub mod praetor;
pub struct ThreadPoolState { pub struct ThreadPoolState {
num_threads: AtomicUsize, num_threads: AtomicUsize,

1141
src/praetor/mod.rs Normal file

File diff suppressed because it is too large Load diff

178
src/praetor/tests.rs Normal file
View file

@ -0,0 +1,178 @@
use std::pin::Pin;
use super::{util::TaggedAtomicPtr, *};
#[test]
fn job_list_pop_back() {
let mut list = JobList::new();
let mut a = Job::empty();
let mut b = Job::empty();
let mut c = Job::empty();
unsafe {
list.push_front(&a);
list.push_front(&b);
list.push_back(&c);
}
assert_eq!(list.pop_back(), NonNull::new(&mut c));
unsafe {
list.push_front(&c);
}
assert_eq!(list.pop_back(), NonNull::new(&mut a));
assert_eq!(list.pop_back(), NonNull::new(&mut b));
assert_eq!(list.pop_back(), NonNull::new(&mut c));
assert_eq!(list.pop_back(), None);
assert_eq!(list.pop_front(), None);
}
#[test]
fn job_list_pop_front() {
let mut list = JobList::new();
let mut a = Job::empty();
let mut b = Job::empty();
let mut c = Job::empty();
unsafe {
list.push_front(&a);
list.push_front(&b);
list.push_back(&c);
}
assert_eq!(list.pop_front(), NonNull::new(&mut b));
unsafe {
list.push_back(&b);
}
assert_eq!(list.pop_front(), NonNull::new(&mut a));
assert_eq!(list.pop_front(), NonNull::new(&mut c));
assert_eq!(list.pop_front(), NonNull::new(&mut b));
assert_eq!(list.pop_front(), None);
assert_eq!(list.pop_back(), None);
}
#[test]
fn unlink_job_middle() {
let mut list = JobList::new();
let mut a = Job::empty();
let b = Job::<()>::empty();
let mut c = Job::empty();
unsafe {
list.push_front(&a);
list.push_front(&b);
list.push_front(&c);
}
unsafe {
b.unlink();
}
assert_eq!(list.pop_front(), NonNull::new(&mut c));
assert_eq!(list.pop_front(), NonNull::new(&mut a));
assert_eq!(list.pop_front(), None);
assert_eq!(list.pop_back(), None);
}
#[test]
fn unlink_job_front() {
let mut list = JobList::new();
let a = Job::<()>::empty();
let mut b = Job::<()>::empty();
let mut c = Job::<()>::empty();
unsafe {
list.push_front(&a);
list.push_front(&b);
list.push_front(&c);
}
unsafe {
a.unlink();
}
assert_eq!(list.pop_front(), NonNull::new(&mut c));
assert_eq!(list.pop_front(), NonNull::new(&mut b));
assert_eq!(list.pop_front(), None);
assert_eq!(list.pop_back(), None);
}
#[test]
fn unlink_job_back() {
let mut list = JobList::new();
let mut a = Job::<()>::empty();
let mut b = Job::<()>::empty();
let c = Job::<()>::empty();
unsafe {
list.push_front(&a);
list.push_front(&b);
list.push_front(&c);
}
unsafe {
c.unlink();
}
assert_eq!(list.pop_front(), NonNull::new(&mut b));
assert_eq!(list.pop_front(), NonNull::new(&mut a));
assert_eq!(list.pop_front(), None);
assert_eq!(list.pop_back(), None);
}
#[test]
fn unlink_job_single() {
let mut list = JobList::new();
let a = Job::<()>::empty();
unsafe {
list.push_front(&a);
}
unsafe {
a.unlink();
}
assert_eq!(list.pop_front(), None);
assert_eq!(list.pop_back(), None);
}
#[test]
fn tagged_ptr_exchange() {
let boxed = Box::into_raw(Box::new(42usize));
let ptr = TaggedAtomicPtr::<_, 3>::new(boxed, 1usize);
assert_eq!(ptr.tag(Ordering::Relaxed), 1);
assert_eq!(ptr.ptr(Ordering::Relaxed).as_ptr(), boxed);
ptr.set_tag(3, Ordering::Release, Ordering::Relaxed);
assert_eq!(ptr.tag(Ordering::Relaxed), 3);
assert_eq!(ptr.ptr(Ordering::Relaxed).as_ptr(), boxed);
let old = ptr.compare_exchange_weak_tag(3, 4, Ordering::Release, Ordering::Relaxed);
assert_eq!(old, Ok(3));
assert_eq!(ptr.tag(Ordering::Relaxed), 4);
assert_eq!(ptr.ptr(Ordering::Relaxed).as_ptr(), boxed);
}
#[test]
fn tagged_ptr_exchange_failure() {
let boxed = Box::into_raw(Box::new(42usize));
let ptr = TaggedAtomicPtr::<_, 3>::new(boxed, 1usize);
assert_eq!(ptr.tag(Ordering::Relaxed), 1);
assert_eq!(ptr.ptr(Ordering::Relaxed).as_ptr(), boxed);
let old = ptr.compare_exchange_weak_tag(3, 4, Ordering::Release, Ordering::Relaxed);
assert_eq!(old, Err(1));
assert_eq!(ptr.tag(Ordering::Relaxed), 1);
assert_eq!(ptr.ptr(Ordering::Relaxed).as_ptr(), boxed);
}
fn pinstuff() {
let pinned = pin!(5);
let b = pinned.as_ref();
let a = takes_pinned_ref(pinned.as_ref());
}
fn takes_pinned_ref(r: Pin<&i32>) -> i32 {
*r
}