A coordination report records nonblocking lock attempts. This program uses Mutex::try_lock, keeps each acquired guard, and reports whether a later attempt was blocked.

Program

Play the program to choose how many acquire attempts run and watch the guard report stay open or block.

holds
mutex_try_lock_coordination_report.rs
Replay: real traced execution (multi-file project)
use std::sync::Mutex;

fn main() {
    let holds = 1;
    let lock = Mutex::new(0u32);
    let mut acquired = 0;
    let mut blocked = 0;
    let mut kept = Vec::new();
    for _ in 0..holds {
        match lock.try_lock() {
            Ok(guard) => {
                acquired += 1;
                kept.push(guard);
            }
            Err(_) => blocked += 1,
        }
    }
    let status = if acquired == 0 {
        "idle"
    } else if blocked > 0 {
        "blocked"
    } else {
        "guarded"
    };
    println!("holds={holds} acquired={acquired} blocked={blocked} {status}");
}
use std::sync::Mutex;

fn main() {
    let holds = 0;
    let lock = Mutex::new(0u32);
    let mut acquired = 0;
    let mut blocked = 0;
    let mut kept = Vec::new();
    for _ in 0..holds {
        match lock.try_lock() {
            Ok(guard) => {
                acquired += 1;
                kept.push(guard);
            }
            Err(_) => blocked += 1,
        }
    }
    let status = if acquired == 0 {
        "idle"
    } else if blocked > 0 {
        "blocked"
    } else {
        "guarded"
    };
    println!("holds={holds} acquired={acquired} blocked={blocked} {status}");
}
use std::sync::Mutex;

fn main() {
    let holds = 2;
    let lock = Mutex::new(0u32);
    let mut acquired = 0;
    let mut blocked = 0;
    let mut kept = Vec::new();
    for _ in 0..holds {
        match lock.try_lock() {
            Ok(guard) => {
                acquired += 1;
                kept.push(guard);
            }
            Err(_) => blocked += 1,
        }
    }
    let status = if acquired == 0 {
        "idle"
    } else if blocked > 0 {
        "blocked"
    } else {
        "guarded"
    };
    println!("holds={holds} acquired={acquired} blocked={blocked} {status}");
}
  1. holds ← 1, lock ← Mutex { data: 0, poisoned: false, .. }, acquired ← 0

    3fn main() {4    let hold→ 1s = 1; //@holds=1, 0, 25    let loc→ Mutex { data: 0, poisoned: false, .. }k = Mutex::new(0u32);6    let mut acquire→ 0d = 0;7    let mut blocke→ 0d = 0;8    let mut kep→ []t = Vec::new();9    for _ in 0..holds {
  2. for _ in 0..holds

    8let mut kept = Vec::new();9for _ in 0..hold1s {10    match lock.try_lock() {
  3. acquired ← 1

    10match lock.try_lock() {11    Ok(guard) => {12        acquire→ 1d += 1;13        kept.push(guard);14    }
  4. status ← "guarded"

    17    }18    let statu→ "guarded"s = if acquire1d == 0 {19        "idle"20    } else if blocke0d > 0 {21        "blocked"22    } else {23        "guarded"24    };25    println!("holds={holds} acquired={acquired} blocked={blocked} {status}");26}
    outputholds=1 acquired=1 blocked=0 guarded
  1. holds ← 0, lock ← Mutex { data: 0, poisoned: false, .. }, acquired ← 0

    3fn main() {4    let hold→ 0s = 0;5    let loc→ Mutex { data: 0, poisoned: false, .. }k = Mutex::new(0u32);6    let mut acquire→ 0d = 0;7    let mut blocke→ 0d = 0;8    let mut kep→ []t = Vec::new();9    for _ in 0..holds {10        match lock.try_lock() {11            Ok(guard) => {12                acquired += 1;13                kept.push(guard);14            }15            Err(_) => blocked += 1,16        }17    }18    let statu→ "idle"s = if acquire0d == 0 {19        "idle"20    } else if blocke0d > 0 {21        "blocked"22    } else {23        "guarded"24    };25    println!("holds={holds} acquired={acquired} blocked={blocked} {status}");26}
    outputholds=0 acquired=0 blocked=0 idle
  1. holds ← 2, lock ← Mutex { data: 0, poisoned: false, .. }, acquired ← 0

    3fn main() {4    let hold→ 2s = 2;5    let loc→ Mutex { data: 0, poisoned: false, .. }k = Mutex::new(0u32);6    let mut acquire→ 0d = 0;7    let mut blocke→ 0d = 0;8    let mut kep→ []t = Vec::new();9    for _ in 0..holds {
  2. for _ in 0..holds

    pass 1 of 2
    8let mut kept = Vec::new();9for _ in 0..hold2s {10    match lock.try_lock() {
  3. acquired ← 1

    10match lock.try_lock() {11    Ok(guard) => {12        acquire→ 1d += 1;13        kept.push(guard);14    }
  4. for _ in 0..holds

    pass 2 of 2
    8let mut kept = Vec::new();9for _ in 0..hold2s {10    match lock.try_lock() {
  5. status ← "blocked"

    17    }18    let statu→ "blocked"s = if acquire1d == 0 {19        "idle"20    } else if blocke1d > 0 {21        "blocked"22    } else {23        "guarded"24    };25    println!("holds={holds} acquired={acquired} blocked={blocked} {status}");26}
    outputholds=2 acquired=1 blocked=1 blocked
nonblocking acquire `Mutex::try_lock` returns `Ok` when it takes the guard and `Err` when the guard is already held, so it never blocks.
held guard Pushing each acquired guard into `kept` keeps the lock held, so a later attempt in the same run is reported as blocked.
coordination status The status line summarizes whether the section stayed idle, guarded, or blocked a later acquire.