Black Lives Matter. Support the Equal Justice Initiative.

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

View as plain text