github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 mutexContended(l *mutex) bool { 23 return false 24 } 25 26 func lock(l *mutex) { 27 lockWithRank(l, getLockRank(l)) 28 } 29 30 func 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 44 func unlock(l *mutex) { 45 unlockWithRank(l) 46 } 47 48 func 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. 61 func noteclear(n *note) { 62 n.key = 0 63 } 64 65 func 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 73 func notesleep(n *note) { 74 throw("notesleep not supported by wasi") 75 } 76 77 func 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) 83 func 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 104 func beforeIdle(int64, int64) (*g, bool) { 105 return nil, false 106 } 107 108 func checkTimeouts() {} 109 110 //go:wasmimport wasi_snapshot_preview1 sched_yield 111 func sched_yield() errno