1 #![cfg(all(
2 tokio_unstable,
3 tokio_taskdump,
4 target_os = "linux",
5 any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")
6 ))]
7
8 use std::hint::black_box;
9 use tokio::runtime::{self, Handle};
10
11 #[inline(never)]
a()12 async fn a() {
13 black_box(b()).await
14 }
15
16 #[inline(never)]
b()17 async fn b() {
18 black_box(c()).await
19 }
20
21 #[inline(never)]
c()22 async fn c() {
23 loop {
24 black_box(tokio::task::yield_now()).await
25 }
26 }
27
28 #[test]
current_thread()29 fn current_thread() {
30 let rt = runtime::Builder::new_current_thread()
31 .enable_all()
32 .build()
33 .unwrap();
34
35 async fn dump() {
36 let handle = Handle::current();
37 let dump = handle.dump().await;
38
39 let tasks: Vec<_> = dump.tasks().iter().collect();
40
41 assert_eq!(tasks.len(), 3);
42
43 for task in tasks {
44 let trace = task.trace().to_string();
45 eprintln!("\n\n{trace}\n\n");
46 assert!(trace.contains("dump::a"));
47 assert!(trace.contains("dump::b"));
48 assert!(trace.contains("dump::c"));
49 assert!(trace.contains("tokio::task::yield_now"));
50 }
51 }
52
53 rt.block_on(async {
54 tokio::select!(
55 biased;
56 _ = tokio::spawn(a()) => {},
57 _ = tokio::spawn(a()) => {},
58 _ = tokio::spawn(a()) => {},
59 _ = dump() => {},
60 );
61 });
62 }
63
64 #[test]
multi_thread()65 fn multi_thread() {
66 let rt = runtime::Builder::new_multi_thread()
67 .enable_all()
68 .worker_threads(3)
69 .build()
70 .unwrap();
71
72 async fn dump() {
73 let handle = Handle::current();
74 let dump = handle.dump().await;
75
76 let tasks: Vec<_> = dump.tasks().iter().collect();
77
78 assert_eq!(tasks.len(), 3);
79
80 for task in tasks {
81 let trace = task.trace().to_string();
82 eprintln!("\n\n{trace}\n\n");
83 assert!(trace.contains("dump::a"));
84 assert!(trace.contains("dump::b"));
85 assert!(trace.contains("dump::c"));
86 assert!(trace.contains("tokio::task::yield_now"));
87 }
88 }
89
90 rt.block_on(async {
91 tokio::select!(
92 biased;
93 _ = tokio::spawn(a()) => {},
94 _ = tokio::spawn(a()) => {},
95 _ = tokio::spawn(a()) => {},
96 _ = dump() => {},
97 );
98 });
99 }
100