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
This commit is contained in:
Ian Lance Taylor 2018-02-16 16:42:53 +00:00
parent 3943b16134
commit c3ab26e8bb
6 changed files with 47 additions and 3 deletions

View File

@ -1,4 +1,4 @@
5d5ea2fd05dbf369ccc53c93d4846623cdea0c47
cef3934fbc63f5e121abb8f88d3799961ac95b59
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -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

View File

@ -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()

View File

@ -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()
}

View File

@ -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
}

View File

@ -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: