@@ -745,7 +745,25 @@ rt_test! {
745
745
#[ cfg_attr( miri, ignore) ] // No `socket` in miri.
746
746
fn yield_defers_until_park( ) {
747
747
for _ in 0 ..10 {
748
- if yield_defers_until_park_inner( ) {
748
+ if yield_defers_until_park_inner( false ) {
749
+ // test passed
750
+ return ;
751
+ }
752
+
753
+ // Wait a bit and run the test again.
754
+ std:: thread:: sleep( std:: time:: Duration :: from_secs( 2 ) ) ;
755
+ }
756
+
757
+ panic!( "yield_defers_until_park is failing consistently" ) ;
758
+ }
759
+
760
+ /// Same as above, but with cooperative scheduling.
761
+ #[ test]
762
+ #[ cfg( not( target_os="wasi" ) ) ]
763
+ #[ cfg_attr( miri, ignore) ] // No `socket` in miri.
764
+ fn coop_yield_defers_until_park( ) {
765
+ for _ in 0 ..10 {
766
+ if yield_defers_until_park_inner( true ) {
749
767
// test passed
750
768
return ;
751
769
}
@@ -760,10 +778,12 @@ rt_test! {
760
778
/// Implementation of `yield_defers_until_park` test. Returns `true` if the
761
779
/// test passed.
762
780
#[ cfg( not( target_os="wasi" ) ) ]
763
- fn yield_defers_until_park_inner( ) -> bool {
781
+ fn yield_defers_until_park_inner( use_coop : bool ) -> bool {
764
782
use std:: sync:: atomic:: { AtomicBool , Ordering :: SeqCst } ;
765
783
use std:: sync:: Barrier ;
766
784
785
+ const BUDGET : usize = 128 ;
786
+
767
787
let rt = rt( ) ;
768
788
769
789
let flag = Arc :: new( AtomicBool :: new( false ) ) ;
@@ -802,7 +822,15 @@ rt_test! {
802
822
// Yield until connected
803
823
let mut cnt = 0 ;
804
824
while !flag_clone. load( SeqCst ) {
805
- tokio:: task:: yield_now( ) . await ;
825
+ if use_coop {
826
+ // Consume a good chunk of budget, which should
827
+ // force at least one yield.
828
+ for _ in 0 ..BUDGET {
829
+ tokio:: task:: consume_budget( ) . await ;
830
+ }
831
+ } else {
832
+ tokio:: task:: yield_now( ) . await ;
833
+ }
806
834
cnt += 1 ;
807
835
808
836
if cnt >= 10 {
0 commit comments