Skip to content
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

wasm: scheduling of JavaScript callbacks is not fair #27894

Open
sherhut opened this issue Sep 27, 2018 · 7 comments

Comments

@sherhut
Copy link

commented Sep 27, 2018

What version of Go are you using (go version)?

go version go1.11 linux/amd64

Does this issue reproduce with the latest release?

yes

Description

I ran the webassembly benchmark in https://djhworld.github.io/post/2018/09/21/i-ported-my-gameboy-color-emulator-to-webassembly/ and as also noted on that page, the benchmark does not properly process keyboard input on chrome. See https://bugs.chromium.org/p/v8/issues/detail?id=8227 for the v8 tracking bug.

Due to a performance issue in v8, the compiled go code runs slower in v8 than firefox. As a consequence, there is more pressure on the go scheduler. In particular, there is nearly always a go-routine ready to be executed with very few idle pauses. Looking at the scheduler implementation at

if pauseSchedulerUntilCallback() {

this leads to starvation of the go-routines that are waiting for a callback from java-script. In case of the gameboy emulator, this means that no more I/O events are being processed.

@myitcv

This comment has been minimized.

Copy link
Member

commented Sep 27, 2018

Is this in some way related to #26045?

@agnivade

This comment has been minimized.

Copy link
Member

commented Sep 27, 2018

Possibly. But I am not very clear on what exactly this issue tries to resolve. Does pauseSchedulerUntilCallback perform a STW-like action where unless the callback hasn't happened, no other goroutine can execute ?

Otherwise, I don't see a reason other goroutines will still wait for a callback from js.

@sherhut

This comment has been minimized.

Copy link
Author

commented Sep 27, 2018

The issue I am seeing here is not that go-routines cannot run while we wait for a callback, but that callbacks do not happen until no other go-routine runs. I just briefly looked at the runtime and might have missed something. But this is how I understand it:

Go (running on top of WebAssembly) can only receive callbacks from JavaScript if the WebAssembly runtime returns to the event loop. This is facilitated by pauseSchedulerUntilCallback, which in the go-runtime for JavaScript calls pause if any callbacks from JavaScript are potentially pending, that is a callback handler has been registered before. I looked at

// pauseSchedulerUntilCallback gets called from the scheduler and pauses the execution

The call to pause will fully unwind the stack and return from WebAssembly back to JavaScript land.

TEXT runtime·pause(SB), NOSPLIT, $0

Is there another path to fully unwind and return to JavaScript that I have missed?

@katiehockman katiehockman changed the title webassembly scheduling of JavaScript callbacks is not fair wasm: scheduling of JavaScript callbacks is not fair Sep 27, 2018

@katiehockman

This comment has been minimized.

Copy link
Contributor

commented Sep 27, 2018

/cc @neelance

@neelance

This comment has been minimized.

Copy link
Member

commented Oct 21, 2018

Yes, giving back execution from Go (WebAssembly) to JavaScript is a "stop the world" action for Go. No goroutine will run until a callback invokes Go code (user action, timer, etc.). Since we want all Go code to run which is not waiting for such callbacks, we give back execution to JS only if ALL goroutines are asleep. If your Go code always has something to do, execution will never be passed back to JS, so user events will not be processed.

This is the current situation. Maybe we could extend the scheduler so it periodically gives back execution to JS, even if there are still runnable goroutines.

This somewhat depends on #26045.

@agnivade

This comment has been minimized.

Copy link
Member

commented Jun 2, 2019

@neelance - Just wanted to check in on this. Now that #26045 is resolved, has this situation improved, or it still needs further work ?

@neelance

This comment has been minimized.

Copy link
Member

commented Jun 3, 2019

I think this needs further work. Most likely it will get resolved when we add WebAssembly threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.