Spend a contention budget against a fixed limit and turn the acquired and rejected counts into a spend, drain, or throttle remediation action.

budget limit The contention limit and budget are scalars, so the acquired and rejected counts that drive the remediation action stay deterministic and free of lock identity.

Mutex Budget Remediation Report

budget
mutex_budget_remediation_report.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

func main() {
	var budget = 1
	limit := 2
	acquired := 0
	rejected := 0
	for i := 0; i < budget; i++ {
		if acquired < limit {
			acquired++
		} else {
			rejected++
		}
	}
	remaining := limit - acquired
	var action string
	if rejected > 0 {
		action = "throttle"
	} else if remaining == 0 {
		action = "drain"
	} else {
		action = "spend"
	}
	fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget, acquired, rejected, action)
}
package main

import "fmt"

func main() {
	var budget = 2
	limit := 2
	acquired := 0
	rejected := 0
	for i := 0; i < budget; i++ {
		if acquired < limit {
			acquired++
		} else {
			rejected++
		}
	}
	remaining := limit - acquired
	var action string
	if rejected > 0 {
		action = "throttle"
	} else if remaining == 0 {
		action = "drain"
	} else {
		action = "spend"
	}
	fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget, acquired, rejected, action)
}
package main

import "fmt"

func main() {
	var budget = 4
	limit := 2
	acquired := 0
	rejected := 0
	for i := 0; i < budget; i++ {
		if acquired < limit {
			acquired++
		} else {
			rejected++
		}
	}
	remaining := limit - acquired
	var action string
	if rejected > 0 {
		action = "throttle"
	} else if remaining == 0 {
		action = "drain"
	} else {
		action = "spend"
	}
	fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget, acquired, rejected, action)
}
  1. budget ← 1, limit ← 2, acquired ← 0, rejected ← 0

    5func main() {6  var budget→ 1 = 1 //@budget=2, 47  limit→ 2 := 28  acquired→ 0 := 09  rejected→ 0 := 010  for i := 0; i < budget; i++ {
  2. for i := 0; i < budget; i++

    9rejected := 010for i0 := 0; i < budget1; i++ {11  if acquired < limit {
  3. acquired ← 1

    10for i := 0; i < budget; i++ {11  if acquired0 < limit2 {12    acquired→ 1++13  } else {
  4. remaining ← 1, action ← ""

    16}17remaining→ 1 := limit2 - acquired118var action→ "" string19if rejected > 0 {
  5. action ← "spend"

    22  action = "drain"23} else {24  action→ "spend" = "spend"25}
  6. fmt.Printf("budget=%d acquired=%d rejected=%d %s ", budget, acquired, …

    25  }26  fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget1, acquired1, rejected0, action"spend")27}
    outputbudget=1 acquired=1 rejected=0 spend
  1. budget ← 2, limit ← 2, acquired ← 0, rejected ← 0

    5func main() {6  var budget→ 2 = 27  limit→ 2 := 28  acquired→ 0 := 09  rejected→ 0 := 010  for i := 0; i < budget; i++ {
  2. for i := 0; i < budget; i++

    pass 1 of 2
    9rejected := 010for i0 := 0; i < budget2; i++ {11  if acquired < limit {
  3. acquired ← 1

    pass 1 of 2
    10for i := 0; i < budget; i++ {11  if acquired0 < limit2 {12    acquired→ 1++13  } else {
  4. for i := 0; i < budget; i++

    pass 2 of 2
    9rejected := 010for i1 := 0; i < budget2; i++ {11  if acquired < limit {
  5. acquired ← 2

    pass 2 of 2
    10for i := 0; i < budget; i++ {11  if acquired1 < limit2 {12    acquired→ 2++13  } else {
  6. remaining ← 0, action ← ""

    16}17remaining→ 0 := limit2 - acquired218var action→ "" string19if rejected > 0 {
  7. action ← "drain"

    20  action = "throttle"21} else if remaining0 == 0 {22  action→ "drain" = "drain"23} else {
  8. fmt.Printf("budget=%d acquired=%d rejected=%d %s ", budget, acquired, …

    25  }26  fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget2, acquired2, rejected0, action"drain")27}
    outputbudget=2 acquired=2 rejected=0 drain
  1. budget ← 4, limit ← 2, acquired ← 0, rejected ← 0

    5func main() {6  var budget→ 4 = 47  limit→ 2 := 28  acquired→ 0 := 09  rejected→ 0 := 010  for i := 0; i < budget; i++ {
  2. for i := 0; i < budget; i++

    pass 1 of 4
    9rejected := 010for i0 := 0; i < budget4; i++ {11  if acquired < limit {
    All 4 passes — pass 1 is the card above
    passilimitacquiredrejected
    1020 1
    2121 2
    320 1
    431 2
  3. acquired ← 1

    pass 1 of 2
    10for i := 0; i < budget; i++ {11  if acquired0 < limit2 {12    acquired→ 1++13  } else {
  4. acquired ← 2

    pass 2 of 2
    10for i := 0; i < budget; i++ {11  if acquired1 < limit2 {12    acquired→ 2++13  } else {
  5. rejected ← 1

    pass 1 of 2
    12  acquired++13} else {14  rejected→ 1++15}
  6. rejected ← 2

    pass 2 of 2
    12  acquired++13} else {14  rejected→ 2++15}
  7. remaining ← 0, action ← ""

    16}17remaining→ 0 := limit2 - acquired218var action→ "" string19if rejected > 0 {
  8. action ← "throttle"

    18var action string19if rejected2 > 0 {20  action→ "throttle" = "throttle"21} else if remaining == 0 {
  9. fmt.Printf("budget=%d acquired=%d rejected=%d %s ", budget, acquired, …

    25  }26  fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget4, acquired2, rejected2, action"throttle")27}
    outputbudget=4 acquired=2 rejected=2 throttle