Ensure yield-equivalent with an already-expired timeout.
PiperOrigin-RevId: 264920977
This commit is contained in:
parent
0e82f9f3fb
commit
761e4bf2fe
|
@ -15,6 +15,7 @@
|
||||||
package kernel
|
package kernel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||||
|
@ -121,6 +122,17 @@ func (t *Task) block(C <-chan struct{}, timerChan <-chan struct{}) error {
|
||||||
// Deactive our address space, we don't need it.
|
// Deactive our address space, we don't need it.
|
||||||
interrupt := t.SleepStart()
|
interrupt := t.SleepStart()
|
||||||
|
|
||||||
|
// If the request is not completed, but the timer has already expired,
|
||||||
|
// then ensure that we run through a scheduler cycle. This is because
|
||||||
|
// we may see applications relying on timer slack to yield the thread.
|
||||||
|
// For example, they may attempt to sleep for some number of nanoseconds,
|
||||||
|
// and expect that this will actually yield the CPU and sleep for at
|
||||||
|
// least microseconds, e.g.:
|
||||||
|
// https://github.com/LMAX-Exchange/disruptor/commit/6ca210f2bcd23f703c479804d583718e16f43c07
|
||||||
|
if len(timerChan) > 0 {
|
||||||
|
runtime.Gosched()
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-C:
|
case <-C:
|
||||||
t.SleepFinish(true)
|
t.SleepFinish(true)
|
||||||
|
|
Loading…
Reference in New Issue