gcc/libgo/go/runtime/os_netbsd.go
Ian Lance Taylor c0401cf78c runtime: copy internal locking code from Go 1.7 runtime
Remove the old locking code written in C.
    
    Add a shell script mkrsysinfo.sh to generate the runtime_sysinfo.go
    file, so that we can get Go copies of the system time structures and
    other types.
    
    Tweak the compiler so that when compiling the runtime package the
    address operator does not cause local variables to escape.  When the gc
    compiler compiles the runtime, an escaping local variable is treated as
    an error.  We should implement that, instead of this change, when escape
    analysis is turned on.
    
    Tweak the compiler so that the generated C header does not include names
    that start with an underscore followed by a non-upper-case letter,
    except for the special cases of _defer and _panic.  Otherwise we
    translate C types to Go in runtime_sysinfo.go and then generate those Go
    types back as C types in runtime.inc, which is useless and painful for
    the C code.
    
    Change entersyscall and friends to take a dummy argument, as the gc
    versions do, to simplify calls from the shared code.
    
    Reviewed-on: https://go-review.googlesource.com/30079

From-SVN: r240657
2016-09-30 13:45:08 +00:00

74 lines
1.6 KiB
Go

// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import (
"runtime/internal/atomic"
"unsafe"
)
type mOS struct {
waitsemacount uint32
}
//go:noescape
//extern lwp_park
func lwp_park(abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
//go:noescape
//extern lwp_unpark
func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
//go:nosplit
func semacreate(mp *m) {
}
//go:nosplit
func semasleep(ns int64) int32 {
_g_ := getg()
// Compute sleep deadline.
var tsp *timespec
if ns >= 0 {
var ts timespec
var nsec int32
ns += nanotime()
ts.set_sec(int64(timediv(ns, 1000000000, &nsec)))
ts.set_nsec(nsec)
tsp = &ts
}
for {
v := atomic.Load(&_g_.m.mos.waitsemacount)
if v > 0 {
if atomic.Cas(&_g_.m.mos.waitsemacount, v, v-1) {
return 0 // semaphore acquired
}
continue
}
// Sleep until unparked by semawakeup or timeout.
ret := lwp_park(tsp, 0, unsafe.Pointer(&_g_.m.mos.waitsemacount), nil)
if ret == _ETIMEDOUT {
return -1
}
}
}
//go:nosplit
func semawakeup(mp *m) {
atomic.Xadd(&mp.mos.waitsemacount, 1)
// From NetBSD's _lwp_unpark(2) manual:
// "If the target LWP is not currently waiting, it will return
// immediately upon the next call to _lwp_park()."
ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.mos.waitsemacount))
if ret != 0 && ret != _ESRCH {
// semawakeup can be called on signal stack.
systemstack(func() {
print("thrwakeup addr=", &mp.mos.waitsemacount, " sem=", mp.mos.waitsemacount, " ret=", ret, "\n")
})
}
}