diff options
| author | Richard Musiol <mail@richard-musiol.de> | 2018-05-20 00:56:36 +0200 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2018-06-14 21:50:53 +0000 |
| commit | e083dc6307b6593bdd44b219ffd21699d6f17fd7 (patch) | |
| tree | 2a411d82639a778c6aa107529b1d708034c7a7f1 /src/runtime/proc.go | |
| parent | 5fdacfa89f871888d6f8fde726b8f95f11e674d6 (diff) | |
| download | go-e083dc6307b6593bdd44b219ffd21699d6f17fd7.tar.xz | |
runtime, sycall/js: add support for callbacks from JavaScript
This commit adds support for JavaScript callbacks back into
WebAssembly. This is experimental API, just like the rest of the
syscall/js package. The time package now also uses this mechanism
to properly support timers without resorting to a busy loop.
JavaScript code can call into the same entry point multiple times.
The new RUN register is used to keep track of the program's
run state. Possible values are: starting, running, paused and exited.
If no goroutine is ready any more, the scheduler can put the
program into the "paused" state and the WebAssembly code will
stop running. When a callback occurs, the JavaScript code puts
the callback data into a queue and then calls into WebAssembly
to allow the Go code to continue running.
Updates #18892
Updates #25506
Change-Id: Ib8701cfa0536d10d69bd541c85b0e2a754eb54fb
Reviewed-on: https://go-review.googlesource.com/114197
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/runtime/proc.go')
| -rw-r--r-- | src/runtime/proc.go | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go index e3549d367a..36c74a1e8c 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -263,6 +263,7 @@ func forcegchelper() { // Gosched yields the processor, allowing other goroutines to run. It does not // suspend the current goroutine, so execution resumes automatically. func Gosched() { + checkTimeouts() mcall(gosched_m) } @@ -282,6 +283,9 @@ func goschedguarded() { // Reasons should be unique and descriptive. // Do not re-use reasons, add new ones. func gopark(unlockf func(*g, unsafe.Pointer) bool, lock unsafe.Pointer, reason waitReason, traceEv byte, traceskip int) { + if reason != waitReasonSleep { + checkTimeouts() // timeouts may expire while two goroutines keep the scheduler busy + } mp := acquirem() gp := mp.curg status := readgstatus(gp) @@ -2361,6 +2365,14 @@ stop: return gp, false } + // wasm only: + // Check if a goroutine is waiting for a callback from the WebAssembly host. + // If yes, pause the execution until a callback was triggered. + if pauseSchedulerUntilCallback() { + // A callback was triggered and caused at least one goroutine to wake up. + goto top + } + // Before we drop our P, make a snapshot of the allp slice, // which can change underfoot once we no longer block // safe-points. We don't need to snapshot the contents because |
