tests and stuff
This commit is contained in:
parent
8f753108ec
commit
bc57d221bc
|
@ -15,6 +15,9 @@ never-local = []
|
||||||
[profile.bench]
|
[profile.bench]
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
@ -39,4 +42,5 @@ parking_lot_core = "0.9.10"
|
||||||
# derive_more = "1.0.0"
|
# derive_more = "1.0.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
async-std = "1.13.0"
|
||||||
tracing-test = "0.2.5"
|
tracing-test = "0.2.5"
|
||||||
|
|
|
@ -1077,6 +1077,81 @@ impl Scope {
|
||||||
self.execute(job);
|
self.execute(job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn<'a, F>(&self, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&Scope) + Send + 'a,
|
||||||
|
{
|
||||||
|
self.job_counter.increment();
|
||||||
|
|
||||||
|
let this = unsafe {
|
||||||
|
SendPtr::new_unchecked(&self.job_counter as *const JobCounter as *mut JobCounter)
|
||||||
|
};
|
||||||
|
|
||||||
|
let job = HeapJob::new(move |scope: &Scope| unsafe {
|
||||||
|
f(scope);
|
||||||
|
this.as_ref().decrement();
|
||||||
|
})
|
||||||
|
.into_boxed_job();
|
||||||
|
|
||||||
|
self.push_front(Pin::as_ref(&job));
|
||||||
|
mem::forget(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_future<'a, T, F>(&'a self, future: F) -> async_task::Task<T>
|
||||||
|
where
|
||||||
|
F: Future<Output = T> + Send + 'a,
|
||||||
|
T: Send + 'a,
|
||||||
|
{
|
||||||
|
self.job_counter.increment();
|
||||||
|
|
||||||
|
let this =
|
||||||
|
unsafe { SendPtr::new_unchecked(&raw const self.job_counter as *mut JobCounter) };
|
||||||
|
|
||||||
|
let future = async move {
|
||||||
|
let _guard = DropGuard::new(move || unsafe {
|
||||||
|
this.as_ref().decrement();
|
||||||
|
});
|
||||||
|
future.await
|
||||||
|
};
|
||||||
|
|
||||||
|
let this = SendPtr::new(&raw const *self as *mut Self).unwrap();
|
||||||
|
let schedule = move |runnable: Runnable| {
|
||||||
|
unsafe fn harness<T>(this: *const (), job: *const Job<T>, _: &Scope) {
|
||||||
|
let runnable = Runnable::<()>::from_raw(NonNull::new_unchecked(this.cast_mut()));
|
||||||
|
runnable.run();
|
||||||
|
|
||||||
|
drop(Box::from_raw(job.cast_mut()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let job = Box::pin(Job::<T>::new(harness::<T>, runnable.into_raw()));
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
this.as_ref().push_front(job.as_ref());
|
||||||
|
}
|
||||||
|
mem::forget(job);
|
||||||
|
};
|
||||||
|
|
||||||
|
let (runnable, task) = unsafe { async_task::spawn_unchecked(future, schedule) };
|
||||||
|
|
||||||
|
runnable.schedule();
|
||||||
|
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn spawn_async<'a, T, Fut, Fn>(&'a self, f: Fn) -> async_task::Task<T>
|
||||||
|
where
|
||||||
|
Fn: FnOnce(&Scope) -> Fut + Send + 'static,
|
||||||
|
Fut: Future<Output = T> + Send + 'static,
|
||||||
|
T: Send + 'static,
|
||||||
|
{
|
||||||
|
let this = SendPtr::new(self as *const Self as *mut Self).unwrap();
|
||||||
|
let future = async move { f(unsafe { this.as_ref() }).await };
|
||||||
|
|
||||||
|
self.spawn_future(future)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn join<A, B, RA, RB>(&self, a: A, b: B) -> (RA, RB)
|
pub fn join<A, B, RA, RB>(&self, a: A, b: B) -> (RA, RB)
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::pin::Pin;
|
use std::{mem::MaybeUninit, pin::Pin};
|
||||||
|
|
||||||
use super::{util::TaggedAtomicPtr, *};
|
use super::{util::TaggedAtomicPtr, *};
|
||||||
|
|
||||||
|
@ -315,3 +315,134 @@ fn value_boxed_drop() {
|
||||||
}
|
}
|
||||||
assert_eq!(dropped, 2);
|
assert_eq!(dropped, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn job_list_pop_front_empty() {
|
||||||
|
let mut list = JobList::new();
|
||||||
|
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn job_list_pop_back_empty() {
|
||||||
|
let mut list = JobList::new();
|
||||||
|
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn job_list_pop_back_emptied() {
|
||||||
|
let mut list = JobList::new();
|
||||||
|
let a = pin!(Job::<()>::empty());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
list.push_front(a.as_ref());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(list.pop_back(), Some(pin_ptr(&a)));
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
assert_eq!(list.pop_back(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn job_list_pop_front_emptied() {
|
||||||
|
let mut list = JobList::new();
|
||||||
|
let a = pin!(Job::<()>::empty());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
list.push_front(a.as_ref());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(list.pop_front(), Some(pin_ptr(&a)));
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
assert_eq!(list.pop_front(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spawn() {
|
||||||
|
let pool = ThreadPool::new();
|
||||||
|
|
||||||
|
let mut x = 0;
|
||||||
|
pool.scope(|s| {
|
||||||
|
s.spawn(|_| {
|
||||||
|
x += 1;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
eprintln!("x: {x}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spawn_borrow() {
|
||||||
|
let pool = ThreadPool::new();
|
||||||
|
|
||||||
|
pool.scope(|s| {
|
||||||
|
let mut x = 0;
|
||||||
|
s.spawn(|_| {
|
||||||
|
x += 1;
|
||||||
|
assert_eq!(x, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spawn_future() {
|
||||||
|
let pool = ThreadPool::new();
|
||||||
|
|
||||||
|
let task = pool.scope(|s| {
|
||||||
|
let task = s.spawn_future(async {
|
||||||
|
eprintln!("executing future");
|
||||||
|
3 + 1
|
||||||
|
});
|
||||||
|
|
||||||
|
// let task = s.spawn_future(async {
|
||||||
|
// eprintln!("task: {}", task.await);
|
||||||
|
// });
|
||||||
|
task
|
||||||
|
});
|
||||||
|
let x = async_std::task::block_on(task);
|
||||||
|
eprintln!("x: {x}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn join() {
|
||||||
|
let pool = ThreadPool::new();
|
||||||
|
|
||||||
|
let x = pool.scope(|s| {
|
||||||
|
let (a, b) = s.join(|_| 3, |_| 4);
|
||||||
|
|
||||||
|
a + b
|
||||||
|
});
|
||||||
|
|
||||||
|
eprintln!("x: {x}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rebox() {
|
||||||
|
struct A(u32);
|
||||||
|
|
||||||
|
impl Drop for A {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
eprintln!("drop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ptr = Box::into_raw(Box::new(A(5)));
|
||||||
|
|
||||||
|
let x = unsafe { &*ptr.offset(mem::offset_of!(A, 0) as isize).cast::<u32>() };
|
||||||
|
let y = *x;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ptr.drop_in_place();
|
||||||
|
_ = Box::<MaybeUninit<A>>::from_raw(ptr.cast());
|
||||||
|
}
|
||||||
|
assert_eq!(y, 5);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue