]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: access _cgo_yield indirectly
authorCherry Zhang <cherryyz@google.com>
Fri, 24 Mar 2017 02:47:56 +0000 (22:47 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 24 Mar 2017 15:37:56 +0000 (15:37 +0000)
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>
src/runtime/cgo.go
src/runtime/lock_futex.go
src/runtime/lock_sema.go
src/runtime/proc.go

index 16ca004ee0380a2d4410f8d6d2d16092caf8df7a..395d54a66e249b9fb6404bbffa9405df19393eed 100644 (file)
@@ -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
index c3ed3be00b92f569bf42d2dc3eea4d0653424a48..45d3da64a412204af1e834d82d77ca5f119137bf 100644 (file)
@@ -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 {
index 4a8295ff4722b1e0a5b41d726067ba7e4f86c74b..5b0169d572564097e4f2e15b0293ed72092f0492 100644 (file)
@@ -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.
index 159a9bd4bc3be08a083d5d1b6c9adf4659366c93..8dede3fb2370c1f3a8aa02ee49192ea7d7c56e74 100644 (file)
@@ -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))