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 7package 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 14const ( 15 mutex_unlocked = 0 16 mutex_locked = 1 17 18 active_spin = 4 19 active_spin_cnt = 30 20) 21 22func mutexContended(l *mutex) bool { 23 return false 24} 25 26func lock(l *mutex) { 27 lockWithRank(l, getLockRank(l)) 28} 29 30func lock2(l *mutex) { 31 if l.key == mutex_locked { 32 // wasm is single-threaded so we should never 33 // observe this. 34 throw("self deadlock") 35 } 36 gp := getg() 37 if gp.m.locks < 0 { 38 throw("lock count") 39 } 40 gp.m.locks++ 41 l.key = mutex_locked 42} 43 44func unlock(l *mutex) { 45 unlockWithRank(l) 46} 47 48func unlock2(l *mutex) { 49 if l.key == mutex_unlocked { 50 throw("unlock of unlocked lock") 51 } 52 gp := getg() 53 gp.m.locks-- 54 if gp.m.locks < 0 { 55 throw("lock count") 56 } 57 l.key = mutex_unlocked 58} 59 60// One-time notifications. 61func noteclear(n *note) { 62 n.key = 0 63} 64 65func notewakeup(n *note) { 66 if n.key != 0 { 67 print("notewakeup - double wakeup (", n.key, ")\n") 68 throw("notewakeup - double wakeup") 69 } 70 n.key = 1 71} 72 73func notesleep(n *note) { 74 throw("notesleep not supported by wasi") 75} 76 77func notetsleep(n *note, ns int64) bool { 78 throw("notetsleep not supported by wasi") 79 return false 80} 81 82// same as runtime·notetsleep, but called on user g (not g0) 83func notetsleepg(n *note, ns int64) bool { 84 gp := getg() 85 if gp == gp.m.g0 { 86 throw("notetsleepg on g0") 87 } 88 89 deadline := nanotime() + ns 90 for { 91 if n.key != 0 { 92 return true 93 } 94 if sched_yield() != 0 { 95 throw("sched_yield failed") 96 } 97 Gosched() 98 if ns >= 0 && nanotime() >= deadline { 99 return false 100 } 101 } 102} 103 104func beforeIdle(int64, int64) (*g, bool) { 105 return nil, false 106} 107 108func checkTimeouts() {} 109 110//go:wasmimport wasi_snapshot_preview1 sched_yield 111func sched_yield() errno 112