* builtins.def (BUILT_IN_SETJMP): Revert latest change.
[official-gcc.git] / libgo / go / runtime / os_netbsd.go
blob464ce88d9c4d169a5faa9eb6913d111ffd5058d2
1 // Copyright 2014 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.
5 package runtime
7 import (
8 "runtime/internal/atomic"
9 "unsafe"
12 type mOS struct {
13 waitsemacount uint32
16 //go:noescape
17 //extern lwp_park
18 func lwp_park(abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
20 //go:noescape
21 //extern lwp_unpark
22 func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
24 //go:nosplit
25 func semacreate(mp *m) {
28 //go:nosplit
29 func semasleep(ns int64) int32 {
30 _g_ := getg()
32 // Compute sleep deadline.
33 var tsp *timespec
34 if ns >= 0 {
35 var ts timespec
36 var nsec int32
37 ns += nanotime()
38 ts.set_sec(int64(timediv(ns, 1000000000, &nsec)))
39 ts.set_nsec(nsec)
40 tsp = &ts
43 for {
44 v := atomic.Load(&_g_.m.mos.waitsemacount)
45 if v > 0 {
46 if atomic.Cas(&_g_.m.mos.waitsemacount, v, v-1) {
47 return 0 // semaphore acquired
49 continue
52 // Sleep until unparked by semawakeup or timeout.
53 ret := lwp_park(tsp, 0, unsafe.Pointer(&_g_.m.mos.waitsemacount), nil)
54 if ret == _ETIMEDOUT {
55 return -1
60 //go:nosplit
61 func semawakeup(mp *m) {
62 atomic.Xadd(&mp.mos.waitsemacount, 1)
63 // From NetBSD's _lwp_unpark(2) manual:
64 // "If the target LWP is not currently waiting, it will return
65 // immediately upon the next call to _lwp_park()."
66 ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.mos.waitsemacount))
67 if ret != 0 && ret != _ESRCH {
68 // semawakeup can be called on signal stack.
69 systemstack(func() {
70 print("thrwakeup addr=", &mp.mos.waitsemacount, " sem=", mp.mos.waitsemacount, " ret=", ret, "\n")