]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: remove work.partial queue
authorAustin Clements <austin@google.com>
Thu, 15 Oct 2015 19:44:16 +0000 (15:44 -0400)
committerAustin Clements <austin@google.com>
Mon, 19 Oct 2015 18:37:54 +0000 (18:37 +0000)
This work queue is no longer used (there are many reads of
work.partial, but the only write is in putpartial, which is never
called).

Fixes #11922.

Change-Id: I08b76c0c02a0867a9cdcb94783e1f7629d44249a
Reviewed-on: https://go-review.googlesource.com/15892
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/mgc.go
src/runtime/mgcmark.go
src/runtime/mgcwork.go

index f57e16cdeb64f88618fb7e7bb6d5838fc6d42d54..70ceb9bbb7bec18b088ae35551ae8c5bfc7745a5 100644 (file)
@@ -622,7 +622,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
                // else for a while, so kick everything out of its run
                // queue.
        } else {
-               if _p_.gcw.wbuf == 0 && work.full == 0 && work.partial == 0 {
+               if _p_.gcw.wbuf == 0 && work.full == 0 {
                        // No work to be done right now. This can
                        // happen at the end of the mark phase when
                        // there are still assists tapering off. Don't
@@ -795,10 +795,8 @@ func (s *bgMarkSignal) clear() {
 }
 
 var work struct {
-       full  uint64 // lock-free list of full blocks workbuf
-       empty uint64 // lock-free list of empty blocks workbuf
-       // TODO(rlh): partial no longer used, remove. (issue #11922)
-       partial uint64                // lock-free list of partially filled blocks workbuf
+       full    uint64                // lock-free list of full blocks workbuf
+       empty   uint64                // lock-free list of empty blocks workbuf
        pad0    [_CacheLineSize]uint8 // prevents false-sharing between full/empty and nproc/nwait
        nproc   uint32
        tstart  int64
@@ -1400,7 +1398,7 @@ func gcBgMarkWorker(p *p) {
                                        "work.nwait=", incnwait, "work.nproc=", work.nproc)
                                throw("work.nwait > work.nproc")
                        }
-                       done = incnwait == work.nproc && work.full == 0 && work.partial == 0
+                       done = incnwait == work.nproc && work.full == 0
                }
 
                // If this worker reached a background mark completion
@@ -1436,7 +1434,7 @@ func gcMarkWorkAvailable(p *p) bool {
        if !p.gcw.empty() {
                return true
        }
-       if atomicload64(&work.full) != 0 || atomicload64(&work.partial) != 0 {
+       if atomicload64(&work.full) != 0 {
                return true // global work available
        }
        return false
@@ -1497,9 +1495,6 @@ func gcMark(start_time int64) {
        if work.full != 0 {
                throw("work.full != 0")
        }
-       if work.partial != 0 {
-               throw("work.partial != 0")
-       }
 
        if work.nproc > 1 {
                notesleep(&work.alldone)
index 95586dc74ef9f5016db5e2b24d1a57b5838c915c..9b20f0aae56d6a0b23e956b4d25a16471ab2238f 100644 (file)
@@ -300,7 +300,7 @@ retry:
                        throw("work.nwait > work.nproc")
                }
 
-               if incnwait == work.nproc && work.full == 0 && work.partial == 0 {
+               if incnwait == work.nproc && work.full == 0 {
                        // This has reached a background completion
                        // point.
                        if gcBlackenPromptly {
index ef53087468878d7bbdc6a24077597c7de178a9d6..4d305e25df3ba9b012bfb9bfe60322dbdd096edd 100644 (file)
@@ -80,7 +80,7 @@ func (ww *gcWork) put(obj uintptr) {
 
        wbuf := w.wbuf.ptr()
        if wbuf == nil {
-               wbuf = getpartialorempty(42)
+               wbuf = getempty(42)
                w.wbuf = wbufptrOf(wbuf)
        }
 
@@ -204,7 +204,7 @@ func (w *gcWork) empty() bool {
 type workbufhdr struct {
        node  lfnode // must be first
        nobj  int
-       inuse bool   // This workbuf is in use by some gorotuine and is not on the work.empty/partial/full queues.
+       inuse bool   // This workbuf is in use by some gorotuine and is not on the work.empty/full queues.
        log   [4]int // line numbers forming a history of ownership changes to workbuf
 }
 
@@ -217,7 +217,7 @@ type workbuf struct {
 // workbuf factory routines. These funcs are used to manage the
 // workbufs.
 // If the GC asks for some work these are the only routines that
-// make partially full wbufs available to the GC.
+// make wbufs available to the GC.
 // Each of the gets and puts also take an distinct integer that is used
 // to record a brief history of changes to ownership of the workbuf.
 // The convention is to use a unique line number but any encoding
@@ -314,54 +314,11 @@ func putfull(b *workbuf, entry int) {
        lfstackpush(&work.full, &b.node)
 }
 
-// getpartialorempty tries to return a partially empty
-// and if none are available returns an empty one.
-// entry is used to provide a brief history of ownership
-// using entry + xxx00000 to
-// indicating that two line numbers in the call chain.
-//go:nowritebarrier
-func getpartialorempty(entry int) *workbuf {
-       b := (*workbuf)(lfstackpop(&work.partial))
-       if b != nil {
-               b.logget(entry)
-               return b
-       }
-       // Let getempty do the logget check but
-       // use the entry to encode that it passed
-       // through this routine.
-       b = getempty(entry + 80700000)
-       return b
-}
-
-// putpartial puts empty buffers on the work.empty queue,
-// full buffers on the work.full queue and
-// others on the work.partial queue.
-// entry is used to provide a brief history of ownership
-// using entry + xxx00000 to
-// indicating that two call chain line numbers.
-//go:nowritebarrier
-func putpartial(b *workbuf, entry int) {
-       if b.nobj == 0 {
-               putempty(b, entry+81500000)
-       } else if b.nobj < len(b.obj) {
-               b.logput(entry)
-               lfstackpush(&work.partial, &b.node)
-       } else if b.nobj == len(b.obj) {
-               b.logput(entry)
-               lfstackpush(&work.full, &b.node)
-       } else {
-               throw("putpartial: bad Workbuf b.nobj")
-       }
-}
-
 // trygetfull tries to get a full or partially empty workbuffer.
 // If one is not immediately available return nil
 //go:nowritebarrier
 func trygetfull(entry int) *workbuf {
        b := (*workbuf)(lfstackpop(&work.full))
-       if b == nil {
-               b = (*workbuf)(lfstackpop(&work.partial))
-       }
        if b != nil {
                b.logget(entry)
                b.checknonempty()
@@ -370,10 +327,9 @@ func trygetfull(entry int) *workbuf {
        return b
 }
 
-// Get a full work buffer off the work.full or a partially
-// filled one off the work.partial list. If nothing is available
-// wait until all the other gc helpers have finished and then
-// return nil.
+// Get a full work buffer off the work.full list.
+// If nothing is available wait until all the other gc helpers have
+// finished and then return nil.
 // getfull acts as a barrier for work.nproc helpers. As long as one
 // gchelper is actively marking objects it
 // may create a workbuffer that the other helpers can work on.
@@ -390,11 +346,6 @@ func getfull(entry int) *workbuf {
                b.checknonempty()
                return b
        }
-       b = (*workbuf)(lfstackpop(&work.partial))
-       if b != nil {
-               b.logget(entry)
-               return b
-       }
 
        incnwait := xadd(&work.nwait, +1)
        if incnwait > work.nproc {
@@ -402,16 +353,13 @@ func getfull(entry int) *workbuf {
                throw("work.nwait > work.nproc")
        }
        for i := 0; ; i++ {
-               if work.full != 0 || work.partial != 0 {
+               if work.full != 0 {
                        decnwait := xadd(&work.nwait, -1)
                        if decnwait == work.nproc {
                                println("runtime: work.nwait=", decnwait, "work.nproc=", work.nproc)
                                throw("work.nwait > work.nproc")
                        }
                        b = (*workbuf)(lfstackpop(&work.full))
-                       if b == nil {
-                               b = (*workbuf)(lfstackpop(&work.partial))
-                       }
                        if b != nil {
                                b.logget(entry)
                                b.checknonempty()