Record guarded acquisitions against a fixed budget and report how it was spent.

acquisition budget A coordination report can cap how many guarded sections run. Each iteration takes the lock with `sync.Mutex.TryLock` and releases it, but only while a fixed limit of acquisitions remains. The selected budget controls how many attempts are offered: the report stays unused when none are offered, reads spent when the budget fits the limit, and reads capped when extra attempts are rejected past the limit.

Mutex Budget Coordination Report

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

import (
	"fmt"
	"sync"
)

func main() {
	var budget = 2
	limit := 2
	var lock sync.Mutex
	acquired := 0
	rejected := 0
	for i := 0; i < budget; i++ {
		if acquired < limit {
			ok := lock.TryLock()
			if ok {
				acquired++
				lock.Unlock()
			}
		} else {
			rejected++
		}
	}
	var status string
	if acquired == 0 {
		status = "unused"
	} else if rejected > 0 {
		status = "capped"
	} else {
		status = "spent"
	}
	fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget, acquired, rejected, status)
}
package main

import (
	"fmt"
	"sync"
)

func main() {
	var budget = 0
	limit := 2
	var lock sync.Mutex
	acquired := 0
	rejected := 0
	for i := 0; i < budget; i++ {
		if acquired < limit {
			ok := lock.TryLock()
			if ok {
				acquired++
				lock.Unlock()
			}
		} else {
			rejected++
		}
	}
	var status string
	if acquired == 0 {
		status = "unused"
	} else if rejected > 0 {
		status = "capped"
	} else {
		status = "spent"
	}
	fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget, acquired, rejected, status)
}
package main

import (
	"fmt"
	"sync"
)

func main() {
	var budget = 3
	limit := 2
	var lock sync.Mutex
	acquired := 0
	rejected := 0
	for i := 0; i < budget; i++ {
		if acquired < limit {
			ok := lock.TryLock()
			if ok {
				acquired++
				lock.Unlock()
			}
		} else {
			rejected++
		}
	}
	var status string
	if acquired == 0 {
		status = "unused"
	} else if rejected > 0 {
		status = "capped"
	} else {
		status = "spent"
	}
	fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget, acquired, rejected, status)
}
  1. budget ← 2, limit ← 2, lock ← sync.Mutex{state:0, sema:0x0}, acquired ← 0

    8func main() {9  var budget→ 2 = 2 //@budget=0, 310  limit→ 2 := 211  var lock→ sync.Mutex{state:0, sema:0x0} sync.Mutex12  acquired→ 0 := 013  rejected→ 0 := 014  for i := 0; i < budget; i++ {
  2. for i := 0; i < budget; i++

    pass 1 of 2
    13rejected := 014for i0 := 0; i < budget2; i++ {15  if acquired < limit {
  3. lock ← sync.Mutex{state:1, sema:0x0}, ok ← true

    pass 1 of 2
    14for i := 0; i < budget; i++ {15  if acquired0 < limit2 {16    ok→ true := lock→ sync.Mutex{state:1, sema:0x0}.TryLock()17    if ok {
  4. acquired ← 1, lock ← sync.Mutex{state:0, sema:0x0}

    pass 1 of 2
    16ok := lock.TryLock()17if oktrue {18  acquired→ 1++19  lock→ sync.Mutex{state:0, sema:0x0}.Unlock()20}
  5. for i := 0; i < budget; i++

    pass 2 of 2
    13rejected := 014for i1 := 0; i < budget2; i++ {15  if acquired < limit {
  6. lock ← sync.Mutex{state:1, sema:0x0}, ok ← true

    pass 2 of 2
    14for i := 0; i < budget; i++ {15  if acquired1 < limit2 {16    ok→ true := lock→ sync.Mutex{state:1, sema:0x0}.TryLock()17    if ok {
  7. acquired ← 2, lock ← sync.Mutex{state:0, sema:0x0}

    pass 2 of 2
    16ok := lock.TryLock()17if oktrue {18  acquired→ 2++19  lock→ sync.Mutex{state:0, sema:0x0}.Unlock()20}
  8. status ← ""

    24}25var status→ "" string26if acquired == 0 {
  9. status ← "spent"

    29  status = "capped"30} else {31  status→ "spent" = "spent"32}
  10. fmt.Printf("budget=%d acquired=%d rejected=%d %s ", budget, acquired, …

    32  }33  fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget2, acquired2, rejected0, status"spent")34}
    outputbudget=2 acquired=2 rejected=0 spent
  1. budget ← 0, limit ← 2, lock ← sync.Mutex{state:0, sema:0x0}, acquired ← 0

    8func main() {9  var budget→ 0 = 010  limit→ 2 := 211  var lock→ sync.Mutex{state:0, sema:0x0} sync.Mutex12  acquired→ 0 := 013  rejected→ 0 := 014  for i := 0; i < budget; i++ {15    if acquired < limit {16      ok := lock.TryLock()17      if ok {18        acquired++19        lock.Unlock()20      }21    } else {22      rejected++23    }24  }25  var status→ "" string26  if acquired == 0 {
  2. status ← "unused"

    25var status string26if acquired0 == 0 {27  status→ "unused" = "unused"28} else if rejected > 0 {
  3. fmt.Printf("budget=%d acquired=%d rejected=%d %s ", budget, acquired, …

    32  }33  fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget0, acquired0, rejected0, status"unused")34}
    outputbudget=0 acquired=0 rejected=0 unused
  1. budget ← 3, limit ← 2, lock ← sync.Mutex{state:0, sema:0x0}, acquired ← 0

    8func main() {9  var budget→ 3 = 310  limit→ 2 := 211  var lock→ sync.Mutex{state:0, sema:0x0} sync.Mutex12  acquired→ 0 := 013  rejected→ 0 := 014  for i := 0; i < budget; i++ {
  2. for i := 0; i < budget; i++

    pass 1 of 3
    13rejected := 014for i0 := 0; i < budget3; i++ {15  if acquired < limit {
    All 3 passes — pass 1 is the card above
    passilimitlockokacquiredrejected
    102sync.Mutex{state:0, sema:0x0} sync.Mutex{state:1, sema:0x0}true0 1
    212sync.Mutex{state:0, sema:0x0} sync.Mutex{state:1, sema:0x0}true1 2
    320 1
  3. lock ← sync.Mutex{state:1, sema:0x0}, ok ← true

    pass 1 of 2
    14for i := 0; i < budget; i++ {15  if acquired0 < limit2 {16    ok→ true := lock→ sync.Mutex{state:1, sema:0x0}.TryLock()17    if ok {
  4. acquired ← 1, lock ← sync.Mutex{state:0, sema:0x0}

    pass 1 of 2
    16ok := lock.TryLock()17if oktrue {18  acquired→ 1++19  lock→ sync.Mutex{state:0, sema:0x0}.Unlock()20}
  5. lock ← sync.Mutex{state:1, sema:0x0}, ok ← true

    pass 2 of 2
    14for i := 0; i < budget; i++ {15  if acquired1 < limit2 {16    ok→ true := lock→ sync.Mutex{state:1, sema:0x0}.TryLock()17    if ok {
  6. acquired ← 2, lock ← sync.Mutex{state:0, sema:0x0}

    pass 2 of 2
    16ok := lock.TryLock()17if oktrue {18  acquired→ 2++19  lock→ sync.Mutex{state:0, sema:0x0}.Unlock()20}
  7. rejected ← 1

    20  }21} else {22  rejected→ 1++23}
  8. status ← ""

    24}25var status→ "" string26if acquired == 0 {
  9. status ← "capped"

    27  status = "unused"28} else if rejected1 > 0 {29  status→ "capped" = "capped"30} else {
  10. fmt.Printf("budget=%d acquired=%d rejected=%d %s ", budget, acquired, …

    32  }33  fmt.Printf("budget=%d acquired=%d rejected=%d %s\n", budget3, acquired2, rejected1, status"capped")34}
    outputbudget=3 acquired=2 rejected=1 capped