Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Prevent event loop starvation by always scheduled goroutines. #1079

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 23, 2021

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
Morty Proxy This is a proxified and sanitized view of the page, visit original site.