aboutsummaryrefslogtreecommitdiff
path: root/libgo/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-10-21 20:07:06 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-10-21 20:07:06 +0000
commite597e0533d69081e6d6b01ca19f2924c1b8307ff (patch)
tree7c1aa0e24fac610637343c40fe8b6a76b60f3ccc /libgo/go
parent16b61424dd309f61326f577a6deb8487c6c1f291 (diff)
downloadgcc-e597e0533d69081e6d6b01ca19f2924c1b8307ff.zip
gcc-e597e0533d69081e6d6b01ca19f2924c1b8307ff.tar.gz
gcc-e597e0533d69081e6d6b01ca19f2924c1b8307ff.tar.bz2
runtime: copy lfstack code from Go 1.7 runtime
Note that lfstack_64bit.go was modified for Solaris support in a different, and better, way than the superseded lfstack.goc code. Reviewed-on: https://go-review.googlesource.com/31673 From-SVN: r241427
Diffstat (limited to 'libgo/go')
-rw-r--r--libgo/go/runtime/export_test.go14
-rw-r--r--libgo/go/runtime/lfstack.go50
-rw-r--r--libgo/go/runtime/lfstack_32bit.go19
-rw-r--r--libgo/go/runtime/lfstack_64bit.go8
4 files changed, 82 insertions, 9 deletions
diff --git a/libgo/go/runtime/export_test.go b/libgo/go/runtime/export_test.go
index 711a551..d3443566 100644
--- a/libgo/go/runtime/export_test.go
+++ b/libgo/go/runtime/export_test.go
@@ -6,6 +6,10 @@
package runtime
+import (
+ "unsafe"
+)
+
//var Fadd64 = fadd64
//var Fsub64 = fsub64
//var Fmul64 = fmul64
@@ -32,11 +36,13 @@ type LFNode struct {
Pushcnt uintptr
}
-func lfstackpush_go(head *uint64, node *LFNode)
-func lfstackpop_go(head *uint64) *LFNode
+func LFStackPush(head *uint64, node *LFNode) {
+ lfstackpush(head, (*lfnode)(unsafe.Pointer(node)))
+}
-var LFStackPush = lfstackpush_go
-var LFStackPop = lfstackpop_go
+func LFStackPop(head *uint64) *LFNode {
+ return (*LFNode)(unsafe.Pointer(lfstackpop(head)))
+}
type ParFor struct {
body func(*ParFor, uint32)
diff --git a/libgo/go/runtime/lfstack.go b/libgo/go/runtime/lfstack.go
new file mode 100644
index 0000000..2f2958c
--- /dev/null
+++ b/libgo/go/runtime/lfstack.go
@@ -0,0 +1,50 @@
+// Copyright 2012 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.
+
+// Lock-free stack.
+// Initialize head to 0, compare with 0 to test for emptiness.
+// The stack does not keep pointers to nodes,
+// so they can be garbage collected if there are no other pointers to nodes.
+// The following code runs only in non-preemptible contexts.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// Temporary for C code to call:
+//go:linkname lfstackpush runtime.lfstackpush
+//go:linkname lfstackpop runtime.lfstackpop
+
+func lfstackpush(head *uint64, node *lfnode) {
+ node.pushcnt++
+ new := lfstackPack(node, node.pushcnt)
+ if node1 := lfstackUnpack(new); node1 != node {
+ print("runtime: lfstackpush invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
+ throw("lfstackpush")
+ }
+ for {
+ old := atomic.Load64(head)
+ node.next = old
+ if atomic.Cas64(head, old, new) {
+ break
+ }
+ }
+}
+
+func lfstackpop(head *uint64) unsafe.Pointer {
+ for {
+ old := atomic.Load64(head)
+ if old == 0 {
+ return nil
+ }
+ node := lfstackUnpack(old)
+ next := atomic.Load64(&node.next)
+ if atomic.Cas64(head, old, next) {
+ return unsafe.Pointer(node)
+ }
+ }
+}
diff --git a/libgo/go/runtime/lfstack_32bit.go b/libgo/go/runtime/lfstack_32bit.go
new file mode 100644
index 0000000..6a99200
--- /dev/null
+++ b/libgo/go/runtime/lfstack_32bit.go
@@ -0,0 +1,19 @@
+// 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.
+
+// +build 386 arm nacl armbe m68k mips mipsle mips64p32 mips64p32le mipso32 mipsn32 s390 sparc
+
+package runtime
+
+import "unsafe"
+
+// On 32-bit systems, the stored uint64 has a 32-bit pointer and 32-bit count.
+
+func lfstackPack(node *lfnode, cnt uintptr) uint64 {
+ return uint64(uintptr(unsafe.Pointer(node)))<<32 | uint64(cnt)
+}
+
+func lfstackUnpack(val uint64) *lfnode {
+ return (*lfnode)(unsafe.Pointer(uintptr(val >> 32)))
+}
diff --git a/libgo/go/runtime/lfstack_64bit.go b/libgo/go/runtime/lfstack_64bit.go
index 3b0eb98..213efb1 100644
--- a/libgo/go/runtime/lfstack_64bit.go
+++ b/libgo/go/runtime/lfstack_64bit.go
@@ -2,9 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build ignore
-
-// +build amd64 arm64 mips64 mips64le ppc64 ppc64le s390x
+// +build amd64 arm64 mips64 mips64le ppc64 ppc64le s390x arm64be alpha mipsn64 sparc64
package runtime
@@ -41,8 +39,8 @@ func lfstackPack(node *lfnode, cnt uintptr) uint64 {
}
func lfstackUnpack(val uint64) *lfnode {
- if GOARCH == "amd64" {
- // amd64 systems can place the stack above the VA hole, so we need to sign extend
+ if GOARCH == "amd64" || GOOS == "solaris" {
+ // amd64 or Solaris systems can place the stack above the VA hole, so we need to sign extend
// val before unpacking.
return (*lfnode)(unsafe.Pointer(uintptr(int64(val) >> cntBits << 3)))
}