Skip to content

Conversation

@nevkontakte
Copy link
Member

If there are two or more goroutines that are constantly interacting with
each other, they both will regularly give back control to the scheduler.
But if scheduler never yields to the JavaScript's event loop, events
like IO or timers will never have a chance to fire, and, for example,
time.Sleep() will never return.

We can't yield to the event loop after every goroutine switch, the
overhead of setTimeout() is ~1000x higher than the tight while-true
loop.

To amortize the overhead we will how yield if there's no scheduled
goroutine (old behavior), or if we spent more than 4ms executing the
code. In my benchmark, the cost of goroutine switch changed from
273ns/op to 341ns/op, which we can live with — most apps don't have such
tight loops anyway.

Fixes #1078.

If there are two or more goroutines that are constantly interacting with
each other, they both will regularly give back control to the scheduler.
But if scheduler never yields to the JavaScript's event loop, events
like IO or timers will never have a chance to fire, and, for example,
`time.Sleep()` will never return.

We can't yield to the event loop after every goroutine switch, the
overhead of `setTimeout()` is ~1000x higher than the tight while-true
loop.

To amortize the overhead we will how yield if there's no scheduled
goroutine (old behavior), or if we spent more than 4ms executing the
code. In my benchmark, the cost of goroutine switch changed from
273ns/op to 341ns/op, which we can live with — most apps don't have such
tight loops anyway.
@nevkontakte nevkontakte requested a review from flimzy October 22, 2021 22:52
@nevkontakte nevkontakte enabled auto-merge October 22, 2021 22:52
@nevkontakte nevkontakte merged commit 1e6abe7 into gopherjs:master Oct 23, 2021
@nevkontakte nevkontakte deleted the event-starvation branch October 23, 2021 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A pair of communicating goroutines can starve other goroutines

2 participants