| #![cfg(all( |
| tokio_unstable, |
| tokio_taskdump, |
| target_os = "linux", |
| any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64") |
| ))] |
| |
| use std::hint::black_box; |
| use tokio::runtime::{self, Handle}; |
| |
| #[inline(never)] |
| async fn a() { |
| black_box(b()).await |
| } |
| |
| #[inline(never)] |
| async fn b() { |
| black_box(c()).await |
| } |
| |
| #[inline(never)] |
| async fn c() { |
| loop { |
| black_box(tokio::task::yield_now()).await |
| } |
| } |
| |
| #[test] |
| fn current_thread() { |
| let rt = runtime::Builder::new_current_thread() |
| .enable_all() |
| .build() |
| .unwrap(); |
| |
| async fn dump() { |
| let handle = Handle::current(); |
| let dump = handle.dump().await; |
| |
| let tasks: Vec<_> = dump.tasks().iter().collect(); |
| |
| assert_eq!(tasks.len(), 3); |
| |
| for task in tasks { |
| let trace = task.trace().to_string(); |
| eprintln!("\n\n{trace}\n\n"); |
| assert!(trace.contains("dump::a")); |
| assert!(trace.contains("dump::b")); |
| assert!(trace.contains("dump::c")); |
| assert!(trace.contains("tokio::task::yield_now")); |
| } |
| } |
| |
| rt.block_on(async { |
| tokio::select!( |
| biased; |
| _ = tokio::spawn(a()) => {}, |
| _ = tokio::spawn(a()) => {}, |
| _ = tokio::spawn(a()) => {}, |
| _ = dump() => {}, |
| ); |
| }); |
| } |
| |
| #[test] |
| fn multi_thread() { |
| let rt = runtime::Builder::new_multi_thread() |
| .enable_all() |
| .worker_threads(3) |
| .build() |
| .unwrap(); |
| |
| async fn dump() { |
| let handle = Handle::current(); |
| let dump = handle.dump().await; |
| |
| let tasks: Vec<_> = dump.tasks().iter().collect(); |
| |
| assert_eq!(tasks.len(), 3); |
| |
| for task in tasks { |
| let trace = task.trace().to_string(); |
| eprintln!("\n\n{trace}\n\n"); |
| assert!(trace.contains("dump::a")); |
| assert!(trace.contains("dump::b")); |
| assert!(trace.contains("dump::c")); |
| assert!(trace.contains("tokio::task::yield_now")); |
| } |
| } |
| |
| rt.block_on(async { |
| tokio::select!( |
| biased; |
| _ = tokio::spawn(a()) => {}, |
| _ = tokio::spawn(a()) => {}, |
| _ = tokio::spawn(a()) => {}, |
| _ = dump() => {}, |
| ); |
| }); |
| } |