File tree 5 files changed +275
-21
lines changed
5 files changed +275
-21
lines changed Original file line number Diff line number Diff line change 6
6
target_os = "linux" ,
7
7
any( target_arch = "aarch64" , target_arch = "x86" , target_arch = "x86_64" )
8
8
) ) ]
9
- #[ tokio:: main( flavor = "current_thread" ) ]
9
+ #[ tokio:: main( worker_threads = 72 ) ]
10
10
async fn main ( ) {
11
+ println ! ( "pid={}" , std:: process:: id( ) ) ;
12
+
11
13
use std:: hint:: black_box;
12
14
13
15
#[ inline( never) ]
@@ -22,21 +24,29 @@ async fn main() {
22
24
23
25
#[ inline( never) ]
24
26
async fn c ( ) {
25
- black_box ( tokio:: task:: yield_now ( ) ) . await
27
+ loop {
28
+ tokio:: task:: yield_now ( ) . await ;
29
+ }
26
30
}
27
31
28
- tokio:: spawn ( a ( ) ) ;
29
- tokio:: spawn ( b ( ) ) ;
30
- tokio:: spawn ( c ( ) ) ;
31
-
32
- let handle = tokio:: runtime:: Handle :: current ( ) ;
33
- let dump = handle. dump ( ) ;
32
+ async fn dump ( ) {
33
+ let handle = tokio:: runtime:: Handle :: current ( ) ;
34
+ let dump = handle. dump ( ) . await ;
34
35
35
- for ( i, task) in dump. tasks ( ) . iter ( ) . enumerate ( ) {
36
- let trace = task. trace ( ) ;
37
- println ! ( "task {i} trace:" ) ;
38
- println ! ( "{trace}" ) ;
36
+ for ( i, task) in dump. tasks ( ) . iter ( ) . enumerate ( ) {
37
+ let trace = task. trace ( ) ;
38
+ println ! ( "task {i} trace:" ) ;
39
+ println ! ( "{trace}" ) ;
40
+ }
39
41
}
42
+
43
+ tokio:: select!(
44
+ biased;
45
+ _ = tokio:: spawn( a( ) ) => { } ,
46
+ _ = dump( ) => { } ,
47
+ ) ;
48
+
49
+ println ! ( "END OF MAIN" ) ;
40
50
}
41
51
42
52
#[ cfg( not( all(
Original file line number Diff line number Diff line change @@ -341,12 +341,20 @@ cfg_metrics! {
341
341
cfg_taskdump ! {
342
342
impl Handle {
343
343
/// Capture a snapshot of this runtime's state.
344
- pub fn dump( & self ) -> crate :: runtime:: Dump {
344
+ pub async fn dump( & self ) -> crate :: runtime:: Dump {
345
345
match & self . inner {
346
346
scheduler:: Handle :: CurrentThread ( handle) => handle. dump( ) ,
347
347
#[ cfg( all( feature = "rt-multi-thread" , not( tokio_wasi) ) ) ]
348
- scheduler:: Handle :: MultiThread ( _) =>
349
- unimplemented!( "taskdumps are unsupported on the multi-thread runtime" ) ,
348
+ scheduler:: Handle :: MultiThread ( handle) => {
349
+ // perform the trace in a separate thread
350
+ let handle = handle. clone( ) ;
351
+ let ( tx, rx) = crate :: sync:: oneshot:: channel( ) ;
352
+ crate :: loom:: thread:: spawn( || {
353
+ let handle = handle;
354
+ tx. send( handle. dump( ) ) . unwrap( ) ;
355
+ } ) ;
356
+ rx. await . unwrap( )
357
+ } ,
350
358
}
351
359
}
352
360
}
Original file line number Diff line number Diff line change @@ -95,6 +95,37 @@ cfg_metrics! {
95
95
}
96
96
}
97
97
98
+ cfg_taskdump ! {
99
+ impl Handle {
100
+ pub ( crate ) fn dump( & self ) -> crate :: runtime:: Dump {
101
+ let trace_status = & self . shared. trace_status;
102
+
103
+ println!( "{:?} Handle::dump: trace requested; waiting for pending dump requests to complete" , std:: thread:: current( ) . id( ) ) ;
104
+
105
+ // If a dump is in progress, block.
106
+ trace_status. start_trace_request( & self ) ;
107
+
108
+ println!( "{:?} Handle::dump: no pending dump requests; waiting for result for this request" , std:: thread:: current( ) . id( ) ) ;
109
+
110
+ let result = loop {
111
+ if let Some ( result) = trace_status. take_result( ) {
112
+ break result;
113
+ } else {
114
+ self . notify_all( ) ;
115
+ crate :: loom:: thread:: yield_now( ) ;
116
+ }
117
+ } ;
118
+
119
+ println!( "{:?} Handle::dump: result received; allowing other dump requests to proceed" , std:: thread:: current( ) . id( ) ) ;
120
+
121
+ // Allow other queued dumps to proceed.
122
+ trace_status. end_trace_request( & self ) ;
123
+
124
+ result
125
+ }
126
+ }
127
+ }
128
+
98
129
impl fmt:: Debug for Handle {
99
130
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
100
131
fmt. debug_struct ( "multi_thread::Handle { ... }" ) . finish ( )
You can’t perform that action at this time.
0 commit comments