mirror of
https://github.com/golang/go
synced 2024-11-18 06:04:53 -07:00
runtime: access _cgo_yield indirectly
The darwin linker for ARM does not allow PC-relative relocation of external symbol in text section. Work around it by accessing it indirectly: putting its address in a global variable (which is not external), and accessing through that variable. Fixes #19684. Change-Id: I41361bbb281b5dbdda0d100ae49d32c69ed85a81 Reviewed-on: https://go-review.googlesource.com/38596 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Elias Naur <elias.naur@gmail.com>
This commit is contained in:
parent
48de5a85fb
commit
3a1ce1085a
@ -50,3 +50,5 @@ func cgoUse(interface{}) { throw("cgoUse should not be called") }
|
||||
// so it emits the test and keeps the call, giving the desired
|
||||
// escape analysis result. The test is cheaper than the call.
|
||||
var cgoAlwaysFalse bool
|
||||
|
||||
var cgo_yield = &_cgo_yield
|
||||
|
@ -141,15 +141,15 @@ func notesleep(n *note) {
|
||||
throw("notesleep not on g0")
|
||||
}
|
||||
ns := int64(-1)
|
||||
if _cgo_yield != nil {
|
||||
if *cgo_yield != nil {
|
||||
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
||||
ns = 10e6
|
||||
}
|
||||
for atomic.Load(key32(&n.key)) == 0 {
|
||||
gp.m.blocked = true
|
||||
futexsleep(key32(&n.key), 0, ns)
|
||||
if _cgo_yield != nil {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
gp.m.blocked = false
|
||||
}
|
||||
@ -164,15 +164,15 @@ func notetsleep_internal(n *note, ns int64) bool {
|
||||
gp := getg()
|
||||
|
||||
if ns < 0 {
|
||||
if _cgo_yield != nil {
|
||||
if *cgo_yield != nil {
|
||||
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
||||
ns = 10e6
|
||||
}
|
||||
for atomic.Load(key32(&n.key)) == 0 {
|
||||
gp.m.blocked = true
|
||||
futexsleep(key32(&n.key), 0, ns)
|
||||
if _cgo_yield != nil {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
gp.m.blocked = false
|
||||
}
|
||||
@ -185,13 +185,13 @@ func notetsleep_internal(n *note, ns int64) bool {
|
||||
|
||||
deadline := nanotime() + ns
|
||||
for {
|
||||
if _cgo_yield != nil && ns > 10e6 {
|
||||
if *cgo_yield != nil && ns > 10e6 {
|
||||
ns = 10e6
|
||||
}
|
||||
gp.m.blocked = true
|
||||
futexsleep(key32(&n.key), 0, ns)
|
||||
if _cgo_yield != nil {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
gp.m.blocked = false
|
||||
if atomic.Load(key32(&n.key)) != 0 {
|
||||
|
@ -163,14 +163,14 @@ func notesleep(n *note) {
|
||||
}
|
||||
// Queued. Sleep.
|
||||
gp.m.blocked = true
|
||||
if _cgo_yield == nil {
|
||||
if *cgo_yield == nil {
|
||||
semasleep(-1)
|
||||
} else {
|
||||
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
||||
const ns = 10e6
|
||||
for atomic.Loaduintptr(&n.key) == 0 {
|
||||
semasleep(ns)
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
}
|
||||
gp.m.blocked = false
|
||||
@ -195,13 +195,13 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
|
||||
if ns < 0 {
|
||||
// Queued. Sleep.
|
||||
gp.m.blocked = true
|
||||
if _cgo_yield == nil {
|
||||
if *cgo_yield == nil {
|
||||
semasleep(-1)
|
||||
} else {
|
||||
// Sleep in arbitrary-but-moderate intervals to poll libc interceptors.
|
||||
const ns = 10e6
|
||||
for semasleep(ns) < 0 {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
}
|
||||
gp.m.blocked = false
|
||||
@ -212,7 +212,7 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
|
||||
for {
|
||||
// Registered. Sleep.
|
||||
gp.m.blocked = true
|
||||
if _cgo_yield != nil && ns > 10e6 {
|
||||
if *cgo_yield != nil && ns > 10e6 {
|
||||
ns = 10e6
|
||||
}
|
||||
if semasleep(ns) >= 0 {
|
||||
@ -221,8 +221,8 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
|
||||
// Done.
|
||||
return true
|
||||
}
|
||||
if _cgo_yield != nil {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
gp.m.blocked = false
|
||||
// Interrupted or timed out. Still registered. Semaphore not acquired.
|
||||
|
@ -1903,8 +1903,8 @@ top:
|
||||
ready(gp, 0, true)
|
||||
}
|
||||
}
|
||||
if _cgo_yield != nil {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
|
||||
// local runq
|
||||
@ -3760,8 +3760,8 @@ func sysmon() {
|
||||
unlock(&sched.lock)
|
||||
}
|
||||
// trigger libc interceptors if needed
|
||||
if _cgo_yield != nil {
|
||||
asmcgocall(_cgo_yield, nil)
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
}
|
||||
// poll network if not polled for more than 10ms
|
||||
lastpoll := int64(atomic.Load64(&sched.lastpoll))
|
||||
|
Loading…
Reference in New Issue
Block a user