libgo: update to Go 1.11
[official-gcc.git] / libgo / go / runtime / os_netbsd.go
blobea47e5cdc82dec2ff7cc4ebdf5856e1f7abcfdd3
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 "runtime/internal/sys"
10 "unsafe"
13 type mOS struct {
14 waitsemacount uint32
17 //go:noescape
18 //extern lwp_park
19 func lwp_park(ts int32, rel int32, abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
21 //go:noescape
22 //extern lwp_unpark
23 func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
25 //go:nosplit
26 func semacreate(mp *m) {
29 //go:nosplit
30 func semasleep(ns int64) int32 {
31 _g_ := getg()
33 // Compute sleep deadline.
34 var tsp *timespec
35 var ts timespec
36 if ns >= 0 {
37 var nsec int32
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(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
54 if ret == _ETIMEDOUT {
55 return -1
56 } else if ret == _EINTR && ns >= 0 {
57 // Avoid sleeping forever if we keep getting
58 // interrupted (for example by the profiling
59 // timer). It would be if tsp upon return had the
60 // remaining time to sleep, but this is good enough.
61 var nsec int32
62 ns /= 2
63 ts.set_sec(timediv(ns, 1000000000, &nsec))
64 ts.set_nsec(nsec)
69 //go:nosplit
70 func semawakeup(mp *m) {
71 atomic.Xadd(&mp.mos.waitsemacount, 1)
72 // From NetBSD's _lwp_unpark(2) manual:
73 // "If the target LWP is not currently waiting, it will return
74 // immediately upon the next call to _lwp_park()."
75 ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.mos.waitsemacount))
76 if ret != 0 && ret != _ESRCH {
77 // semawakeup can be called on signal stack.
78 systemstack(func() {
79 print("thrwakeup addr=", &mp.mos.waitsemacount, " sem=", mp.mos.waitsemacount, " ret=", ret, "\n")