@@ -143,6 +143,36 @@ where
143143 }
144144}
145145
146+ fn maybe_set_network_timer ( now : u64 ) {
147+ if let Some ( mut guard) = crate :: executor:: network:: NIC . try_lock ( ) {
148+ let delay = if let Ok ( nic) = guard. as_nic_mut ( ) {
149+ let mut delay_micros = nic
150+ . poll_delay ( Instant :: from_micros_const ( now. try_into ( ) . unwrap ( ) ) )
151+ . map ( |d| d. total_micros ( ) ) ;
152+
153+ // Under heavy workloads, we may be lagging behind, in which case we
154+ // need to try to catch up immediately
155+ while delay_micros == Some ( 0 ) {
156+ nic. poll_common ( crate :: executor:: network:: now ( ) ) ;
157+ delay_micros = nic
158+ . poll_delay ( crate :: executor:: network:: now ( ) )
159+ . map ( |d| d. total_micros ( ) ) ;
160+ }
161+
162+ // We will yield back to userspace and may not have an opportunity to handle
163+ // network traffic unless we enable interrupts
164+ nic. set_polling_mode ( false ) ;
165+
166+ delay_micros
167+ } else {
168+ None
169+ } ;
170+
171+ core_local:: core_scheduler ( )
172+ . add_network_timer ( delay. map ( |d| crate :: arch:: processor:: get_timer_ticks ( ) + d) ) ;
173+ }
174+ }
175+
146176/// Blocks the current thread on `f`, running the executor when idling.
147177pub ( crate ) fn block_on < F , T > ( future : F , timeout : Option < Duration > ) -> io:: Result < T >
148178where
@@ -166,21 +196,7 @@ where
166196 if let Poll :: Ready ( t) = result {
167197 // allow network interrupts
168198 #[ cfg( feature = "net" ) ]
169- {
170- if let Some ( mut guard) = crate :: executor:: network:: NIC . try_lock ( ) {
171- let delay = if let Ok ( nic) = guard. as_nic_mut ( ) {
172- nic. set_polling_mode ( false ) ;
173-
174- nic. poll_delay ( Instant :: from_micros_const ( now. try_into ( ) . unwrap ( ) ) )
175- . map ( |d| d. total_micros ( ) )
176- } else {
177- None
178- } ;
179- core_local:: core_scheduler ( ) . add_network_timer (
180- delay. map ( |d| crate :: arch:: processor:: get_timer_ticks ( ) + d) ,
181- ) ;
182- }
183- }
199+ maybe_set_network_timer ( now) ;
184200
185201 return t;
186202 }
@@ -190,21 +206,7 @@ where
190206 {
191207 // allow network interrupts
192208 #[ cfg( feature = "net" ) ]
193- {
194- if let Some ( mut guard) = crate :: executor:: network:: NIC . try_lock ( ) {
195- let delay = if let Ok ( nic) = guard. as_nic_mut ( ) {
196- nic. set_polling_mode ( false ) ;
197-
198- nic. poll_delay ( Instant :: from_micros_const ( now. try_into ( ) . unwrap ( ) ) )
199- . map ( |d| d. total_micros ( ) )
200- } else {
201- None
202- } ;
203- core_local:: core_scheduler ( ) . add_network_timer (
204- delay. map ( |d| crate :: arch:: processor:: get_timer_ticks ( ) + d) ,
205- ) ;
206- }
207- }
209+ maybe_set_network_timer ( now) ;
208210
209211 return Err ( Errno :: Time ) ;
210212 }
0 commit comments