mirror of
https://github.com/golang/go
synced 2024-09-30 13:28:38 -06: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
|
// so it emits the test and keeps the call, giving the desired
|
||||||
// escape analysis result. The test is cheaper than the call.
|
// escape analysis result. The test is cheaper than the call.
|
||||||
var cgoAlwaysFalse bool
|
var cgoAlwaysFalse bool
|
||||||
|
|
||||||
|
var cgo_yield = &_cgo_yield
|
||||||
|
@ -141,15 +141,15 @@ func notesleep(n *note) {
|
|||||||
throw("notesleep not on g0")
|
throw("notesleep not on g0")
|
||||||
}
|
}
|
||||||
ns := int64(-1)
|
ns := int64(-1)
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
||||||
ns = 10e6
|
ns = 10e6
|
||||||
}
|
}
|
||||||
for atomic.Load(key32(&n.key)) == 0 {
|
for atomic.Load(key32(&n.key)) == 0 {
|
||||||
gp.m.blocked = true
|
gp.m.blocked = true
|
||||||
futexsleep(key32(&n.key), 0, ns)
|
futexsleep(key32(&n.key), 0, ns)
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
gp.m.blocked = false
|
gp.m.blocked = false
|
||||||
}
|
}
|
||||||
@ -164,15 +164,15 @@ func notetsleep_internal(n *note, ns int64) bool {
|
|||||||
gp := getg()
|
gp := getg()
|
||||||
|
|
||||||
if ns < 0 {
|
if ns < 0 {
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
||||||
ns = 10e6
|
ns = 10e6
|
||||||
}
|
}
|
||||||
for atomic.Load(key32(&n.key)) == 0 {
|
for atomic.Load(key32(&n.key)) == 0 {
|
||||||
gp.m.blocked = true
|
gp.m.blocked = true
|
||||||
futexsleep(key32(&n.key), 0, ns)
|
futexsleep(key32(&n.key), 0, ns)
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
gp.m.blocked = false
|
gp.m.blocked = false
|
||||||
}
|
}
|
||||||
@ -185,13 +185,13 @@ func notetsleep_internal(n *note, ns int64) bool {
|
|||||||
|
|
||||||
deadline := nanotime() + ns
|
deadline := nanotime() + ns
|
||||||
for {
|
for {
|
||||||
if _cgo_yield != nil && ns > 10e6 {
|
if *cgo_yield != nil && ns > 10e6 {
|
||||||
ns = 10e6
|
ns = 10e6
|
||||||
}
|
}
|
||||||
gp.m.blocked = true
|
gp.m.blocked = true
|
||||||
futexsleep(key32(&n.key), 0, ns)
|
futexsleep(key32(&n.key), 0, ns)
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
gp.m.blocked = false
|
gp.m.blocked = false
|
||||||
if atomic.Load(key32(&n.key)) != 0 {
|
if atomic.Load(key32(&n.key)) != 0 {
|
||||||
|
@ -163,14 +163,14 @@ func notesleep(n *note) {
|
|||||||
}
|
}
|
||||||
// Queued. Sleep.
|
// Queued. Sleep.
|
||||||
gp.m.blocked = true
|
gp.m.blocked = true
|
||||||
if _cgo_yield == nil {
|
if *cgo_yield == nil {
|
||||||
semasleep(-1)
|
semasleep(-1)
|
||||||
} else {
|
} else {
|
||||||
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
// Sleep for an arbitrary-but-moderate interval to poll libc interceptors.
|
||||||
const ns = 10e6
|
const ns = 10e6
|
||||||
for atomic.Loaduintptr(&n.key) == 0 {
|
for atomic.Loaduintptr(&n.key) == 0 {
|
||||||
semasleep(ns)
|
semasleep(ns)
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gp.m.blocked = false
|
gp.m.blocked = false
|
||||||
@ -195,13 +195,13 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
|
|||||||
if ns < 0 {
|
if ns < 0 {
|
||||||
// Queued. Sleep.
|
// Queued. Sleep.
|
||||||
gp.m.blocked = true
|
gp.m.blocked = true
|
||||||
if _cgo_yield == nil {
|
if *cgo_yield == nil {
|
||||||
semasleep(-1)
|
semasleep(-1)
|
||||||
} else {
|
} else {
|
||||||
// Sleep in arbitrary-but-moderate intervals to poll libc interceptors.
|
// Sleep in arbitrary-but-moderate intervals to poll libc interceptors.
|
||||||
const ns = 10e6
|
const ns = 10e6
|
||||||
for semasleep(ns) < 0 {
|
for semasleep(ns) < 0 {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gp.m.blocked = false
|
gp.m.blocked = false
|
||||||
@ -212,7 +212,7 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
|
|||||||
for {
|
for {
|
||||||
// Registered. Sleep.
|
// Registered. Sleep.
|
||||||
gp.m.blocked = true
|
gp.m.blocked = true
|
||||||
if _cgo_yield != nil && ns > 10e6 {
|
if *cgo_yield != nil && ns > 10e6 {
|
||||||
ns = 10e6
|
ns = 10e6
|
||||||
}
|
}
|
||||||
if semasleep(ns) >= 0 {
|
if semasleep(ns) >= 0 {
|
||||||
@ -221,8 +221,8 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
|
|||||||
// Done.
|
// Done.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
gp.m.blocked = false
|
gp.m.blocked = false
|
||||||
// Interrupted or timed out. Still registered. Semaphore not acquired.
|
// Interrupted or timed out. Still registered. Semaphore not acquired.
|
||||||
|
@ -1903,8 +1903,8 @@ top:
|
|||||||
ready(gp, 0, true)
|
ready(gp, 0, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// local runq
|
// local runq
|
||||||
@ -3760,8 +3760,8 @@ func sysmon() {
|
|||||||
unlock(&sched.lock)
|
unlock(&sched.lock)
|
||||||
}
|
}
|
||||||
// trigger libc interceptors if needed
|
// trigger libc interceptors if needed
|
||||||
if _cgo_yield != nil {
|
if *cgo_yield != nil {
|
||||||
asmcgocall(_cgo_yield, nil)
|
asmcgocall(*cgo_yield, nil)
|
||||||
}
|
}
|
||||||
// poll network if not polled for more than 10ms
|
// poll network if not polled for more than 10ms
|
||||||
lastpoll := int64(atomic.Load64(&sched.lastpoll))
|
lastpoll := int64(atomic.Load64(&sched.lastpoll))
|
||||||
|
Loading…
Reference in New Issue
Block a user