github.com/rafaeltorres324/go/src@v0.0.0-20210519164414-9fdf653a9838/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 lockRankPanic 48 lockRankAllg 49 lockRankAllp 50 51 lockRankTimers // Multiple timers locked simultaneously in destroy() 52 lockRankItab 53 lockRankReflectOffs 54 lockRankHchan // Multiple hchans acquired in lock order in syncadjustsudogs() 55 lockRankFin 56 lockRankNotifyList 57 lockRankTraceBuf 58 lockRankTraceStrings 59 lockRankMspanSpecial 60 lockRankProf 61 lockRankGcBitsArenas 62 lockRankRoot 63 lockRankTrace 64 lockRankTraceStackTab 65 lockRankNetpollInit 66 67 lockRankRwmutexW 68 lockRankRwmutexR 69 70 lockRankSpanSetSpine 71 lockRankGscan 72 lockRankStackpool 73 lockRankStackLarge 74 lockRankDefer 75 lockRankSudog 76 77 // Memory-related non-leaf locks 78 lockRankWbufSpans 79 lockRankMheap 80 lockRankMheapSpecial 81 82 // Memory-related leaf locks 83 lockRankGlobalAlloc 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 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 lockRankPanic: "panic", 127 lockRankAllg: "allg", 128 lockRankAllp: "allp", 129 130 lockRankTimers: "timers", 131 lockRankItab: "itab", 132 lockRankReflectOffs: "reflectOffs", 133 134 lockRankHchan: "hchan", 135 lockRankFin: "fin", 136 lockRankNotifyList: "notifyList", 137 lockRankTraceBuf: "traceBuf", 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 163 lockRankGFree: "gFree", 164 lockRankHchanLeaf: "hchanLeaf", 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 lockRankPanic: {lockRankDeadlock}, 206 lockRankAllg: {lockRankSysmon, lockRankSched, lockRankPanic}, 207 lockRankAllp: {lockRankSysmon, lockRankSched}, 208 lockRankTimers: {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllp, lockRankPollDesc, lockRankTimers}, 209 lockRankItab: {}, 210 lockRankReflectOffs: {lockRankItab}, 211 lockRankHchan: {lockRankScavenge, lockRankSweep, lockRankHchan}, 212 lockRankFin: {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan}, 213 lockRankNotifyList: {}, 214 lockRankTraceBuf: {lockRankSysmon, lockRankScavenge}, 215 lockRankTraceStrings: {lockRankTraceBuf}, 216 lockRankMspanSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings}, 217 lockRankProf: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, 218 lockRankGcBitsArenas: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, 219 lockRankRoot: {}, 220 lockRankTrace: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankSweep}, 221 lockRankTraceStackTab: {lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankTrace}, 222 lockRankNetpollInit: {lockRankTimers}, 223 224 lockRankRwmutexW: {}, 225 lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW}, 226 227 lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, 228 lockRankGscan: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot, lockRankNotifyList, lockRankProf, lockRankGcBitsArenas, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankSpanSetSpine}, 229 lockRankStackpool: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankSpanSetSpine, lockRankGscan}, 230 lockRankStackLarge: {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan}, 231 lockRankDefer: {}, 232 lockRankSudog: {lockRankNotifyList, lockRankHchan}, 233 lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProf, lockRankRoot, lockRankGscan, lockRankDefer, lockRankSudog}, 234 lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankFin, lockRankPollDesc, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan, lockRankMspanSpecial, lockRankProf, lockRankGcBitsArenas, lockRankRoot, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans, lockRankSpanSetSpine}, 235 lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankNotifyList, lockRankTraceBuf, lockRankTraceStrings, lockRankHchan}, 236 lockRankGlobalAlloc: {lockRankProf, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial}, 237 238 lockRankGFree: {lockRankSched}, 239 lockRankHchanLeaf: {lockRankGscan, lockRankHchanLeaf}, 240 241 lockRankNewmHandoff: {}, 242 lockRankDebugPtrmask: {}, 243 lockRankFaketimeState: {}, 244 lockRankTicks: {}, 245 lockRankRaceFini: {}, 246 lockRankPollCache: {}, 247 lockRankDebug: {}, 248 }