github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/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 lockRankTraceBuf 55 lockRankFin 56 lockRankNotifyList 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 lockRankPageAllocScav 84 85 // Other leaf locks 86 lockRankGFree 87 // Generally, hchan must be acquired before gscan. But in one specific 88 // case (in syncadjustsudogs from markroot after the g has been suspended 89 // by suspendG), we allow gscan to be acquired, and then an hchan lock. To 90 // allow this case, we get this lockRankHchanLeaf rank in 91 // syncadjustsudogs(), rather than lockRankHchan. By using this special 92 // rank, we don't allow any further locks to be acquired other than more 93 // hchan locks. 94 lockRankHchanLeaf 95 lockRankPanic 96 97 // Leaf locks with no dependencies, so these constants are not actually used anywhere. 98 // There are other architecture-dependent leaf locks as well. 99 lockRankNewmHandoff 100 lockRankDebugPtrmask 101 lockRankFaketimeState 102 lockRankTicks 103 lockRankRaceFini 104 lockRankPollCache 105 lockRankDebug 106 ) 107 108 // lockRankLeafRank is the rank of lock that does not have a declared rank, and hence is 109 // a leaf lock. 110 const lockRankLeafRank lockRank = 1000 111 112 // lockNames gives the names associated with each of the above ranks 113 var lockNames = []string{ 114 lockRankDummy: "", 115 116 lockRankSysmon: "sysmon", 117 lockRankScavenge: "scavenge", 118 lockRankForcegc: "forcegc", 119 lockRankSweepWaiters: "sweepWaiters", 120 lockRankAssistQueue: "assistQueue", 121 lockRankCpuprof: "cpuprof", 122 lockRankSweep: "sweep", 123 124 lockRankPollDesc: "pollDesc", 125 lockRankSched: "sched", 126 lockRankDeadlock: "deadlock", 127 lockRankAllg: "allg", 128 lockRankAllp: "allp", 129 130 lockRankTimers: "timers", 131 lockRankItab: "itab", 132 lockRankReflectOffs: "reflectOffs", 133 134 lockRankHchan: "hchan", 135 lockRankTraceBuf: "traceBuf", 136 lockRankFin: "fin", 137 lockRankNotifyList: "notifyList", 138 lockRankTraceStrings: "traceStrings", 139 lockRankMspanSpecial: "mspanSpecial", 140 lockRankProf: "prof", 141 lockRankGcBitsArenas: "gcBitsArenas", 142 lockRankRoot: "root", 143 lockRankTrace: "trace", 144 lockRankTraceStackTab: "traceStackTab", 145 lockRankNetpollInit: "netpollInit", 146 147 lockRankRwmutexW: "rwmutexW", 148 lockRankRwmutexR: "rwmutexR", 149 150 lockRankSpanSetSpine: "spanSetSpine", 151 lockRankGscan: "gscan", 152 lockRankStackpool: "stackpool", 153 lockRankStackLarge: "stackLarge", 154 lockRankDefer: "defer", 155 lockRankSudog: "sudog", 156 157 lockRankWbufSpans: "wbufSpans", 158 lockRankMheap: "mheap", 159 lockRankMheapSpecial: "mheapSpecial", 160 161 lockRankGlobalAlloc: "globalAlloc.mutex", 162 lockRankPageAllocScav: "pageAlloc.scav.lock", 163 164 lockRankGFree: "gFree", 165 lockRankHchanLeaf: "hchanLeaf", 166 lockRankPanic: "panic", 167 168 lockRankNewmHandoff: "newmHandoff.lock", 169 lockRankDebugPtrmask: "debugPtrmask.lock", 170 lockRankFaketimeState: "faketimeState.lock", 171 lockRankTicks: "ticks.lock", 172 lockRankRaceFini: "raceFiniLock", 173 lockRankPollCache: "pollCache.lock", 174 lockRankDebug: "debugLock", 175 } 176 177 func (rank lockRank) String() string { 178 if rank == 0 { 179 return "UNKNOWN" 180 } 181 if rank == lockRankLeafRank { 182 return "LEAF" 183 } 184 return lockNames[rank] 185 } 186 187 // lockPartialOrder is a partial order among the various lock types, listing the 188 // immediate ordering that has actually been observed in the runtime. Each entry 189 // (which corresponds to a particular lock rank) specifies the list of locks 190 // that can already be held immediately "above" it. 191 // 192 // So, for example, the lockRankSched entry shows that all the locks preceding 193 // it in rank can actually be held. The allp lock shows that only the sysmon or 194 // sched lock can be held immediately above it when it is acquired. 195 var lockPartialOrder [][]lockRank = [][]lockRank{ 196 lockRankDummy: {}, 197 lockRankSysmon: {}, 198 lockRankScavenge: {lockRankSysmon}, 199 lockRankForcegc: {lockRankSysmon}, 200 lockRankSweepWaiters: {}, 201 lockRankAssistQueue: {}, 202 lockRankCpuprof: {}, 203 lockRankSweep: {}, 204 lockRankPollDesc: {}, 205 lockRankSched: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc}, 206 lockRankDeadlock: {lockRankDeadlock}, 207 lockRankAllg: {lockRankSysmon, lockRankSched}, 208 lockRankAllp: {lockRankSysmon, lockRankSched}, 209 lockRankTimers: {lockRankSysmon, lockRankScavenge, lockRankPollDesc, lockRankSched, lockRankAllp, lockRankTimers}, 210 lockRankItab: {}, 211 lockRankReflectOffs: {lockRankItab}, 212 lockRankHchan: {lockRankScavenge, lockRankSweep, lockRankHchan}, 213 lockRankTraceBuf: {lockRankSysmon, lockRankScavenge}, 214 lockRankFin: {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllg, lockRankTimers, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf}, 215 lockRankNotifyList: {}, 216 lockRankTraceStrings: {lockRankTraceBuf}, 217 lockRankMspanSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings}, 218 lockRankProf: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings}, 219 lockRankGcBitsArenas: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings}, 220 lockRankRoot: {}, 221 lockRankTrace: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot}, 222 lockRankTraceStackTab: {lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankRoot, lockRankTrace}, 223 lockRankNetpollInit: {lockRankTimers}, 224 225 lockRankRwmutexW: {}, 226 lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW}, 227 228 lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings}, 229 lockRankGscan: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankSpanSetSpine}, 230 lockRankStackpool: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankSpanSetSpine, lockRankGscan}, 231 lockRankStackLarge: {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan}, 232 lockRankDefer: {}, 233 lockRankSudog: {lockRankHchan, lockRankNotifyList}, 234 lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog}, 235 lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans}, 236 lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings}, 237 lockRankGlobalAlloc: {lockRankProf, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial}, 238 lockRankPageAllocScav: {lockRankMheap}, 239 240 lockRankGFree: {lockRankSched}, 241 lockRankHchanLeaf: {lockRankGscan, lockRankHchanLeaf}, 242 lockRankPanic: {lockRankDeadlock}, // plus any other lock held on throw. 243 244 lockRankNewmHandoff: {}, 245 lockRankDebugPtrmask: {}, 246 lockRankFaketimeState: {}, 247 lockRankTicks: {}, 248 lockRankRaceFini: {}, 249 lockRankPollCache: {}, 250 lockRankDebug: {}, 251 }