mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
3943b16134
commit
c3ab26e8bb
|
|
@ -1,4 +1,4 @@
|
||||||
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) {
|
||||||
* 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)
|
||||||
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 {
|
||||||
// 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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
// 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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
// 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:
|
||||||
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:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue