github.com/moontrade/wavm-go@v0.3.2-0.20220316110326-d229dd66ad65/worker/worker.go (about) 1 package worker 2 3 /* 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <time.h> 7 #include "worker.h" 8 #include "wavm-c.h" 9 */ 10 import "C" 11 import ( 12 "fmt" 13 "github.com/moontrade/wavm-go" 14 "unsafe" 15 ) 16 17 func Now() int64 { 18 return runtimeNano() 19 } 20 21 type Worker struct { 22 id int64 23 next *Worker 24 prev *Worker 25 engine *wavm.Engine 26 compartment *wavm.Compartment 27 store *wavm.Store 28 memory *wavm.Memory 29 start *wavm.Func 30 resume *wavm.Func 31 alloc *wavm.Func 32 realloc *wavm.Func 33 free *wavm.Func 34 stub *wavm.Func 35 funcCall *C.void // wasm_func_call ptr 36 log *C.char // log buffer managed by C (malloc/free) 37 logLen int64 38 logCap int64 39 begin int64 40 end int64 41 started int64 42 resumeAt int64 43 resumeAtStack *int64 // setTimeout stack managed by C (malloc/free) 44 resumeAtStackLen int64 45 resumeAtStackCap int64 46 Params []wavm.Val 47 Results []wavm.Val 48 Funcs []*wavm.Func 49 Globals []*wavm.Global 50 Tables []*wavm.Table 51 Memories []*wavm.Memory 52 Args args 53 } 54 55 type args struct { 56 worker uintptr 57 thunk uintptr 58 fn uintptr 59 trap uintptr 60 argPointer uintptr 61 resultsPointer uintptr 62 args [8]wavm.Val 63 results [8]wavm.Val 64 } 65 66 func (w *Worker) SetArgI32(index int, value int32) { 67 w.Args.args[index].SetI32(value) 68 } 69 func (w *Worker) SetArgF32(index int, value float32) { 70 w.Args.args[index].SetF32(value) 71 } 72 func (w *Worker) SetArgI64(index int, value int64) { 73 w.Args.args[index].SetI64(value) 74 } 75 func (w *Worker) SetArgF64(index int, value float64) { 76 w.Args.args[index].SetF64(value) 77 } 78 func (w *Worker) SetArgV128(index int, value wavm.V128T) { 79 w.Args.args[index].SetV128(value) 80 } 81 func (w *Worker) ResultI32(index int) int32 { 82 return w.Args.results[index].I32() 83 } 84 func (w *Worker) ResultI64(index int) int64 { 85 return w.Args.results[index].I64() 86 } 87 func (w *Worker) ResultF32(index int) float32 { 88 return w.Args.results[index].F32() 89 } 90 func (w *Worker) ResultF64(index int) float64 { 91 return w.Args.results[index].F64() 92 } 93 func (w *Worker) ResultV128(index int) wavm.V128T { 94 return w.Args.results[index].V128() 95 } 96 97 func (w *Worker) init() { 98 const ( 99 secondOffset = unsafe.Sizeof(uintptr(0)) 100 argsPointerOffset = secondOffset + unsafe.Sizeof(uintptr(0)) 101 argsMax = 8 102 argsSize = unsafe.Sizeof(wavm.Val{}) * argsMax 103 resultsPointerOffset = argsPointerOffset + unsafe.Sizeof(uintptr(0)) 104 ) 105 106 w.Args.worker = uintptr(unsafe.Pointer(w)) 107 w.Args.argPointer = uintptr(unsafe.Pointer(&w.Args.args[0])) 108 w.Args.resultsPointer = uintptr(unsafe.Pointer(&w.Args.results[0])) 109 } 110 111 func (w *Worker) Close() error { 112 if w.log != nil { 113 C.free(unsafe.Pointer(w.log)) 114 w.log = nil 115 } 116 if w.resumeAtStack != nil { 117 C.free(unsafe.Pointer(w.resumeAtStack)) 118 w.resumeAtStack = nil 119 } 120 121 w.store.Delete() 122 w.compartment.Delete() 123 w.engine.Delete() 124 return nil 125 } 126 127 func (w *Worker) Start() error { 128 w.begin = Now() 129 if err := w.Call(w.start); err != nil { 130 w.end = Now() 131 return err 132 } 133 w.end = Now() 134 w.started = w.end 135 return nil 136 } 137 138 var ( 139 funcCall = uintptr(unsafe.Pointer(wavm.WASMFuncCall)) 140 funcCallNoCopy = uintptr(unsafe.Pointer(wavm.WASMFuncCallNoCopy)) 141 funcCallNoTrap = uintptr(unsafe.Pointer(wavm.WASMFuncCallNoTrap)) 142 funcCallNoCopyNoTrap = uintptr(unsafe.Pointer(wavm.WASMFuncCallNoCopyNoTrap)) 143 ) 144 145 func (w *Worker) Call(fn *wavm.Func) error { 146 w.Args.fn = uintptr(unsafe.Pointer(fn)) 147 w.Args.thunk = funcCall 148 w.Args.trap = 0 149 w.doCall() 150 if w.Args.trap != 0 { 151 trap := (*wavm.Trap)(unsafe.Pointer(w.Args.trap)) 152 e := fmt.Errorf(trap.String()) 153 trap.Delete() 154 return e 155 } 156 return nil 157 } 158 159 func (w *Worker) CallNoCopy(fn *wavm.Func) error { 160 w.Args.fn = uintptr(unsafe.Pointer(fn)) 161 w.Args.thunk = funcCallNoCopy 162 w.Args.trap = 0 163 w.doCall() 164 if w.Args.trap != 0 { 165 trap := (*wavm.Trap)(unsafe.Pointer(w.Args.trap)) 166 e := fmt.Errorf(trap.String()) 167 trap.Delete() 168 return e 169 } 170 return nil 171 } 172 173 func (w *Worker) CallNoTrap(fn *wavm.Func) error { 174 w.Args.fn = uintptr(unsafe.Pointer(fn)) 175 w.Args.thunk = funcCallNoTrap 176 w.Args.trap = 0 177 w.doCall() 178 if w.Args.trap != 0 { 179 trap := (*wavm.Trap)(unsafe.Pointer(w.Args.trap)) 180 e := fmt.Errorf(trap.String()) 181 trap.Delete() 182 return e 183 } 184 return nil 185 } 186 187 func (w *Worker) CallNoCopyNoTrap(fn *wavm.Func) error { 188 w.Args.fn = uintptr(unsafe.Pointer(fn)) 189 w.Args.thunk = funcCallNoCopyNoTrap 190 w.Args.trap = 0 191 w.doCall() 192 if w.Args.trap != 0 { 193 trap := (*wavm.Trap)(unsafe.Pointer(w.Args.trap)) 194 e := fmt.Errorf(trap.String()) 195 trap.Delete() 196 return e 197 } 198 return nil 199 } 200 201 ////export moontradeSetTimeout 202 //func moontradeSetTimeout(workerPtr unsafe.Pointer, nanos int64) { 203 // worker := (*Worker)(workerPtr) 204 // _ = worker 205 // println("setTimeout", uintptr(workerPtr), nanos) 206 //} 207 208 func moontrade_fd_write() wavm.FuncCallback { 209 return (wavm.FuncCallback)(C.moontrade_fd_write) 210 } 211 212 func moontrade_clock_time_get() wavm.FuncCallback { 213 return (wavm.FuncCallback)(C.moontrade_clock_time_get) 214 } 215 216 func moontrade_args_sizes_get() wavm.FuncCallback { 217 return (wavm.FuncCallback)(C.moontrade_args_sizes_get) 218 } 219 220 func moontrade_args_get() wavm.FuncCallback { 221 return (wavm.FuncCallback)(C.moontrade_args_get) 222 } 223 224 func moontrade_set_timeout() wavm.FuncCallback { 225 return (wavm.FuncCallback)(C.moontrade_set_timeout) 226 } 227 228 //////////////////////////////////////////////////////////////////////////////////////////////////// 229 // Testing Stuff 230 //////////////////////////////////////////////////////////////////////////////////////////////////// 231 func stub_safe() { 232 C.moontrade_stub() 233 } 234 235 func stub_fast() { 236 callStub() 237 } 238 239 func moontrade_benchmark_stub(worker *Worker, n int) { 240 C.moontrade_benchmark_stub((*C.moontrade_worker_t)(unsafe.Pointer(worker)), (C.int64_t)(n)) 241 } 242 243 func moontrade_benchmark_stub_no_copy(worker *Worker, n int) { 244 C.moontrade_benchmark_stub_fn((*C.moontrade_worker_t)(unsafe.Pointer(worker)), unsafe.Pointer((*C.void)(wavm.WASMFuncCallNoCopy)), (C.int64_t)(n)) 245 } 246 247 func moontrade_benchmark_stub_no_trap(worker *Worker, n int) { 248 C.moontrade_benchmark_stub_fn((*C.moontrade_worker_t)(unsafe.Pointer(worker)), unsafe.Pointer((*C.void)(wavm.WASMFuncCallNoTrap)), (C.int64_t)(n)) 249 } 250 251 func moontrade_benchmark_stub_no_copy_no_trap(worker *Worker, n int) { 252 C.moontrade_benchmark_stub_fn((*C.moontrade_worker_t)(unsafe.Pointer(worker)), unsafe.Pointer((*C.void)(wavm.WASMFuncCallNoCopyNoTrap)), (C.int64_t)(n)) 253 }