github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/imports/wasi_snapshot_preview1/clock.go (about) 1 package wasi_snapshot_preview1 2 3 import ( 4 "context" 5 6 "github.com/wasilibs/wazerox/api" 7 "github.com/wasilibs/wazerox/experimental/sys" 8 "github.com/wasilibs/wazerox/internal/wasip1" 9 "github.com/wasilibs/wazerox/internal/wasm" 10 ) 11 12 // clockResGet is the WASI function named ClockResGetName that returns the 13 // resolution of time values returned by clockTimeGet. 14 // 15 // # Parameters 16 // 17 // - id: clock ID to use 18 // - resultResolution: offset to write the resolution to api.Memory 19 // - the resolution is an uint64 little-endian encoding 20 // 21 // Result (Errno) 22 // 23 // The return value is 0 except the following error conditions: 24 // - sys.ENOTSUP: the clock ID is not supported. 25 // - sys.EINVAL: the clock ID is invalid. 26 // - sys.EFAULT: there is not enough memory to write results 27 // 28 // For example, if the resolution is 100ns, this function writes the below to 29 // api.Memory: 30 // 31 // uint64le 32 // +-------------------------------------+ 33 // | | 34 // []byte{?, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ?} 35 // resultResolution --^ 36 // 37 // Note: This is similar to `clock_getres` in POSIX. 38 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_res_getid-clockid---errno-timestamp 39 // See https://linux.die.net/man/3/clock_getres 40 var clockResGet = newHostFunc(wasip1.ClockResGetName, clockResGetFn, []api.ValueType{i32, i32}, "id", "result.resolution") 41 42 func clockResGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { 43 sysCtx := mod.(*wasm.ModuleInstance).Sys 44 id, resultResolution := uint32(params[0]), uint32(params[1]) 45 46 var resolution uint64 // ns 47 switch id { 48 case wasip1.ClockIDRealtime: 49 resolution = uint64(sysCtx.WalltimeResolution()) 50 case wasip1.ClockIDMonotonic: 51 resolution = uint64(sysCtx.NanotimeResolution()) 52 default: 53 return sys.EINVAL 54 } 55 56 if !mod.Memory().WriteUint64Le(resultResolution, resolution) { 57 return sys.EFAULT 58 } 59 return 0 60 } 61 62 // clockTimeGet is the WASI function named ClockTimeGetName that returns 63 // the time value of a name (time.Now). 64 // 65 // # Parameters 66 // 67 // - id: clock ID to use 68 // - precision: maximum lag (exclusive) that the returned time value may have, 69 // compared to its actual value 70 // - resultTimestamp: offset to write the timestamp to api.Memory 71 // - the timestamp is epoch nanos encoded as a little-endian uint64 72 // 73 // Result (Errno) 74 // 75 // The return value is 0 except the following error conditions: 76 // - sys.ENOTSUP: the clock ID is not supported. 77 // - sys.EINVAL: the clock ID is invalid. 78 // - sys.EFAULT: there is not enough memory to write results 79 // 80 // For example, if time.Now returned exactly midnight UTC 2022-01-01 81 // (1640995200000000000), and parameters resultTimestamp=1, this function 82 // writes the below to api.Memory: 83 // 84 // uint64le 85 // +------------------------------------------+ 86 // | | 87 // []byte{?, 0x0, 0x0, 0x1f, 0xa6, 0x70, 0xfc, 0xc5, 0x16, ?} 88 // resultTimestamp --^ 89 // 90 // Note: This is similar to `clock_gettime` in POSIX. 91 // See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_time_getid-clockid-precision-timestamp---errno-timestamp 92 // See https://linux.die.net/man/3/clock_gettime 93 var clockTimeGet = newHostFunc(wasip1.ClockTimeGetName, clockTimeGetFn, []api.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp") 94 95 func clockTimeGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno { 96 sysCtx := mod.(*wasm.ModuleInstance).Sys 97 id := uint32(params[0]) 98 // TODO: precision is currently ignored. 99 // precision = params[1] 100 resultTimestamp := uint32(params[2]) 101 102 var val int64 103 switch id { 104 case wasip1.ClockIDRealtime: 105 val = sysCtx.WalltimeNanos() 106 case wasip1.ClockIDMonotonic: 107 val = sysCtx.Nanotime() 108 default: 109 return sys.EINVAL 110 } 111 112 if !mod.Memory().WriteUint64Le(resultTimestamp, uint64(val)) { 113 return sys.EFAULT 114 } 115 return 0 116 }