mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 04:53:42 +00:00
runtime,syscall,internal/poll,os: wasip1 poll_oneoff scheduler integration + net.FileListener (#5386)
* runtime,syscall,internal/poll,os: wasip1 poll_oneoff scheduler integration + net.FileListener On wasip1 today every syscall.Read/Write blocks the entire wasm module — the cooperative scheduler invokes poll_oneoff only for sleep/timer wakeups, and there's no path from the net package to a working TCP server. This change fixes both: it threads poll_oneoff through the scheduler's idle path so a goroutine doing FD I/O parks instead of blocking the module, and it provides enough internal/poll / os / syscall surface that upstream Go's net.FileListener / net.FileConn works on a host-pre-opened TCP socket. * runtime: keep scheduler_cooperative idle-wait calls direct TestBinarySize/hifive1b/examples/echo regressed by 32 bytes after the previous commit routed the scheduler's idle wait through a schedulerIdleWait helper. The extra call frame + branch landed on every non-wasip1 cooperative target, where the original direct sleepTicks / waitForEvents calls compile to a single inlined call.
This commit is contained in:
@@ -78,11 +78,6 @@ var (
|
||||
sleepTicksNEvents uint32
|
||||
)
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
sleepTicksSubscription.u.u.timeout = uint64(d)
|
||||
poll_oneoff(&sleepTicksSubscription, &sleepTicksResult, 1, &sleepTicksNEvents)
|
||||
}
|
||||
|
||||
func ticks() timeUnit {
|
||||
var nano uint64
|
||||
clock_time_get(0, timePrecisionNanoseconds, &nano)
|
||||
@@ -106,9 +101,9 @@ func poll_oneoff(in *__wasi_subscription_t, out *__wasi_event_t, nsubscriptions
|
||||
type __wasi_eventtype_t = uint8
|
||||
|
||||
const (
|
||||
__wasi_eventtype_t_clock __wasi_eventtype_t = 0
|
||||
// TODO: __wasi_eventtype_t_fd_read __wasi_eventtype_t = 1
|
||||
// TODO: __wasi_eventtype_t_fd_write __wasi_eventtype_t = 2
|
||||
__wasi_eventtype_t_clock __wasi_eventtype_t = iota
|
||||
__wasi_eventtype_t_fd_read
|
||||
__wasi_eventtype_t_fd_write
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -118,10 +113,12 @@ type (
|
||||
u __wasi_subscription_u_t
|
||||
}
|
||||
|
||||
// The union payload is sized by the largest variant (clock, 32 bytes after
|
||||
// the tag and its 7-byte alignment pad). FD read/write subscriptions reuse
|
||||
// the same memory via setFDReadWrite.
|
||||
__wasi_subscription_u_t struct {
|
||||
tag __wasi_eventtype_t
|
||||
|
||||
// TODO: support fd_read/fd_write event
|
||||
u __wasi_subscription_clock_t
|
||||
}
|
||||
|
||||
@@ -134,6 +131,28 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// __wasi_subscription_fd_readwrite_t is the FD variant of the subscription
|
||||
// union payload. It overlays the first 4 bytes of the clock variant.
|
||||
type __wasi_subscription_fd_readwrite_t struct {
|
||||
fd uint32
|
||||
}
|
||||
|
||||
func (s *__wasi_subscription_u_t) setClock(id uint32, timeoutNs, precision uint64, flags uint16) {
|
||||
s.tag = __wasi_eventtype_t_clock
|
||||
s.u = __wasi_subscription_clock_t{
|
||||
id: id,
|
||||
timeout: timeoutNs,
|
||||
precision: precision,
|
||||
flags: flags,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *__wasi_subscription_u_t) setFDReadWrite(eventType __wasi_eventtype_t, fd uint32) {
|
||||
s.tag = eventType
|
||||
s.u = __wasi_subscription_clock_t{}
|
||||
(*__wasi_subscription_fd_readwrite_t)(unsafe.Pointer(&s.u)).fd = fd
|
||||
}
|
||||
|
||||
type (
|
||||
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-event-record
|
||||
__wasi_event_t struct {
|
||||
@@ -141,11 +160,18 @@ type (
|
||||
errno uint16
|
||||
eventType __wasi_eventtype_t
|
||||
|
||||
// only used for fd_read or fd_write events
|
||||
// TODO: support fd_read/fd_write event
|
||||
_ struct {
|
||||
// fdReadWrite is populated by poll_oneoff for fd_read / fd_write events.
|
||||
// For clock events the field is zero. Reading nBytes/flags after a
|
||||
// clock event is meaningless but not unsafe.
|
||||
fdReadWrite struct {
|
||||
nBytes uint64
|
||||
flags uint16
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// Compile-time size assertions for the wasip1 ABI. If these fail to compile
|
||||
// the struct layout drifted from the spec and poll_oneoff would corrupt
|
||||
// memory.
|
||||
var _ [0]byte = [48 - unsafe.Sizeof(__wasi_subscription_t{})]byte{}
|
||||
var _ [0]byte = [32 - unsafe.Sizeof(__wasi_event_t{})]byte{}
|
||||
|
||||
Reference in New Issue
Block a user