]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/runtime/runtime2.go
runtime: make it harder to introduce deadlocks with forEachP
[gostls13.git] / src / runtime / runtime2.go
index cdd8c3db7fe1ac85d427dc29f74c15707195c368..e7a3d4ed1ba2e4857bcc43fca70e3b33f9e01582 100644 (file)
@@ -342,7 +342,7 @@ type gobuf struct {
        bp   uintptr // for framepointer-enabled architectures
 }
 
-// sudog represents a g in a wait list, such as for sending/receiving
+// sudog (pseudo-g) represents a g in a wait list, such as for sending/receiving
 // on a channel.
 //
 // sudog is necessary because the g ↔ synchronization object relation
@@ -382,6 +382,13 @@ type sudog struct {
        // because c was closed.
        success bool
 
+       // waiters is a count of semaRoot waiting list other than head of list,
+       // clamped to a uint16 to fit in unused space.
+       // Only meaningful at the head of the list.
+       // (If we wanted to be overly clever, we could store a high 16 bits
+       // in the second entry in the list.)
+       waiters uint16
+
        parent   *sudog // semaRoot binary tree
        waitlink *sudog // g.waiting list or semaRoot
        waittail *sudog // semaRoot
@@ -416,7 +423,7 @@ type g struct {
        // stack describes the actual stack memory: [stack.lo, stack.hi).
        // stackguard0 is the stack pointer compared in the Go stack growth prologue.
        // It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
-       // stackguard1 is the stack pointer compared in the C stack growth prologue.
+       // stackguard1 is the stack pointer compared in the //go:systemstack stack growth prologue.
        // It is stack.lo+StackGuard on g0 and gsignal stacks.
        // It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
        stack       stack   // offset known to runtime/cgo
@@ -433,7 +440,7 @@ type g struct {
        // param is a generic pointer parameter field used to pass
        // values in particular contexts where other storage for the
        // parameter would be difficult to find. It is currently used
-       // in three ways:
+       // in four ways:
        // 1. When a channel operation wakes up a blocked goroutine, it sets param to
        //    point to the sudog of the completed blocking operation.
        // 2. By gcAssistAlloc1 to signal back to its caller that the goroutine completed
@@ -441,6 +448,8 @@ type g struct {
        //    stack may have moved in the meantime.
        // 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
        //    closure in the runtime is forbidden.
+       // 4. When a panic is recovered and control returns to the respective frame,
+       //    param may point to a savedOpenDeferState.
        param        unsafe.Pointer
        atomicstatus atomic.Uint32
        stackLock    uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
@@ -472,6 +481,7 @@ type g struct {
        parkingOnChan atomic.Bool
 
        raceignore    int8  // ignore race detection events
+       nocgocallback bool  // whether disable callback from C
        tracking      bool  // whether we're tracking this G for sched latency statistics
        trackingSeq   uint8 // used to decide whether to track this G
        trackingStamp int64 // timestamp of when the G last started being tracked
@@ -574,7 +584,7 @@ type m struct {
        alllink       *m // on allm
        schedlink     muintptr
        lockedg       guintptr
-       createstack   [32]uintptr // stack that created this thread.
+       createstack   [32]uintptr // stack that created this thread, it's used for StackRecord.Stack0, so it must align with it.
        lockedExt     uint32      // tracking for external LockOSThread
        lockedInt     uint32      // tracking for internal lockOSThread
        nextwaitm     muintptr    // next m waiting for lock
@@ -609,6 +619,9 @@ type m struct {
        // Whether this is a pending preemption signal on this M.
        signalPending atomic.Uint32
 
+       // pcvalue lookup cache
+       pcvalueCache pcvalueCache
+
        dlogPerM
 
        mOS
@@ -947,7 +960,7 @@ type funcinl struct {
 // layout of Itab known to compilers
 // allocated in non-garbage-collected memory
 // Needs to be in sync with
-// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
+// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WritePluginTable.
 type itab struct {
        inter *interfacetype
        _type *_type
@@ -999,11 +1012,16 @@ func extendRandom(r []byte, n int) {
 // initialize them are not required. All defers must be manually scanned,
 // and for heap defers, marked.
 type _defer struct {
-       heap bool
-       sp   uintptr // sp at time of defer
-       pc   uintptr // pc at time of defer
-       fn   func()  // can be nil for open-coded defers
-       link *_defer // next defer on G; can point to either heap or stack!
+       heap      bool
+       rangefunc bool    // true for rangefunc list
+       sp        uintptr // sp at time of defer
+       pc        uintptr // pc at time of defer
+       fn        func()  // can be nil for open-coded defers
+       link      *_defer // next defer on G; can point to either heap or stack!
+
+       // If rangefunc is true, *head is the head of the atomic linked list
+       // during a range-over-func execution.
+       head *atomic.Pointer[_defer]
 }
 
 // A _panic holds information about an active panic.
@@ -1041,6 +1059,15 @@ type _panic struct {
        deferreturn bool
 }
 
+// savedOpenDeferState tracks the extra state from _panic that's
+// necessary for deferreturn to pick up where gopanic left off,
+// without needing to unwind the stack.
+type savedOpenDeferState struct {
+       retpc           uintptr
+       deferBitsOffset uintptr
+       slotsOffset     uintptr
+}
+
 // ancestorInfo records details of where a goroutine was started.
 type ancestorInfo struct {
        pcs  []uintptr // pcs from the stack of this goroutine
@@ -1085,6 +1112,7 @@ const (
        waitReasonDebugCall                               // "debug call"
        waitReasonGCMarkTermination                       // "GC mark termination"
        waitReasonStoppingTheWorld                        // "stopping the world"
+       waitReasonFlushProcCaches                         // "flushing proc caches"
 )
 
 var waitReasonStrings = [...]string{
@@ -1120,6 +1148,7 @@ var waitReasonStrings = [...]string{
        waitReasonDebugCall:             "debug call",
        waitReasonGCMarkTermination:     "GC mark termination",
        waitReasonStoppingTheWorld:      "stopping the world",
+       waitReasonFlushProcCaches:       "flushing proc caches",
 }
 
 func (w waitReason) String() string {