• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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