Commit 3d58498f authored by Austin Clements's avatar Austin Clements

runtime: simplify forced GC triggering

Now that the gcMode is no longer involved in the GC trigger condition,
we can simplify the triggering of forced GCs. By making the trigger
condition for forced GCs true even if gcphase is not _GCoff, we don't
need any special case path in gcStart to ensure that forced GCs don't
get consolidated.

Change-Id: I6067a13d76e40ff2eef8fade6fc14adb0cb58ee5
Reviewed-on: https://go-review.googlesource.com/37517
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent 29be3f19
...@@ -911,8 +911,8 @@ type gcTriggerKind int ...@@ -911,8 +911,8 @@ type gcTriggerKind int
const ( const (
// gcTriggerAlways indicates that a cycle should be started // gcTriggerAlways indicates that a cycle should be started
// unconditionally, even if GOGC is off. This cannot be // unconditionally, even if GOGC is off or we're in a cycle
// consolidated with other cycles. // right now. This cannot be consolidated with other cycles.
gcTriggerAlways gcTriggerKind = iota gcTriggerAlways gcTriggerKind = iota
// gcTriggerHeap indicates that a cycle should be started when // gcTriggerHeap indicates that a cycle should be started when
...@@ -930,13 +930,13 @@ const ( ...@@ -930,13 +930,13 @@ const (
// that the exit condition for the _GCoff phase has been met. The exit // that the exit condition for the _GCoff phase has been met. The exit
// condition should be tested when allocating. // condition should be tested when allocating.
func (t gcTrigger) test() bool { func (t gcTrigger) test() bool {
if !(gcphase == _GCoff && memstats.enablegc && panicking == 0) { if !memstats.enablegc || panicking != 0 {
return false return false
} }
if t.kind == gcTriggerAlways { if t.kind == gcTriggerAlways {
return true return true
} }
if gcpercent < 0 { if gcphase != _GCoff || gcpercent < 0 {
return false return false
} }
switch t.kind { switch t.kind {
...@@ -984,20 +984,12 @@ func gcStart(mode gcMode, trigger gcTrigger) { ...@@ -984,20 +984,12 @@ func gcStart(mode gcMode, trigger gcTrigger) {
// Perform GC initialization and the sweep termination // Perform GC initialization and the sweep termination
// transition. // transition.
//
// If this is a forced GC, don't acquire the transition lock
// or re-check the transition condition because we
// specifically *don't* want to share the transition with
// another thread.
useStartSema := trigger.kind != gcTriggerAlways
if useStartSema {
semacquire(&work.startSema) semacquire(&work.startSema)
// Re-check transition condition under transition lock. // Re-check transition condition under transition lock.
if !trigger.test() { if !trigger.test() {
semrelease(&work.startSema) semrelease(&work.startSema)
return return
} }
}
// For stats, check if this GC was forced by the user. // For stats, check if this GC was forced by the user.
forced := trigger.kind == gcTriggerAlways forced := trigger.kind == gcTriggerAlways
...@@ -1103,9 +1095,7 @@ func gcStart(mode gcMode, trigger gcTrigger) { ...@@ -1103,9 +1095,7 @@ func gcStart(mode gcMode, trigger gcTrigger) {
gcMarkTermination() gcMarkTermination()
} }
if useStartSema {
semrelease(&work.startSema) semrelease(&work.startSema)
}
} }
// gcMarkDone transitions the GC from mark 1 to mark 2 and from mark 2 // gcMarkDone transitions the GC from mark 1 to mark 2 and from mark 2
......
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