github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/lock_wasip1.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build wasip1 6 7 package runtime 8 9 // wasm has no support for threads yet. There is no preemption. 10 // See proposal: https://github.com/WebAssembly/threads 11 // Waiting for a mutex or timeout is implemented as a busy loop 12 // while allowing other goroutines to run. 13 14 const ( 15 mutex_unlocked = 0 16 mutex_locked = 1 17 18 active_spin = 4 19 active_spin_cnt = 30 20 ) 21 22 func lock(l *mutex) { 23 lockWithRank(l, getLockRank(l)) 24 } 25 26 func lock2(l *mutex) { 27 if l.key == mutex_locked { 28 // wasm is single-threaded so we should never 29 // observe this. 30 throw("self deadlock") 31 } 32 gp := getg() 33 if gp.m.locks < 0 { 34 throw("lock count") 35 } 36 gp.m.locks++ 37 l.key = mutex_locked 38 } 39 40 func unlock(l *mutex) { 41 unlockWithRank(l) 42 } 43 44 func unlock2(l *mutex) { 45 if l.key == mutex_unlocked { 46 throw("unlock of unlocked lock") 47 } 48 gp := getg() 49 gp.m.locks-- 50 if gp.m.locks < 0 { 51 throw("lock count") 52 } 53 l.key = mutex_unlocked 54 } 55 56 // One-time notifications. 57 func noteclear(n *note) { 58 n.key = 0 59 } 60 61 func notewakeup(n *note) { 62 if n.key != 0 { 63 print("notewakeup - double wakeup (", n.key, ")\n") 64 throw("notewakeup - double wakeup") 65 } 66 n.key = 1 67 } 68 69 func notesleep(n *note) { 70 throw("notesleep not supported by wasi") 71 } 72 73 func notetsleep(n *note, ns int64) bool { 74 throw("notetsleep not supported by wasi") 75 return false 76 } 77 78 // same as runtimeĀ·notetsleep, but called on user g (not g0) 79 func notetsleepg(n *note, ns int64) bool { 80 gp := getg() 81 if gp == gp.m.g0 { 82 throw("notetsleepg on g0") 83 } 84 85 deadline := nanotime() + ns 86 for { 87 if n.key != 0 { 88 return true 89 } 90 if sched_yield() != 0 { 91 throw("sched_yield failed") 92 } 93 Gosched() 94 if ns >= 0 && nanotime() >= deadline { 95 return false 96 } 97 } 98 } 99 100 func beforeIdle(int64, int64) (*g, bool) { 101 return nil, false 102 } 103 104 func checkTimeouts() {} 105 106 //go:wasmimport wasi_snapshot_preview1 sched_yield 107 func sched_yield() errno