```toml
# default = ["tick_event", "timer_registration"]
# default = ["channel-flume", "tick_event", "timer_registration"]
# channel-flume = []
dhat = { version = "0.3" }
```
```rust
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
pub struct DhatTester {
name: &'static str,
profiler: Option<dhat::Profiler>,
}
impl DhatTester {
pub fn new(_name: &'static str) -> Self {
let this = Self::new_dhat(_name);
this
}
pub fn stats(_stats_cb: impl FnOnce(dhat::HeapStats)) {
{
let stats = dhat::HeapStats::get();
_stats_cb(stats);
}
}
fn new_dhat(name: &'static str) -> Self {
const DHAT_TEST_DIR: &str = "target/dhat";
if !std::fs::exists(DHAT_TEST_DIR).unwrap() {
let _ignore = std::fs::create_dir_all(DHAT_TEST_DIR);
}
let profiler = dhat::Profiler::builder()
.file_name(format!("{DHAT_TEST_DIR}/{name}.json"))
.build();
Self {
name,
profiler: Some(profiler),
}
}
}
impl Drop for DhatTester {
fn drop(&mut self) {
let stats = dhat::HeapStats::get();
println!("-------------");
println!("{}:\n{stats:?}", self.name);
drop(self.profiler.take().unwrap());
println!("-------------");
}
}
#[tokio::test]
async fn test_memory_for_executor() {
let mut executor = {
let _profiler = DhatTester::new("test_memory_for_executor_1");
let executor = TickedAsyncExecutor::default();
executor
};
// let rt = {
// let _profiler = DhatTester::new("test_tokio");
// let rt = tokio::runtime::Builder::new_multi_thread()
// .worker_threads(1)
// .enable_all()
// .build()
// .unwrap();
// rt
// };
{
let _profiler = DhatTester::new("test_tokio_spawn");
// let handle = rt.spawn(async move {});
let _handle = tokio::spawn(async move {
for i in 0..1000000 {
println!("I: {i}");
}
});
// let _r = handle.await;
}
{
let _profiler = DhatTester::new("test_memory_types");
// let _a = std::rc::Rc::new(10);
let _a = 10;
// let _b = std::sync::Arc::new(10);
}
let (tx, mut rx) = {
// oneshot: 72
// watch: 344
// mpsc: 800
// broadcast: 176
let _profiler = DhatTester::new("test_memory_for_executor_channel");
// let (tx, rx) = tokio::sync::oneshot::channel::<usize>();
// let (tx, rx) = tokio::sync::watch::channel::<usize>(1);
// let (tx, rx) = tokio::sync::mpsc::channel::<usize>(1);
let (tx, rx) = tokio::sync::broadcast::channel::<usize>(1);
(tx, rx)
};
{
let _profiler = DhatTester::new("test_memory_for_executor_2");
executor
.spawn_local("_", async move {
// let d = rx.await;
// println!("D: {d:?}");
// rx.changed().await.unwrap();
// let d = *rx.borrow_and_update();
// println!("D: {d:?}");
// rx.changed().await.unwrap();
// let d = *rx.borrow_and_update();
// println!("D: {d:?}");
let d = rx.recv().await.unwrap();
println!("D: {d:?}");
let d = rx.recv().await.unwrap();
println!("D: {d:?}");
})
.detach();
}
{
let _profiler = DhatTester::new("test_memory_for_executor_3");
executor.tick(1.0, None);
executor.tick(1.0, None);
executor.tick(1.0, None);
executor.tick(1.0, None);
assert_eq!(executor.num_tasks(), 1);
// tx.send(100).unwrap();
// tx.send_replace(100);
// tx.try_send(100).unwrap();
tx.send(100).unwrap();
executor.tick(1.0, None);
executor.tick(1.0, None);
executor.tick(1.0, None);
executor.tick(1.0, None);
assert_eq!(executor.num_tasks(), 1);
// tx.send_replace(200);
// tx.try_send(200).unwrap();
tx.send(200).unwrap();
executor.wait_till_completed(1.0);
}
}
#[test]
fn test_future() {
let (tx, rx) = tokio::sync::oneshot::channel::<usize>();
let future = async move {
let data = rx.await;
println!("Data: {data:?}");
};
let waker = std::task::Waker::noop();
let mut cx = std::task::Context::from_waker(waker);
let mut future = std::pin::pin!(future);
{
let status = future.as_mut().poll(&mut cx);
assert_eq!(status, std::task::Poll::Pending);
}
{
let status = future.as_mut().poll(&mut cx);
assert_eq!(status, std::task::Poll::Pending);
}
{
let _r = tx.send(1000).unwrap();
let status = future.as_mut().poll(&mut cx);
assert_eq!(status, std::task::Poll::Ready(()));
}
}
// #[test]
// fn test_offload() {
// {
// let _profiler = DhatTester::new("test_thread_scope");
// std::thread::scope(|s| {
// s.spawn(|| {});
// });
// }
// {
// let _profiler = DhatTester::new("test_thread_scope2");
// std::thread::scope(|s| {});
// }
// let runtime = tokio::runtime::Builder::new_multi_thread()
// .worker_threads(1)
// .enable_all()
// .build()
// .unwrap();
// {
// let _profiler = DhatTester::new("test_thread_scope3");
// let h = runtime.spawn(async move {
// println!("OK");
// });
// while !h.is_finished() {}
// // runtime.spawn_blocking(|| async move { println!("OK") });
// }
// // let alloc = bumpalo::Bump::new();
// // let future = alloc.alloc(async move {});
// // let f = std::pin::pin!(future);
// // f.as_mut().poll();
// // std::pin::pin!(future).as_mut().poll();
// }
```