From c3ab26e8bb0c5bf1c20358d036f987a20734c9ad Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 16 Feb 2018 16:42:53 +0000 Subject: runtime: add some more preemption checks In particular this lets BenchmarkPingPongHog in runtime/proc_test.go complete. Reviewed-on: https://go-review.googlesource.com/94735 From-SVN: r257743 --- libgo/go/runtime/chan.go | 10 ++++++++++ libgo/go/runtime/hashmap.go | 25 +++++++++++++++++++++++++ libgo/go/runtime/malloc.go | 1 + libgo/go/runtime/proc.go | 5 +++-- libgo/go/runtime/select.go | 7 +++++++ 5 files changed, 46 insertions(+), 2 deletions(-) (limited to 'libgo/go') diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go index bf708ae..87f7879 100644 --- a/libgo/go/runtime/chan.go +++ b/libgo/go/runtime/chan.go @@ -148,6 +148,11 @@ func chansend1(c *hchan, elem unsafe.Pointer) { * the operation; we'll see that it's now closed. */ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + if c == nil { if !block { return false @@ -430,6 +435,11 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) print("chanrecv: chan=", c, "\n") } + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + if c == nil { if !block { return diff --git a/libgo/go/runtime/hashmap.go b/libgo/go/runtime/hashmap.go index a1fe49e..aba9abd 100644 --- a/libgo/go/runtime/hashmap.go +++ b/libgo/go/runtime/hashmap.go @@ -356,6 +356,11 @@ func makemap(t *maptype, hint int, h *hmap) *hmap { // NOTE: The returned pointer may keep the whole map live, so don't // hold onto it for very long. func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + if raceenabled && h != nil { callerpc := getcallerpc() pc := funcPC(mapaccess1) @@ -409,6 +414,11 @@ func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { } func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) { + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + if raceenabled && h != nil { callerpc := getcallerpc() pc := funcPC(mapaccess2) @@ -463,6 +473,11 @@ func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) // returns both key and value. Used by map iterator func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) { + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + if h == nil || h.count == 0 { return nil, nil } @@ -521,6 +536,11 @@ func mapaccess2_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) (unsafe.Point // Like mapaccess, but allocates a slot for the key if it is not present in the map. func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + if h == nil { panic(plainError("assignment to entry in nil map")) } @@ -772,6 +792,11 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) { } func mapiternext(it *hiter) { + // Check preemption, since unlike gc we don't check on every call. + if getg().preempt { + checkPreempt() + } + h := it.h if raceenabled { callerpc := getcallerpc() diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index 88e4ba3..c27aa48 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -826,6 +826,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } } + // Check preemption, since unlike gc we don't check on every call. if getg().preempt { checkPreempt() } diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index edf4140..1d95109 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -4084,8 +4084,9 @@ func preemptone(_p_ *p) bool { // setting a global variable and figuring out a way to efficiently // check that global variable. // - // For now we check gp.preempt in schedule and mallocgc, - // which is at least better than doing nothing at all. + // For now we check gp.preempt in schedule, mallocgc, selectgo, + // and a few other places, which is at least better than doing + // nothing at all. return true } diff --git a/libgo/go/runtime/select.go b/libgo/go/runtime/select.go index 096af52..1c5124b 100644 --- a/libgo/go/runtime/select.go +++ b/libgo/go/runtime/select.go @@ -584,6 +584,13 @@ retc: if cas.releasetime > 0 { blockevent(cas.releasetime-t0, 1) } + + // Check preemption, since unlike gc we don't check on every call. + // A test case for this one is BenchmarkPingPongHog in proc_test.go. + if dfl != nil && getg().preempt { + checkPreempt() + } + return casi sclose: -- cgit v1.1 From 911cef2e3ba7548ee13e761f88457c6bbe1fa7fe Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 20 Feb 2018 15:30:31 +0000 Subject: runtime: allow preemption in fast syscall return Let a fast syscall return be a preemption point. This helps with tight loops that make system calls, as in BenchmarkSyscallExcessWork. Reviewed-on: https://go-review.googlesource.com/94895 From-SVN: r257848 --- libgo/go/runtime/proc.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'libgo/go') diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index 1d95109..20fa0ad 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -2794,6 +2794,13 @@ func exitsyscall(dummy int32) { exitsyscallclear(_g_) _g_.m.locks-- _g_.throwsplit = false + + // Check preemption, since unlike gc we don't check on + // every call. + if getg().preempt { + checkPreempt() + } + return } -- cgit v1.1 From b613cc2e9120ea002f8a0855d2620ee4ba8fbfe5 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 22 Feb 2018 19:49:04 +0000 Subject: re PR go/84484 (libgo configure tests fail to find -latomic) PR go/84484 libgo: add support for riscv64 Patch by Andreas Schwab. Reviewed-on: https://go-review.googlesource.com/96377 * go.test/go-test.exp (go-set-goarch): Recognize riscv64-*-*. From-SVN: r257914 --- libgo/go/cmd/cgo/main.go | 2 ++ libgo/go/go/build/syslist.go | 2 +- libgo/go/internal/syscall/unix/getrandom_linux_generic.go | 2 +- libgo/go/runtime/hash64.go | 2 +- libgo/go/runtime/lfstack_64bit.go | 2 +- libgo/go/runtime/unaligned1.go | 2 +- libgo/go/syscall/endian_little.go | 2 +- libgo/go/syscall/libcall_linux_ustat.go | 2 +- 8 files changed, 9 insertions(+), 7 deletions(-) (limited to 'libgo/go') diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go index f5c231c..6baabfd 100644 --- a/libgo/go/cmd/cgo/main.go +++ b/libgo/go/cmd/cgo/main.go @@ -168,6 +168,7 @@ var ptrSizeMap = map[string]int64{ "ppc": 4, "ppc64": 8, "ppc64le": 8, + "riscv64": 8, "s390": 4, "s390x": 8, "sh": 4, @@ -192,6 +193,7 @@ var intSizeMap = map[string]int64{ "ppc": 4, "ppc64": 8, "ppc64le": 8, + "riscv64": 8, "s390": 4, "s390x": 8, "sh": 4, diff --git a/libgo/go/go/build/syslist.go b/libgo/go/go/build/syslist.go index 6bf7263..679d195 100644 --- a/libgo/go/go/build/syslist.go +++ b/libgo/go/go/build/syslist.go @@ -5,4 +5,4 @@ package build const goosList = "aix android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows zos " -const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be alpha m68k ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sh shbe sparc sparc64" +const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be alpha m68k ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv64 s390 s390x sh shbe sparc sparc64" diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go index 8425800..d6af3de 100644 --- a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go +++ b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build arm64 +// +build arm64 riscv64 package unix diff --git a/libgo/go/runtime/hash64.go b/libgo/go/runtime/hash64.go index 5912943..74775a8 100644 --- a/libgo/go/runtime/hash64.go +++ b/libgo/go/runtime/hash64.go @@ -6,7 +6,7 @@ // xxhash: https://code.google.com/p/xxhash/ // cityhash: https://code.google.com/p/cityhash/ -// +build amd64 amd64p32 arm64 mips64 mips64le ppc64 ppc64le s390x alpha arm64be ia64 mips64p32 mips64p32le sparc64 +// +build amd64 amd64p32 arm64 mips64 mips64le ppc64 ppc64le s390x alpha arm64be ia64 mips64p32 mips64p32le sparc64 riscv64 package runtime diff --git a/libgo/go/runtime/lfstack_64bit.go b/libgo/go/runtime/lfstack_64bit.go index 95d0eba..dca1718 100644 --- a/libgo/go/runtime/lfstack_64bit.go +++ b/libgo/go/runtime/lfstack_64bit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64 arm64 mips64 mips64le ppc64 ppc64le s390x arm64be alpha sparc64 ia64 +// +build amd64 arm64 mips64 mips64le ppc64 ppc64le s390x arm64be alpha sparc64 ia64 riscv64 package runtime diff --git a/libgo/go/runtime/unaligned1.go b/libgo/go/runtime/unaligned1.go index c94f19e..2f5b63a 100644 --- a/libgo/go/runtime/unaligned1.go +++ b/libgo/go/runtime/unaligned1.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build 386 amd64 amd64p32 arm64 ppc64 ppc64le s390x ppc s390 arm64be +// +build 386 amd64 amd64p32 arm64 ppc64 ppc64le s390x ppc s390 arm64be riscv64 package runtime diff --git a/libgo/go/syscall/endian_little.go b/libgo/go/syscall/endian_little.go index b91d4bb..4a73121 100644 --- a/libgo/go/syscall/endian_little.go +++ b/libgo/go/syscall/endian_little.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // -// +build 386 amd64 amd64p32 arm arm64 ppc64le mips64le mipsle alpha ia64 mips64p32le sh +// +build 386 amd64 amd64p32 arm arm64 ppc64le mips64le mipsle alpha ia64 mips64p32le sh riscv64 package syscall diff --git a/libgo/go/syscall/libcall_linux_ustat.go b/libgo/go/syscall/libcall_linux_ustat.go index 261f086..3aff344 100644 --- a/libgo/go/syscall/libcall_linux_ustat.go +++ b/libgo/go/syscall/libcall_linux_ustat.go @@ -4,7 +4,7 @@ // GNU/Linux library ustat call. // This is not supported on some kernels, such as arm64. -// +build !arm64 +// +build !arm64,!riscv64 package syscall -- cgit v1.1