Commit c3ab26e8 by Ian Lance Taylor

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
parent 3943b161
5d5ea2fd05dbf369ccc53c93d4846623cdea0c47 cef3934fbc63f5e121abb8f88d3799961ac95b59
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -148,6 +148,11 @@ func chansend1(c *hchan, elem unsafe.Pointer) { ...@@ -148,6 +148,11 @@ func chansend1(c *hchan, elem unsafe.Pointer) {
* the operation; we'll see that it's now closed. * the operation; we'll see that it's now closed.
*/ */
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { 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 c == nil {
if !block { if !block {
return false return false
...@@ -430,6 +435,11 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) ...@@ -430,6 +435,11 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool)
print("chanrecv: chan=", c, "\n") 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 c == nil {
if !block { if !block {
return return
......
...@@ -356,6 +356,11 @@ func makemap(t *maptype, hint int, h *hmap) *hmap { ...@@ -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 // NOTE: The returned pointer may keep the whole map live, so don't
// hold onto it for very long. // hold onto it for very long.
func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { 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 { if raceenabled && h != nil {
callerpc := getcallerpc() callerpc := getcallerpc()
pc := funcPC(mapaccess1) pc := funcPC(mapaccess1)
...@@ -409,6 +414,11 @@ func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer { ...@@ -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) { 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 { if raceenabled && h != nil {
callerpc := getcallerpc() callerpc := getcallerpc()
pc := funcPC(mapaccess2) pc := funcPC(mapaccess2)
...@@ -463,6 +473,11 @@ func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) ...@@ -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 // returns both key and value. Used by map iterator
func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) { 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 { if h == nil || h.count == 0 {
return nil, nil return nil, nil
} }
...@@ -521,6 +536,11 @@ func mapaccess2_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) (unsafe.Point ...@@ -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. // 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 { 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 { if h == nil {
panic(plainError("assignment to entry in nil map")) panic(plainError("assignment to entry in nil map"))
} }
...@@ -772,6 +792,11 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) { ...@@ -772,6 +792,11 @@ func mapiterinit(t *maptype, h *hmap, it *hiter) {
} }
func mapiternext(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 h := it.h
if raceenabled { if raceenabled {
callerpc := getcallerpc() callerpc := getcallerpc()
......
...@@ -826,6 +826,7 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { ...@@ -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 { if getg().preempt {
checkPreempt() checkPreempt()
} }
......
...@@ -4084,8 +4084,9 @@ func preemptone(_p_ *p) bool { ...@@ -4084,8 +4084,9 @@ func preemptone(_p_ *p) bool {
// setting a global variable and figuring out a way to efficiently // setting a global variable and figuring out a way to efficiently
// check that global variable. // check that global variable.
// //
// For now we check gp.preempt in schedule and mallocgc, // For now we check gp.preempt in schedule, mallocgc, selectgo,
// which is at least better than doing nothing at all. // and a few other places, which is at least better than doing
// nothing at all.
return true return true
} }
......
...@@ -584,6 +584,13 @@ retc: ...@@ -584,6 +584,13 @@ retc:
if cas.releasetime > 0 { if cas.releasetime > 0 {
blockevent(cas.releasetime-t0, 1) 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 return casi
sclose: sclose:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment