wasi: implements sched_yield with sys.Osyield (#1131)
This implements WASI `sched_yield` with `sys.Osyield` that defaults to return immediately. This is intentionally left without a built-in alternative as common platforms such as darwin implement `runtime.osyield` by sleeping for a microsecond. If we implemented that, user code would be slowed down without a clear reason why. Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
20
config.go
20
config.go
@@ -554,7 +554,7 @@ type ModuleConfig interface {
|
||||
//
|
||||
// This example uses a custom sleep function:
|
||||
// moduleConfig = moduleConfig.
|
||||
// WithNanosleep(func(ctx context.Context, ns int64) {
|
||||
// WithNanosleep(func(ns int64) {
|
||||
// rel := unix.NsecToTimespec(ns)
|
||||
// remain := unix.Timespec{}
|
||||
// for { // loop until no more time remaining
|
||||
@@ -569,6 +569,14 @@ type ModuleConfig interface {
|
||||
// - Use WithSysNanosleep for a usable implementation.
|
||||
WithNanosleep(sys.Nanosleep) ModuleConfig
|
||||
|
||||
// WithOsyield yields the processor, typically to implement spin-wait
|
||||
// loops. Defaults to return immediately.
|
||||
//
|
||||
// # Notes:
|
||||
// - This primarily supports `sched_yield` in WASI
|
||||
// - This does not default to runtime.osyield as that violates sandboxing.
|
||||
WithOsyield(sys.Osyield) ModuleConfig
|
||||
|
||||
// WithSysNanosleep uses time.Sleep for sys.Nanosleep.
|
||||
//
|
||||
// See WithNanosleep
|
||||
@@ -598,6 +606,7 @@ type moduleConfig struct {
|
||||
nanotime *sys.Nanotime
|
||||
nanotimeResolution sys.ClockResolution
|
||||
nanosleep *sys.Nanosleep
|
||||
osyield *sys.Osyield
|
||||
args [][]byte
|
||||
// environ is pair-indexed to retain order similar to os.Environ.
|
||||
environ [][]byte
|
||||
@@ -740,6 +749,13 @@ func (c *moduleConfig) WithNanosleep(nanosleep sys.Nanosleep) ModuleConfig {
|
||||
return &ret
|
||||
}
|
||||
|
||||
// WithOsyield implements ModuleConfig.WithOsyield
|
||||
func (c *moduleConfig) WithOsyield(osyield sys.Osyield) ModuleConfig {
|
||||
ret := *c // copy
|
||||
ret.osyield = &osyield
|
||||
return &ret
|
||||
}
|
||||
|
||||
// WithSysNanosleep implements ModuleConfig.WithSysNanosleep
|
||||
func (c *moduleConfig) WithSysNanosleep() ModuleConfig {
|
||||
return c.WithNanosleep(platform.Nanosleep)
|
||||
@@ -796,7 +812,7 @@ func (c *moduleConfig) toSysContext() (sysCtx *internalsys.Context, err error) {
|
||||
c.randSource,
|
||||
c.walltime, c.walltimeResolution,
|
||||
c.nanotime, c.nanotimeResolution,
|
||||
c.nanosleep,
|
||||
c.nanosleep, c.osyield,
|
||||
fs,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user