Source File
mgcwork.go
Belonging Package
runtime
package runtime
import (
)
const (
_WorkbufSize = 2048 // in bytes; larger values result in less contention
workbufAlloc = 32 << 10
)
func () {
if workbufAlloc%pageSize != 0 || workbufAlloc%_WorkbufSize != 0 {
throw("bad workbufAlloc")
}
}
lockWithRankMayAcquire(&work.wbufSpans.lock, lockRankWbufSpans)
lockWithRankMayAcquire(&mheap_.lock, lockRankMheap)
if == nil {
.init()
if && gcphase == _GCmark {
gcController.enlistWorker()
}
}
func ( *gcWork) ( []uintptr) {
if len() == 0 {
return
}
:= false
:= .wbuf1
if == nil {
.init()
= .wbuf1
}
for len() > 0 {
for .nobj == len(.obj) {
putfull()
.flushedWork = true
.wbuf1, .wbuf2 = .wbuf2, getempty()
= .wbuf1
= true
}
:= copy(.obj[.nobj:], )
.nobj +=
= [:]
}
if && gcphase == _GCmark {
gcController.enlistWorker()
}
}
atomic.Xadd64(&work.bytesMarked, int64(.bytesMarked))
.bytesMarked = 0
}
if .scanWork != 0 {
atomic.Xaddint64(&gcController.scanWork, .scanWork)
.scanWork = 0
}
}
if gcphase == _GCmark {
gcController.enlistWorker()
}
}
type workbufhdr struct {
node lfnode // must be first
nobj int
}
type workbuf struct {
obj [(_WorkbufSize - unsafe.Sizeof(workbufhdr{})) / sys.PtrSize]uintptr
}
var *mspan
if work.wbufSpans.free.first != nil {
lock(&work.wbufSpans.lock)
= work.wbufSpans.free.first
if != nil {
work.wbufSpans.free.remove()
work.wbufSpans.busy.insert()
}
unlock(&work.wbufSpans.lock)
}
if == nil {
systemstack(func() {
= mheap_.allocManual(workbufAlloc/pageSize, spanAllocWorkBuf)
})
if == nil {
throw("out of memory")
for := uintptr(0); +_WorkbufSize <= workbufAlloc; += _WorkbufSize {
:= (*workbuf)(unsafe.Pointer(.base() + ))
.nobj = 0
lfnodeValidate(&.node)
if == 0 {
=
} else {
putempty()
}
}
}
return
}
putfull()
return
}
func ( bool) bool {
const = 64 // ~1–2 µs per span.
lock(&work.wbufSpans.lock)
if gcphase != _GCoff || work.wbufSpans.free.isEmpty() {
unlock(&work.wbufSpans.lock)
return false
}
systemstack(func() {
:= getg().m.curg
for := 0; < && !( && .preempt); ++ {
:= work.wbufSpans.free.first
if == nil {
break
}
work.wbufSpans.free.remove()
mheap_.freeManual(, spanAllocWorkBuf)
}
})
:= !work.wbufSpans.free.isEmpty()
unlock(&work.wbufSpans.lock)
return
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |