5656 ( a. unwrap ( ) , b. unwrap ( ) )
5757}
5858
59- /// Runs a list of blocks in parallel. The first block is executed immediately on
60- /// the current thread. Use that for the longest running block.
61- #[ macro_export]
62- macro_rules! parallel {
63- ( impl $fblock: block [ $( $c: expr, ) * ] [ $block: expr $( , $rest: expr) * ] ) => {
64- parallel!( impl $fblock [ $block, $( $c, ) * ] [ $( $rest) ,* ] )
65- } ;
66- ( impl $fblock: block [ $( $blocks: expr, ) * ] [ ] ) => {
67- $crate:: sync:: parallel_guard( |guard| {
68- $crate:: sync:: scope( |s| {
69- $(
70- let block = $crate:: sync:: FromDyn :: from( || $blocks) ;
71- s. spawn( move |_| {
72- guard. run( move || block. into_inner( ) ( ) ) ;
73- } ) ;
74- ) *
75- guard. run( || $fblock) ;
76- } ) ;
77- } ) ;
78- } ;
79- ( $fblock: block, $( $blocks: block) ,* ) => {
80- if $crate:: sync:: is_dyn_thread_safe( ) {
81- // Reverse the order of the later blocks since Rayon executes them in reverse order
82- // when using a single thread. This ensures the execution order matches that
83- // of a single threaded rustc.
84- parallel!( impl $fblock [ ] [ $( $blocks) ,* ] ) ;
85- } else {
86- $crate:: sync:: parallel_guard( |guard| {
87- guard. run( || $fblock) ;
88- $( guard. run( || $blocks) ; ) *
89- } ) ;
90- }
91- } ;
92- }
93-
9459pub fn spawn ( func : impl FnOnce ( ) + DynSend + ' static ) {
9560 if mode:: is_dyn_thread_safe ( ) {
9661 let func = FromDyn :: from ( func) ;
@@ -102,18 +67,43 @@ pub fn spawn(func: impl FnOnce() + DynSend + 'static) {
10267 }
10368}
10469
105- // This function only works when `mode::is_dyn_thread_safe()`.
106- pub fn scope < ' scope , OP , R > ( op : OP ) -> R
107- where
108- OP : FnOnce ( & rustc_thread_pool:: Scope < ' scope > ) -> R + DynSend ,
109- R : DynSend ,
110- {
111- let op = FromDyn :: from ( op) ;
112- rustc_thread_pool:: scope ( |s| FromDyn :: from ( op. into_inner ( ) ( s) ) ) . into_inner ( )
70+ /// Runs the functions in parallel.
71+ ///
72+ /// The first function is executed immediately on the current thread.
73+ /// Use that for the longest running function for better scheduling.
74+ pub fn par_fns ( funcs : & mut [ & mut ( dyn FnMut ( ) + DynSend ) ] ) {
75+ parallel_guard ( |guard : & ParallelGuard | {
76+ if mode:: is_dyn_thread_safe ( ) {
77+ let funcs = FromDyn :: from ( funcs) ;
78+ rustc_thread_pool:: scope ( |s| {
79+ let Some ( ( first, rest) ) = funcs. into_inner ( ) . split_at_mut_checked ( 1 ) else {
80+ return ;
81+ } ;
82+
83+ // Reverse the order of the later functions since Rayon executes them in reverse
84+ // order when using a single thread. This ensures the execution order matches
85+ // that of a single threaded rustc.
86+ for f in rest. iter_mut ( ) . rev ( ) {
87+ let f = FromDyn :: from ( f) ;
88+ s. spawn ( |_| {
89+ guard. run ( || ( f. into_inner ( ) ) ( ) ) ;
90+ } ) ;
91+ }
92+
93+ // Run the first function without spawning to
94+ // ensure it executes immediately on this thread.
95+ guard. run ( || first[ 0 ] ( ) ) ;
96+ } ) ;
97+ } else {
98+ for f in funcs {
99+ guard. run ( || f ( ) ) ;
100+ }
101+ }
102+ } ) ;
113103}
114104
115105#[ inline]
116- pub fn join < A , B , RA : DynSend , RB : DynSend > ( oper_a : A , oper_b : B ) -> ( RA , RB )
106+ pub fn par_join < A , B , RA : DynSend , RB : DynSend > ( oper_a : A , oper_b : B ) -> ( RA , RB )
117107where
118108 A : FnOnce ( ) -> RA + DynSend ,
119109 B : FnOnce ( ) -> RB + DynSend ,
0 commit comments