...

Source file src/runtime/lockrank.go

Documentation: runtime

		 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  }
	 249  

View as plain text