• Austin Clements's avatar
    runtime: use park/ready to wake up GC at end of concurrent mark · ce502b06
    Austin Clements authored
    Currently, the main GC goroutine sleeps on a note during concurrent
    mark and the first background mark worker or assist to finish marking
    use wakes up that note to let the main goroutine proceed into mark
    termination. Unfortunately, the latency of this wakeup can be quite
    high, since the GC goroutine will typically have lost its P while in
    the futex sleep, meaning it will be placed on the global run queue and
    will wait there until some P is kind enough to pick it up. This delay
    gives the mutator more time to allocate and create floating garbage,
    growing the heap unnecessarily. Worse, it's likely that background
    marking has stopped at this point (unless GOMAXPROCS>4), so anything
    that's allocated and published to the heap during this window will
    have to be scanned during mark termination while the world is stopped.
    
    This change replaces the note sleep/wakeup with a gopark/ready
    scheme. This keeps the wakeup inside the Go scheduler and lets the
    garbage collector take advantage of the new scheduler semantics that
    run the ready()d goroutine immediately when the ready()ing goroutine
    sleeps.
    
    For the json benchmark from x/benchmarks with GOMAXPROCS=4, this
    reduces the delay in waking up the GC goroutine and entering mark
    termination once concurrent marking is done from ~100ms to typically
    <100µs.
    
    Change-Id: Ib11f8b581b8914f2d68e0094f121e49bac3bb384
    Reviewed-on: https://go-review.googlesource.com/9291Reviewed-by: default avatarRick Hudson <rlh@golang.org>
    Reviewed-by: default avatarRuss Cox <rsc@golang.org>
    ce502b06
mgc.go 49.8 KB