Attempt a nonblocking mutex acquisition a fixed number of times and report whether the guard stayed open or blocked a later attempt.

nonblocking mutex `Mutex#try_lock` returns `true` when it takes the lock and `false` when the guard is already held, so a second attempt that fails reports that the mutex is not reentrant and the section is busy.

Mutex Try-Lock Coordination Report

holds
mutex_try_lock_coordination_report.rb
Replay: real traced execution (multi-file project)
holds = 1
guard = Mutex.new
acquired = 0
blocked = 0

holds.times do
  if guard.try_lock
    acquired += 1
  else
    blocked += 1
  end
end

guard.unlock if guard.locked?

status = if acquired == 0
  "open"
elsif blocked > 0
  "blocked"
else
  "guarded"
end

puts "holds=#{holds}"
puts "acquired=#{acquired}"
puts "blocked=#{blocked}"
puts "status=#{status}"
holds = 0
guard = Mutex.new
acquired = 0
blocked = 0

holds.times do
  if guard.try_lock
    acquired += 1
  else
    blocked += 1
  end
end

guard.unlock if guard.locked?

status = if acquired == 0
  "open"
elsif blocked > 0
  "blocked"
else
  "guarded"
end

puts "holds=#{holds}"
puts "acquired=#{acquired}"
puts "blocked=#{blocked}"
puts "status=#{status}"
holds = 2
guard = Mutex.new
acquired = 0
blocked = 0

holds.times do
  if guard.try_lock
    acquired += 1
  else
    blocked += 1
  end
end

guard.unlock if guard.locked?

status = if acquired == 0
  "open"
elsif blocked > 0
  "blocked"
else
  "guarded"
end

puts "holds=#{holds}"
puts "acquired=#{acquired}"
puts "blocked=#{blocked}"
puts "status=#{status}"
  1. holds ← 1, guard ← ⟨Thread::Mutex A⟩, acquired ← 0, blocked ← 0

    1holds→ 1 = 1  #@holds=0, 22guard→ ⟨Thread::Mutex A⟩ = Mutex.new3acquired→ 0 = 04blocked→ 0 = 056holds1.times do7  if guard.try_lock8    acquired += 19  else10    blocked += 111  end12end
  2. acquired ← 1

    6holds1.times do7  if guard.try_lockfalse8    acquired→ 1 += 19  else10    blocked += 111  end12end
  3. status ← guarded

    16status→ guarded = if acquired1 == 017  "open"18elsif blocked0 > 019  "blocked"20else21  "guarded"22end2324puts "holds=#{holds1}"25puts "acquired=#{acquired1}"26puts "blocked=#{blocked0}"27puts "status=#{statusguarded}"
    outputholds=1
    acquired=1
    blocked=0
    status=guarded
  1. holds ← 0, guard ← ⟨Thread::Mutex A⟩, acquired ← 0, blocked ← 0

    1holds→ 0 = 02guard→ ⟨Thread::Mutex A⟩ = Mutex.new3acquired→ 0 = 04blocked→ 0 = 056holds0.times do7  if guard.try_lock8    acquired += 19  else10    blocked += 111  end12end1314guard.unlock if guard.locked?1516status→ open = if acquired0 == 017  "open"18elsif blocked0 > 019  "blocked"20else21  "guarded"22end2324puts "holds=#{holds0}"25puts "acquired=#{acquired0}"26puts "blocked=#{blocked0}"27puts "status=#{statusopen}"
    outputholds=0
    acquired=0
    blocked=0
    status=open
  1. holds ← 2, guard ← ⟨Thread::Mutex A⟩, acquired ← 0, blocked ← 0

    1holds→ 2 = 22guard→ ⟨Thread::Mutex A⟩ = Mutex.new3acquired→ 0 = 04blocked→ 0 = 056holds2.times do7  if guard.try_lock8    acquired += 19  else10    blocked += 111  end12end
  2. acquired ← 1

    6holds.times do7  if guard.try_lockfalse8    acquired→ 1 += 19  else
  3. blocked ← 1

    6holds2.times do7  if guard.try_lock8    acquired += 19  else10    blocked→ 1 += 111  end12end
  4. status ← blocked

    16status→ blocked = if acquired1 == 017  "open"18elsif blocked1 > 019  "blocked"20else21  "guarded"22end2324puts "holds=#{holds2}"25puts "acquired=#{acquired1}"26puts "blocked=#{blocked1}"27puts "status=#{statusblocked}"
    outputholds=2
    acquired=1
    blocked=1
    status=blocked