Implements OS interactions and memory management.
For #58141
Co-authored-by: Richard Musiol <neelance@gmail.com>
Co-authored-by: Achille Roussel <achille.roussel@gmail.com>
Co-authored-by: Julien Fabre <ju.pryz@gmail.com>
Co-authored-by: Evan Phoenix <evan@phx.io>
Change-Id: I876e7b033090c2fe2d76d2535bb63d52efa36185
Reviewed-on: https://go-review.googlesource.com/c/go/+/479618
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
}
}
+// HasParallelism reports whether the current system can execute multiple
+// threads in parallel.
+func HasParallelism() bool {
+ switch runtime.GOOS {
+ case "js", "wasip1":
+ return false
+ }
+ return true
+}
+
+// MustHaveParallelism checks that the current system can execute multiple
+// threads in parallel. If not, MustHaveParallelism calls t.Skip with an explanation.
+func MustHaveParallelism(t testing.TB) {
+ if !HasParallelism() {
+ t.Skipf("skipping test: no parallelism available on %s/%s", runtime.GOOS, runtime.GOARCH)
+ }
+}
+
// GoToolPath reports the path to the Go tool.
// It is a convenience wrapper around GoTool.
// If the tool is unavailable GoToolPath calls t.Skip.
--- /dev/null
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build wasip1
+
+package runtime
+
+// wasm has no support for threads yet. There is no preemption.
+// See proposal: https://github.com/WebAssembly/threads
+// Waiting for a mutex or timeout is implemented as a busy loop
+// while allowing other goroutines to run.
+
+const (
+ mutex_unlocked = 0
+ mutex_locked = 1
+
+ active_spin = 4
+ active_spin_cnt = 30
+)
+
+func lock(l *mutex) {
+ lockWithRank(l, getLockRank(l))
+}
+
+func lock2(l *mutex) {
+ if l.key == mutex_locked {
+ // wasm is single-threaded so we should never
+ // observe this.
+ throw("self deadlock")
+ }
+ gp := getg()
+ if gp.m.locks < 0 {
+ throw("lock count")
+ }
+ gp.m.locks++
+ l.key = mutex_locked
+}
+
+func unlock(l *mutex) {
+ unlockWithRank(l)
+}
+
+func unlock2(l *mutex) {
+ if l.key == mutex_unlocked {
+ throw("unlock of unlocked lock")
+ }
+ gp := getg()
+ gp.m.locks--
+ if gp.m.locks < 0 {
+ throw("lock count")
+ }
+ l.key = mutex_unlocked
+}
+
+// One-time notifications.
+func noteclear(n *note) {
+ n.key = 0
+}
+
+func notewakeup(n *note) {
+ if n.key != 0 {
+ print("notewakeup - double wakeup (", n.key, ")\n")
+ throw("notewakeup - double wakeup")
+ }
+ n.key = 1
+}
+
+func notesleep(n *note) {
+ throw("notesleep not supported by wasi")
+}
+
+func notetsleep(n *note, ns int64) bool {
+ throw("notetsleep not supported by wasi")
+ return false
+}
+
+// same as runtime·notetsleep, but called on user g (not g0)
+func notetsleepg(n *note, ns int64) bool {
+ gp := getg()
+ if gp == gp.m.g0 {
+ throw("notetsleepg on g0")
+ }
+
+ deadline := nanotime() + ns
+ for {
+ if n.key != 0 {
+ return true
+ }
+ if sched_yield() != 0 {
+ throw("sched_yield failed")
+ }
+ Gosched()
+ if ns >= 0 && nanotime() >= deadline {
+ return false
+ }
+ }
+}
+
+func beforeIdle(int64, int64) (*g, bool) {
+ return nil, false
+}
+
+func checkTimeouts() {}
+
+//go:wasmimport wasi_snapshot_preview1 sched_yield
+func sched_yield() errno
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build js && wasm
+//go:build js
package runtime
-import "unsafe"
-
-func sbrk(n uintptr) unsafe.Pointer {
- grow := divRoundUp(n, physPageSize)
- size := currentMemory()
-
- if growMemory(int32(grow)) < 0 {
- return nil
- }
-
- resetMemoryDataView()
- return unsafe.Pointer(uintptr(size) * physPageSize)
-}
-
-func currentMemory() int32
-func growMemory(pages int32) int32
-
// resetMemoryDataView signals the JS front-end that WebAssembly's memory.grow instruction has been used.
// This allows the front-end to replace the old DataView object with a new one.
//
--- /dev/null
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build wasip1
+
+package runtime
+
+func resetMemoryDataView() {
+ // This function is a no-op on WASI, it is only used to notify the browser
+ // that its view of the WASM memory needs to be updated when compiling for
+ // GOOS=js.
+}
--- /dev/null
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+func sbrk(n uintptr) unsafe.Pointer {
+ grow := divRoundUp(n, physPageSize)
+ size := growMemory(int32(grow))
+ if size < 0 {
+ return nil
+ }
+ resetMemoryDataView()
+ return unsafe.Pointer(uintptr(size) * physPageSize)
+}
+
+// Implemented in src/runtime/sys_wasm.s
+func growMemory(pages int32) int32
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build unix || (js && wasm) || windows
+//go:build unix || (js && wasm) || wasip1 || windows
package runtime
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Fake network poller for wasm/js.
-// Should never be used, because wasm/js network connections do not honor "SetNonblock".
+// Fake network poller for js/wasm and wasip1/wasm.
+// Should never be used, because wasm network connections do not honor "SetNonblock".
-//go:build js && wasm
+//go:build (js && wasm) || wasip1
package runtime
package runtime
import (
- "runtime/internal/atomic"
"unsafe"
)
return n
}
-// Stubs so tests can link correctly. These should never be called.
-func open(name *byte, mode, perm int32) int32 { panic("not implemented") }
-func closefd(fd int32) int32 { panic("not implemented") }
-func read(fd int32, p unsafe.Pointer, n int32) int32 { panic("not implemented") }
-
//go:wasmimport gojs runtime.wasmWrite
//go:noescape
func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
-func usleep(usec uint32)
-
-//go:nosplit
-func usleep_no_g(usec uint32) {
- usleep(usec)
-}
-
-func exitThread(wait *atomic.Uint32)
-
-type mOS struct{}
-
-func osyield()
-
-//go:nosplit
-func osyield_no_g() {
- osyield()
-}
-
-const _SIGSEGV = 0xb
-
-func sigpanic() {
- gp := getg()
- if !canpanic() {
- throw("unexpected signal during runtime execution")
- }
-
- // js only invokes the exception handler for memory faults.
- gp.sig = _SIGSEGV
- panicmem()
-}
-
-type sigset struct{}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-func mpreinit(mp *m) {
- mp.gsignal = malg(32 * 1024)
- mp.gsignal.m = mp
-}
-
-//go:nosplit
-func sigsave(p *sigset) {
-}
-
-//go:nosplit
-func msigrestore(sigmask sigset) {
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func clearSignalHandlers() {
-}
-
-//go:nosplit
-func sigblock(exiting bool) {
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, cannot allocate memory.
-func minit() {
-}
-
-// Called from dropm to undo the effect of an minit.
-func unminit() {
-}
-
-// Called from exitm, but not from drop, to undo the effect of thread-owned
-// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
-func mdestroy(mp *m) {
-}
-
-func osinit() {
- // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances
- physPageSize = 64 * 1024
- initBloc()
- ncpu = 1
- getg().m.procid = 2
-}
-
-// wasm has no signals
-const _NSIG = 0
-
-func signame(sig uint32) string {
- return ""
-}
-
-func crash() {
- *(*int32)(nil) = 0
+func usleep(usec uint32) {
+ // TODO(neelance): implement usleep
}
//go:wasmimport gojs runtime.getRandomData
+//go:noescape
func getRandomData(r []byte)
func goenvs() {
goenvs_unix()
}
-
-func initsig(preinit bool) {
-}
-
-// May run with m.p==nil, so write barriers are not allowed.
-//
-//go:nowritebarrier
-func newosproc(mp *m) {
- throw("newosproc: not implemented")
-}
-
-func setProcessCPUProfiler(hz int32) {}
-func setThreadCPUProfiler(hz int32) {}
-func sigdisable(uint32) {}
-func sigenable(uint32) {}
-func sigignore(uint32) {}
-
-//go:linkname os_sigpipe os.sigpipe
-func os_sigpipe() {
- throw("too many writes on closed pipe")
-}
-
-//go:nosplit
-func cputicks() int64 {
- // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand().
- // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
- return nanotime()
-}
-
-//go:linkname syscall_now syscall.now
-func syscall_now() (sec int64, nsec int32) {
- sec, nsec, _ = time_now()
- return
-}
-
-// gsignalStack is unused on js.
-type gsignalStack struct{}
-
-const preemptMSupported = false
-
-func preemptM(mp *m) {
- // No threads, so nothing to do.
-}
-
-// getcallerfp returns the address of the frame pointer in the callers frame or 0 if not implemented.
-func getcallerfp() uintptr { return 0 }
--- /dev/null
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build wasip1
+
+package runtime
+
+import "unsafe"
+
+// GOARCH=wasm currently has 64 bits pointers, but the WebAssembly host expects
+// pointers to be 32 bits so we use this type alias to represent pointers in
+// structs and arrays passed as arguments to WASI functions.
+//
+// Note that the use of an integer type prevents the compiler from tracking
+// pointers passed to WASI functions, so we must use KeepAlive to explicitly
+// retain the objects that could otherwise be reclaimed by the GC.
+type uintptr32 = uint32
+
+// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-size-u32
+type size = uint32
+
+// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-errno-variant
+type errno = uint32
+
+// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-filesize-u64
+type filesize = uint64
+
+// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-timestamp-u64
+type timestamp = uint64
+
+// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-clockid-variant
+type clockid = uint32
+
+const (
+ clockRealtime clockid = 0
+ clockMonotonic clockid = 1
+)
+
+// https://github.com/WebAssembly/WASI/blob/a2b96e81c0586125cc4dc79a5be0b78d9a059925/legacy/preview1/docs.md#-iovec-record
+type iovec struct {
+ buf uintptr32
+ bufLen size
+}
+
+//go:wasmimport wasi_snapshot_preview1 proc_exit
+func exit(code int32)
+
+//go:wasmimport wasi_snapshot_preview1 args_get
+//go:noescape
+func args_get(argv *uintptr32, argvBuf *byte) errno
+
+//go:wasmimport wasi_snapshot_preview1 args_sizes_get
+//go:noescape
+func args_sizes_get(argc *size, argvBufLen *size) errno
+
+//go:wasmimport wasi_snapshot_preview1 clock_time_get
+//go:noescape
+func clock_time_get(clock_id clockid, precision timestamp, time *timestamp) errno
+
+//go:wasmimport wasi_snapshot_preview1 environ_get
+//go:noescape
+func environ_get(environ *uintptr32, environBuf *byte) errno
+
+//go:wasmimport wasi_snapshot_preview1 environ_sizes_get
+//go:noescape
+func environ_sizes_get(environCount *size, environBufLen *size) errno
+
+//go:wasmimport wasi_snapshot_preview1 fd_write
+//go:noescape
+func fd_write(fd int32, iovs *iovec, iovsLen size, nwritten *size) errno
+
+//go:wasmimport wasi_snapshot_preview1 random_get
+//go:noescape
+func random_get(buf *byte, bufLen size) errno
+
+type eventtype = uint8
+
+const (
+ eventtypeClock eventtype = iota
+ eventtypeFdRead
+ eventtypeFdWrite
+)
+
+type eventrwflags = uint16
+
+const (
+ fdReadwriteHangup eventrwflags = 1 << iota
+)
+
+type userdata = uint64
+
+// The go:wasmimport directive currently does not accept values of type uint16
+// in arguments or returns of the function signature. Most WASI imports return
+// an errno value, which we have to define as uint32 because of that limitation.
+// However, the WASI errno type is intended to be a 16 bits integer, and in the
+// event struct the error field should be of type errno. If we used the errno
+// type for the error field it would result in a mismatching field alignment and
+// struct size because errno is declared as a 32 bits type, so we declare the
+// error field as a plain uint16.
+type event struct {
+ userdata userdata
+ error uint16
+ typ eventtype
+ fdReadwrite eventFdReadwrite
+}
+
+type eventFdReadwrite struct {
+ nbytes filesize
+ flags eventrwflags
+}
+
+type subclockflags = uint16
+
+const (
+ subscriptionClockAbstime subclockflags = 1 << iota
+)
+
+type subscriptionClock struct {
+ id clockid
+ timeout timestamp
+ precision timestamp
+ flags subclockflags
+}
+
+type subscription struct {
+ userdata userdata
+ u subscriptionUnion
+}
+
+type subscriptionUnion [5]uint64
+
+func (u *subscriptionUnion) eventtype() *eventtype {
+ return (*eventtype)(unsafe.Pointer(&u[0]))
+}
+
+func (u *subscriptionUnion) subscriptionClock() *subscriptionClock {
+ return (*subscriptionClock)(unsafe.Pointer(&u[1]))
+}
+
+//go:wasmimport wasi_snapshot_preview1 poll_oneoff
+//go:noescape
+func poll_oneoff(in *subscription, out *event, nsubscriptions size, nevents *size) errno
+
+func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
+ iov := iovec{
+ buf: uintptr32(uintptr(p)),
+ bufLen: size(n),
+ }
+ var nwritten size
+ if fd_write(int32(fd), &iov, 1, &nwritten) != 0 {
+ throw("fd_write failed")
+ }
+ return int32(nwritten)
+}
+
+func usleep(usec uint32) {
+ var in subscription
+ var out event
+ var nevents size
+
+ eventtype := in.u.eventtype()
+ *eventtype = eventtypeClock
+
+ subscription := in.u.subscriptionClock()
+ subscription.id = clockMonotonic
+ subscription.timeout = timestamp(usec) * 1e3
+ subscription.precision = 1e3
+
+ if poll_oneoff(&in, &out, 1, &nevents) != 0 {
+ throw("wasi_snapshot_preview1.poll_oneoff")
+ }
+}
+
+func getRandomData(r []byte) {
+ if random_get(&r[0], size(len(r))) != 0 {
+ throw("random_get failed")
+ }
+}
+
+func goenvs() {
+ // arguments
+ var argc size
+ var argvBufLen size
+ if args_sizes_get(&argc, &argvBufLen) != 0 {
+ throw("args_sizes_get failed")
+ }
+
+ argslice = make([]string, argc)
+ if argc > 0 {
+ argv := make([]uintptr32, argc)
+ argvBuf := make([]byte, argvBufLen)
+ if args_get(&argv[0], &argvBuf[0]) != 0 {
+ throw("args_get failed")
+ }
+
+ for i := range argslice {
+ start := argv[i] - uintptr32(uintptr(unsafe.Pointer(&argvBuf[0])))
+ end := start
+ for argvBuf[end] != 0 {
+ end++
+ }
+ argslice[i] = string(argvBuf[start:end])
+ }
+ }
+
+ // environment
+ var environCount size
+ var environBufLen size
+ if environ_sizes_get(&environCount, &environBufLen) != 0 {
+ throw("environ_sizes_get failed")
+ }
+
+ envs = make([]string, environCount)
+ if environCount > 0 {
+ environ := make([]uintptr32, environCount)
+ environBuf := make([]byte, environBufLen)
+ if environ_get(&environ[0], &environBuf[0]) != 0 {
+ throw("environ_get failed")
+ }
+
+ for i := range envs {
+ start := environ[i] - uintptr32(uintptr(unsafe.Pointer(&environBuf[0])))
+ end := start
+ for environBuf[end] != 0 {
+ end++
+ }
+ envs[i] = string(environBuf[start:end])
+ }
+ }
+}
+
+func walltime() (sec int64, nsec int32) {
+ return walltime1()
+}
+
+func walltime1() (sec int64, nsec int32) {
+ var time timestamp
+ if clock_time_get(clockRealtime, 0, &time) != 0 {
+ throw("clock_time_get failed")
+ }
+ return int64(time / 1000000000), int32(time % 1000000000)
+}
+
+func nanotime1() int64 {
+ var time timestamp
+ if clock_time_get(clockMonotonic, 0, &time) != 0 {
+ throw("clock_time_get failed")
+ }
+ return int64(time)
+}
--- /dev/null
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+func osinit() {
+ // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances
+ physPageSize = 64 * 1024
+ initBloc()
+ ncpu = 1
+ getg().m.procid = 2
+}
+
+const _SIGSEGV = 0xb
+
+func sigpanic() {
+ gp := getg()
+ if !canpanic() {
+ throw("unexpected signal during runtime execution")
+ }
+
+ // js only invokes the exception handler for memory faults.
+ gp.sig = _SIGSEGV
+ panicmem()
+}
+
+// func exitThread(wait *uint32)
+// FIXME: wasm doesn't have atomic yet
+func exitThread(wait *atomic.Uint32)
+
+type mOS struct{}
+
+func osyield()
+
+//go:nosplit
+func osyield_no_g() {
+ osyield()
+}
+
+type sigset struct{}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+ mp.gsignal = malg(32 * 1024)
+ mp.gsignal.m = mp
+}
+
+//go:nosplit
+func usleep_no_g(usec uint32) {
+ usleep(usec)
+}
+
+//go:nosplit
+func sigsave(p *sigset) {
+}
+
+//go:nosplit
+func msigrestore(sigmask sigset) {
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func clearSignalHandlers() {
+}
+
+//go:nosplit
+func sigblock(exiting bool) {
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, cannot allocate memory.
+func minit() {
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+}
+
+// Called from exitm, but not from drop, to undo the effect of thread-owned
+// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
+func mdestroy(mp *m) {
+}
+
+// wasm has no signals
+const _NSIG = 0
+
+func signame(sig uint32) string {
+ return ""
+}
+
+func crash() {
+ *(*int32)(nil) = 0
+}
+
+func initsig(preinit bool) {
+}
+
+// May run with m.p==nil, so write barriers are not allowed.
+//
+//go:nowritebarrier
+func newosproc(mp *m) {
+ throw("newosproc: not implemented")
+}
+
+//go:linkname os_sigpipe os.sigpipe
+func os_sigpipe() {
+ throw("too many writes on closed pipe")
+}
+
+//go:linkname syscall_now syscall.now
+func syscall_now() (sec int64, nsec int32) {
+ sec, nsec, _ = time_now()
+ return
+}
+
+//go:nosplit
+func cputicks() int64 {
+ // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand().
+ // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+ // TODO: need more entropy to better seed fastrand.
+ return nanotime()
+}
+
+// gsignalStack is unused on js.
+type gsignalStack struct{}
+
+const preemptMSupported = false
+
+func preemptM(mp *m) {
+ // No threads, so nothing to do.
+}
+
+// getcallerfp returns the address of the frame pointer in the callers frame or 0 if not implemented.
+func getcallerfp() uintptr { return 0 }
+
+func setProcessCPUProfiler(hz int32) {}
+func setThreadCPUProfiler(hz int32) {}
+func sigdisable(uint32) {}
+func sigenable(uint32) {}
+func sigignore(uint32) {}
+
+// Stubs so tests can link correctly. These should never be called.
+func open(name *byte, mode, perm int32) int32 { panic("not implemented") }
+func closefd(fd int32) int32 { panic("not implemented") }
+func read(fd int32, p unsafe.Pointer, n int32) int32 { panic("not implemented") }
t.Logf("uname -a: %v", vers)
case "plan9":
t.Skip("skipping on plan9")
+ case "wasip1":
+ t.Skip("skipping on wasip1")
}
broken := cpuProfilingBroken()
}
func TestGoroutineProfileConcurrency(t *testing.T) {
+ testenv.MustHaveParallelism(t)
+
goroutineProf := Lookup("goroutine")
profilerCalls := func(s string) int {
}
func TestLabelRace(t *testing.T) {
+ testenv.MustHaveParallelism(t)
// Test the race detector annotations for synchronization
// between setting labels and consuming them from the
// profile.
}
func TestGoroutineProfileLabelRace(t *testing.T) {
+ testenv.MustHaveParallelism(t)
// Test the race detector annotations for synchronization
// between setting labels and consuming them from the
// goroutine profile. See issue #50292.
BuildID: peBuildID(exe),
HasFunctions: true,
}
- case "js":
+ case "js", "wasip1":
addr1 = uint64(abi.FuncPCABIInternal(f1))
addr2 = uint64(abi.FuncPCABIInternal(f2))
default:
//
//go:nocheckptr
func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
- if GOOS == "js" {
- t.Skip("js does not support catching faults")
+ if GOOS == "js" || GOOS == "wasip1" {
+ t.Skip(GOOS + " does not support catching faults")
}
defer func() {
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build !plan9 && !windows && !js
+//go:build !plan9 && !windows && !js && !wasip1
package runtime_test
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build !aix && !darwin && !js && !openbsd && !plan9 && !solaris && !windows
+//go:build !aix && !darwin && !js && !openbsd && !plan9 && !solaris && !wasip1 && !windows
package runtime
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build !aix && !darwin && !freebsd && !openbsd && !plan9 && !solaris
+//go:build !aix && !darwin && !freebsd && !openbsd && !plan9 && !solaris && !wasip1
package runtime
TEXT runtime·osyield(SB), NOSPLIT, $0-0
UNDEF
-TEXT runtime·usleep(SB), NOSPLIT, $0-0
- RET // TODO(neelance): implement usleep
-
-TEXT runtime·currentMemory(SB), NOSPLIT, $0
- Get SP
- CurrentMemory
- I32Store ret+0(FP)
- RET
-
TEXT runtime·growMemory(SB), NOSPLIT, $0
Get SP
I32Load pages+0(FP)
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build !aix && !darwin && !freebsd && !openbsd && !solaris && !windows && !(linux && amd64)
+//go:build !aix && !darwin && !freebsd && !openbsd && !solaris && !wasip1 && !windows && !(linux && amd64)
package runtime
}
func TestTraceStress(t *testing.T) {
- if runtime.GOOS == "js" {
- t.Skip("no os.Pipe on js")
+ switch runtime.GOOS {
+ case "js", "wasip1":
+ t.Skip("no os.Pipe on " + runtime.GOOS)
}
if IsEnabled() {
t.Skip("skipping because -test.trace is set")
// Do a bunch of various stuff (timers, GC, network, etc) in a separate goroutine.
// And concurrently with all that start/stop trace 3 times.
func TestTraceStressStartStop(t *testing.T) {
- if runtime.GOOS == "js" {
- t.Skip("no os.Pipe on js")
+ switch runtime.GOOS {
+ case "js", "wasip1":
+ t.Skip("no os.Pipe on " + runtime.GOOS)
}
if IsEnabled() {
t.Skip("skipping because -test.trace is set")