github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/lockrank.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file records the static ranks of the locks in the runtime. If a lock 6 // is not given a rank, then it is assumed to be a leaf lock, which means no other 7 // lock can be acquired while it is held. Therefore, leaf locks do not need to be 8 // given an explicit rank. We list all of the architecture-independent leaf locks 9 // for documentation purposes, but don't list any of the architecture-dependent 10 // locks (which are all leaf locks). debugLock is ignored for ranking, since it is used 11 // when printing out lock ranking errors. 12 // 13 // lockInit(l *mutex, rank int) is used to set the rank of lock before it is used. 14 // If there is no clear place to initialize a lock, then the rank of a lock can be 15 // specified during the lock call itself via lockWithrank(l *mutex, rank int). 16 // 17 // Besides the static lock ranking (which is a total ordering of the locks), we 18 // also represent and enforce the actual partial order among the locks in the 19 // arcs[] array below. That is, if it is possible that lock B can be acquired when 20 // lock A is the previous acquired lock that is still held, then there should be 21 // an entry for A in arcs[B][]. We will currently fail not only if the total order 22 // (the lock ranking) is violated, but also if there is a missing entry in the 23 // partial order. 24 25 package runtime 26 27 type lockRank int 28 29 // Constants representing the lock rank of the architecture-independent locks in 30 // the runtime. Locks with lower rank must be taken before locks with higher 31 // rank. 32 const ( 33 lockRankDummy lockRank = iota 34 35 // Locks held above sched 36 lockRankSysmon 37 lockRankScavenge 38 lockRankForcegc 39 lockRankSweepWaiters 40 lockRankAssistQueue 41 lockRankCpuprof 42 lockRankSweep 43 44 lockRankPollDesc 45 lockRankSched 46 lockRankDeadlock 47 lockRankAllg 48 lockRankAllp 49 50 lockRankTimers // Multiple timers locked simultaneously in destroy() 51 lockRankItab 52 lockRankReflectOffs 53 lockRankHchan // Multiple hchans acquired in lock order in syncadjustsudogs() 54 lockRankFin 55 lockRankNotifyList 56 lockRankTraceBuf 57 lockRankTraceStrings 58 lockRankMspanSpecial 59 lockRankProf 60 lockRankGcBitsArenas 61 lockRankRoot 62 lockRankTrace 63 lockRankTraceStackTab 64 lockRankNetpollInit 65 66 lockRankRwmutexW 67 lockRankRwmutexR 68 69 lockRankSpanSetSpine 70 lockRankGscan 71 lockRankStackpool 72 lockRankStackLarge 73 lockRankDefer 74 lockRankSudog 75 76 // Memory-related non-leaf locks 77 lockRankWbufSpans 78 lockRankMheap 79 lockRankMheapSpecial 80 81 // Memory-related leaf locks 82 lockRankGlobalAlloc 83 84 // Other leaf locks 85 lockRankGFree 86 // Generally, hchan must be acquired before gscan. But in one specific 87 // case (in syncadjustsudogs from markroot after the g has been suspended 88 // by suspendG), we allow gscan to be acquired, and then an hchan lock. To 89 // allow this case, we get this lockRankHchanLeaf rank in 90 // syncadjustsudogs(), rather than lockRankHchan. By using this special 91 // rank, we don't allow any further locks to be acquired other than more 92 // hchan locks. 93 lockRankHchanLeaf 94 lockRankPanic 95 96 // Leaf locks with no dependencies, so these constants are not actually used anywhere. 97 // There are other architecture-dependent leaf locks as well. 98 lockRankNewmHandoff 99 lockRankDebugPtrmask 100 lockRankFaketimeState 101 lockRankTicks 102 lockRankRaceFini 103 lockRankPollCache 104 lockRankDebug 105 ) 106 107 // lockRankLeafRank is the rank of lock that does not have a declared rank, and hence is 108 // a leaf lock. 109 const lockRankLeafRank lockRank = 1000 110 111 // lockNames gives the names associated with each of the above ranks 112 var lockNames = []string{ 113 lockRankDummy: "", 114 115 lockRankSysmon: "sysmon", 116 lockRankScavenge: "scavenge", 117 lockRankForcegc: "forcegc", 118 lockRankSweepWaiters: "sweepWaiters", 119 lockRankAssistQueue: "assistQueue", 120 lockRankCpuprof: "cpuprof", 121 lockRankSweep: "sweep", 122 123 lockRankPollDesc: "pollDesc", 124 lockRankSched: "sched", 125 lockRankDeadlock: "deadlock", 126 lockRankAllg: "allg", 127 lockRankAllp: "allp", 128 129 lockRankTimers: "timers", 130 lockRankItab: "itab", 131 lockRankReflectOffs: "reflectOffs", 132 133 lockRankHchan: "hchan", 134 lockRankFin: "fin", 135 lockRankNotifyList: "notifyList", 136 lockRankTraceBuf: "traceBuf", 137 lockRankTraceStrings: "traceStrings", 138 lockRankMspanSpecial: "mspanSpecial", 139 lockRankProf: "prof", 140 lockRankGcBitsArenas: "gcBitsArenas", 141 lockRankRoot: "root", 142 lockRankTrace: "trace", 143 lockRankTraceStackTab: "traceStackTab", 144 lockRankNetpollInit: "netpollInit", 145 146 lockRankRwmutexW: "rwmutexW", 147 lockRankRwmutexR: "rwmutexR", 148 149 lockRankSpanSetSpine: "spanSetSpine", 150 lockRankGscan: "gscan", 151 lockRankStackpool: "stackpool", 152 lockRankStackLarge: "stackLarge", 153 lockRankDefer: "defer", 154 lockRankSudog: "sudog", 155 156 lockRankWbufSpans: "wbufSpans", 157 lockRankMheap: "mheap", 158 lockRankMheapSpecial: "mheapSpecial", 159 160 lockRankGlobalAlloc: "globalAlloc.mutex", 161 162 lockRankGFree: "gFree", 163 lockRankHchanLeaf: "hchanLeaf", 164 lockRankPanic: "panic", 165 166 lockRankNewmHandoff: "newmHandoff.lock", 167 lockRankDebugPtrmask: "debugPtrmask.lock", 168 lockRankFaketimeState: "faketimeState.lock", 169 lockRankTicks: "ticks.lock", 170 lockRankRaceFini: "raceFiniLock", 171 lockRankPollCache: "pollCache.lock", 172 lockRankDebug: "debugLock", 173 } 174 175 func (rank lockRank) String() string { 176 if rank == 0 { 177 return "UNKNOWN" 178 } 179 if rank == lockRankLeafRank { 180 return "LEAF" 181 } 182 return lockNames[rank] 183 } 184 185 // lockPartialOrder is a partial order among the various lock types, listing the 186 // immediate ordering that has actually been observed in the runtime. Each entry 187 // (which corresponds to a particular lock rank) specifies the list of locks 188 // that can already be held immediately "above" it. 189 // 190 // So, for example, the lockRankSched entry shows that all the locks preceding 191 // it in rank can actually be held. The allp lock shows that only the sysmon or 192 // sched lock can be held immediately above it when it is acquired. 193 var lockPartialOrder [][]lockRank = [][]lockRank{ 194 lockRankDummy: {}, 195 lockRankSysmon: {}, 196 lockRankScavenge: {lockRankSysmon}, 197 lockRankForcegc: {lockRankSysmon}, 198 lockRankSweepWaiters: {}, 199 lockRankAssistQueue: {}, 200 lockRankCpuprof: {}, 201 lockRankSweep: {}, 202 lockRankPollDesc: {}, 203 lockRankSched: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc}, 204 lockRankDeadlock: {lockRankDeadlock}, 205 lockRankAllg: {lockRankSysmon, lockRankSched}, 206 lockRankAllp: {lockRankSysmon, lockRankSched}, 207 lockRankTimers: {lockRankSysmon, lockRankScavenge, lockRankPollDesc, lockRankSched, lockRankAllp, lockRankTimers}, 208 lockRankItab: {}, 209 lockRankReflectOffs: {lockRankItab}, 210 lockRankHchan: {lockRankScavenge, lockRankSweep, lockRankHchan}, 211 lockRankFin: {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan}, 212 lockRankNotifyList: {}, 213 lockRankTraceBuf: {lockRankSysmon, lockRankScavenge}, 214 lockRankTraceStrings: {lockRankTraceBuf}, 215 lockRankMspanSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, 216 lockRankProf: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, 217 lockRankGcBitsArenas: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, 218 lockRankRoot: {}, 219 lockRankTrace: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot}, 220 lockRankTraceStackTab: {lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankTrace}, 221 lockRankNetpollInit: {lockRankTimers}, 222 223 lockRankRwmutexW: {}, 224 lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW}, 225 226 lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, 227 lockRankGscan: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankSpanSetSpine}, 228 lockRankStackpool: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankSpanSetSpine, lockRankGscan}, 229 lockRankStackLarge: {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan}, 230 lockRankDefer: {}, 231 lockRankSudog: {lockRankHchan, lockRankNotifyList}, 232 lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog}, 233 lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans}, 234 lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, 235 lockRankGlobalAlloc: {lockRankProf, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial}, 236 237 lockRankGFree: {lockRankSched}, 238 lockRankHchanLeaf: {lockRankGscan, lockRankHchanLeaf}, 239 lockRankPanic: {lockRankDeadlock}, // plus any other lock held on throw. 240 241 lockRankNewmHandoff: {}, 242 lockRankDebugPtrmask: {}, 243 lockRankFaketimeState: {}, 244 lockRankTicks: {}, 245 lockRankRaceFini: {}, 246 lockRankPollCache: {}, 247 lockRankDebug: {}, 248 }