1
0
mirror of https://github.com/golang/go synced 2024-09-29 09:24:28 -06:00

runtime: add remaining wasip1 files

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>
This commit is contained in:
Johan Brandhorst-Satzkorn 2023-03-24 23:11:55 -07:00 committed by Gopher Robot
parent c02fa75086
commit be50055eef
19 changed files with 588 additions and 182 deletions

View File

@ -78,6 +78,24 @@ func MustHaveGoRun(t testing.TB) {
}
}
// 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.

107
src/runtime/lock_wasip1.go Normal file
View File

@ -0,0 +1,107 @@
// 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

View File

@ -2,27 +2,10 @@
// 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.
//

13
src/runtime/mem_wasip1.go Normal file
View File

@ -0,0 +1,13 @@
// 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.
}

20
src/runtime/mem_wasm.go Normal file
View File

@ -0,0 +1,20 @@
// 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

View File

@ -2,7 +2,7 @@
// 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

View File

@ -2,10 +2,10 @@
// 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

View File

@ -7,7 +7,6 @@
package runtime
import (
"runtime/internal/atomic"
"unsafe"
)
@ -21,154 +20,18 @@ func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
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 }

251
src/runtime/os_wasip1.go Normal file
View File

@ -0,0 +1,251 @@
// 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)
}

152
src/runtime/os_wasm.go Normal file
View File

@ -0,0 +1,152 @@
// 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") }

View File

@ -448,6 +448,8 @@ func testCPUProfile(t *testing.T, matches profileMatchFunc, f func(dur time.Dura
t.Logf("uname -a: %v", vers)
case "plan9":
t.Skip("skipping on plan9")
case "wasip1":
t.Skip("skipping on wasip1")
}
broken := cpuProfilingBroken()
@ -1457,6 +1459,8 @@ func containsCountsLabels(prof *profile.Profile, countLabels map[int64]map[strin
}
func TestGoroutineProfileConcurrency(t *testing.T) {
testenv.MustHaveParallelism(t)
goroutineProf := Lookup("goroutine")
profilerCalls := func(s string) int {
@ -1785,6 +1789,7 @@ func TestCPUProfileLabel(t *testing.T) {
}
func TestLabelRace(t *testing.T) {
testenv.MustHaveParallelism(t)
// Test the race detector annotations for synchronization
// between setting labels and consuming them from the
// profile.
@ -1809,6 +1814,7 @@ func TestLabelRace(t *testing.T) {
}
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.

View File

@ -131,7 +131,7 @@ func testPCs(t *testing.T) (addr1, addr2 uint64, map1, map2 *profile.Mapping) {
BuildID: peBuildID(exe),
HasFunctions: true,
}
case "js":
case "js", "wasip1":
addr1 = uint64(abi.FuncPCABIInternal(f1))
addr2 = uint64(abi.FuncPCABIInternal(f2))
default:

View File

@ -207,8 +207,8 @@ func TestSetPanicOnFault(t *testing.T) {
//
//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() {

View File

@ -2,7 +2,7 @@
// 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

View File

@ -2,7 +2,7 @@
// 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

View File

@ -2,7 +2,7 @@
// 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

View File

@ -86,15 +86,6 @@ TEXT runtime·exitThread(SB), NOSPLIT, $0-0
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)

View File

@ -2,7 +2,7 @@
// 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

View File

@ -184,8 +184,9 @@ func testBrokenTimestamps(t *testing.T, data []byte) {
}
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")
@ -348,8 +349,9 @@ func isMemoryConstrained() bool {
// 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")