diff options
Diffstat (limited to 'libgo/go/runtime/runtime2.go')
-rw-r--r-- | libgo/go/runtime/runtime2.go | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go index fd77c4c..77648c2 100644 --- a/libgo/go/runtime/runtime2.go +++ b/libgo/go/runtime/runtime2.go @@ -22,6 +22,13 @@ const ( // If you add to this list, add to the list // of "okay during garbage collection" status // in mgcmark.go too. + // + // TODO(austin): The _Gscan bit could be much lighter-weight. + // For example, we could choose not to run _Gscanrunnable + // goroutines found in the run queue, rather than CAS-looping + // until they become _Grunnable. And transitions like + // _Gscanwaiting -> _Gscanrunnable are actually okay because + // they don't affect stack ownership. // _Gidle means this goroutine was just allocated and has not // yet been initialized. @@ -97,10 +104,51 @@ const ( const ( // P status - _Pidle = iota - _Prunning // Only this P is allowed to change from _Prunning. + + // _Pidle means a P is not being used to run user code or the + // scheduler. Typically, it's on the idle P list and available + // to the scheduler, but it may just be transitioning between + // other states. + // + // The P is owned by the idle list or by whatever is + // transitioning its state. Its run queue is empty. + _Pidle = iota + + // _Prunning means a P is owned by an M and is being used to + // run user code or the scheduler. Only the M that owns this P + // is allowed to change the P's status from _Prunning. The M + // may transition the P to _Pidle (if it has no more work to + // do), _Psyscall (when entering a syscall), or _Pgcstop (to + // halt for the GC). The M may also hand ownership of the P + // off directly to another M (e.g., to schedule a locked G). + _Prunning + + // _Psyscall means a P is not running user code. It has + // affinity to an M in a syscall but is not owned by it and + // may be stolen by another M. This is similar to _Pidle but + // uses lightweight transitions and maintains M affinity. + // + // Leaving _Psyscall must be done with a CAS, either to steal + // or retake the P. Note that there's an ABA hazard: even if + // an M successfully CASes its original P back to _Prunning + // after a syscall, it must understand the P may have been + // used by another M in the interim. _Psyscall + + // _Pgcstop means a P is halted for STW and owned by the M + // that stopped the world. The M that stopped the world + // continues to use its P, even in _Pgcstop. Transitioning + // from _Prunning to _Pgcstop causes an M to release its P and + // park. + // + // The P retains its run queue and startTheWorld will restart + // the scheduler on Ps with non-empty run queues. _Pgcstop + + // _Pdead means a P is no longer used (GOMAXPROCS shrank). We + // reuse Ps if GOMAXPROCS increases. A dead P is mostly + // stripped of its resources, though a few things remain + // (e.g., trace buffers). _Pdead ) @@ -481,7 +529,6 @@ type m struct { profilehz int32 spinning bool // m is out of work and is actively looking for work blocked bool // m is blocked on a note - inwb bool // m is executing a write barrier newSigstack bool // minit on C thread called sigaltstack printlock int8 incgo bool // m is executing a cgo call @@ -498,11 +545,11 @@ type m struct { schedlink muintptr mcache *mcache lockedg guintptr - createstack [32]location // stack that created this thread. - lockedExt uint32 // tracking for external LockOSThread - lockedInt uint32 // tracking for internal lockOSThread - nextwaitm muintptr // next m waiting for lock - waitunlockf unsafe.Pointer // todo go func(*g, unsafe.pointer) bool + createstack [32]location // stack that created this thread. + lockedExt uint32 // tracking for external LockOSThread + lockedInt uint32 // tracking for internal lockOSThread + nextwaitm muintptr // next m waiting for lock + waitunlockf func(*g, unsafe.Pointer) bool waitlock unsafe.Pointer waittraceev byte waittraceskip int @@ -519,7 +566,9 @@ type m struct { // Not for gccgo: libcallg guintptr // Not for gccgo: syscall libcall // stores syscall parameters on windows - mos mOS + dlogPerM + + mOS // Remaining fields are specific to gccgo. @@ -529,14 +578,10 @@ type m struct { dropextram bool // drop after call is done exiting bool // thread is exiting - gcing int32 - scannote note // synchonization for signal-based stack scanning } type p struct { - lock mutex - id int32 status uint32 // one of pidle/prunning/... link puintptr @@ -545,7 +590,7 @@ type p struct { sysmontick sysmontick // last tick observed by sysmon m muintptr // back-link to associated m (nil if idle) mcache *mcache - racectx uintptr + raceprocctx uintptr // gccgo has only one size of defer. deferpool []*_defer @@ -591,10 +636,12 @@ type p struct { palloc persistentAlloc // per-P to avoid mutex + _ uint32 // Alignment for atomic fields below + // Per-P GC state - gcAssistTime int64 // Nanoseconds in assistAlloc - gcFractionalMarkTime int64 // Nanoseconds in fractional mark worker - gcBgMarkWorker guintptr + gcAssistTime int64 // Nanoseconds in assistAlloc + gcFractionalMarkTime int64 // Nanoseconds in fractional mark worker (atomic) + gcBgMarkWorker guintptr // (atomic) gcMarkWorkerMode gcMarkWorkerMode // gcMarkWorkerStartTime is the nanotime() at which this mark @@ -707,7 +754,7 @@ const ( ) // Lock-free stack node. -// // Also known to export_test.go. +// Also known to export_test.go. type lfnode struct { next uint64 pushcnt uintptr @@ -847,6 +894,7 @@ const ( waitReasonSelectNoCases // "select (no cases)" waitReasonGCAssistWait // "GC assist wait" waitReasonGCSweepWait // "GC sweep wait" + waitReasonGCScavengeWait // "GC scavenge wait" waitReasonChanReceive // "chan receive" waitReasonChanSend // "chan send" waitReasonFinalizerWait // "finalizer wait" @@ -874,6 +922,7 @@ var waitReasonStrings = [...]string{ waitReasonSelectNoCases: "select (no cases)", waitReasonGCAssistWait: "GC assist wait", waitReasonGCSweepWait: "GC sweep wait", + waitReasonGCScavengeWait: "GC scavenge wait", waitReasonChanReceive: "chan receive", waitReasonChanSend: "chan send", waitReasonFinalizerWait: "finalizer wait", |