Record lock-free guard acquisitions and report whether a later attempt was blocked.

compare-and-exchange acquire A coordination report records nonblocking acquire attempts. A `std::atomic<int>` permit starts at zero, and `compare_exchange_strong` swaps it to one only when it still reads zero, so the first attempt takes the permit and returns true while a later attempt in the same run reads one and returns false. The exchange never blocks and never spawns a thread, so the report stays deterministic: the status line summarizes whether the guard stayed idle, guarded a single holder, or blocked a later acquire.

Atomic Guard Coordination Report

attempts
atomic_guard_coordination_report.cpp
Replay: real traced execution (multi-file project)
#include <atomic>
#include <iostream>
#include <string>

int main() {
    int attempts = 1;
    std::atomic<int> permit{0};
    int acquired = 0;
    int blocked = 0;

    for (int i = 0; i < attempts; ++i) {
        int expected = 0;
        if (permit.compare_exchange_strong(expected, 1)) {
            acquired += 1;
        } else {
            blocked += 1;
        }
    }

    std::string status;
    if (acquired == 0) {
        status = "idle";
    } else if (blocked > 0) {
        status = "blocked";
    } else {
        status = "guarded";
    }

    std::cout << "attempts=" << attempts
              << " acquired=" << acquired
              << " blocked=" << blocked
              << " " << status << std::endl;
    return 0;
}
#include <atomic>
#include <iostream>
#include <string>

int main() {
    int attempts = 0;
    std::atomic<int> permit{0};
    int acquired = 0;
    int blocked = 0;

    for (int i = 0; i < attempts; ++i) {
        int expected = 0;
        if (permit.compare_exchange_strong(expected, 1)) {
            acquired += 1;
        } else {
            blocked += 1;
        }
    }

    std::string status;
    if (acquired == 0) {
        status = "idle";
    } else if (blocked > 0) {
        status = "blocked";
    } else {
        status = "guarded";
    }

    std::cout << "attempts=" << attempts
              << " acquired=" << acquired
              << " blocked=" << blocked
              << " " << status << std::endl;
    return 0;
}
#include <atomic>
#include <iostream>
#include <string>

int main() {
    int attempts = 2;
    std::atomic<int> permit{0};
    int acquired = 0;
    int blocked = 0;

    for (int i = 0; i < attempts; ++i) {
        int expected = 0;
        if (permit.compare_exchange_strong(expected, 1)) {
            acquired += 1;
        } else {
            blocked += 1;
        }
    }

    std::string status;
    if (acquired == 0) {
        status = "idle";
    } else if (blocked > 0) {
        status = "blocked";
    } else {
        status = "guarded";
    }

    std::cout << "attempts=" << attempts
              << " acquired=" << acquired
              << " blocked=" << blocked
              << " " << status << std::endl;
    return 0;
}
  1. attempts ← 1, permit ← 0, acquired ← 0, blocked ← 0

    5int main() {6    int attempts→ 1 = 1; //@attempts=0, 27    std::atomic<int> permit→ 0{0};8    int acquired→ 0 = 0;9    int blocked→ 0 = 0;
  2. expected ← 0

    11for (int i0 = 0; i < attempts1; ++i) {12    int expected→ 0 = 0;13    if (permit.compare_exchange_strong(expected, 1)) {
  3. acquired ← 1

    12int expected = 0;13if (permit1.compare_exchange_strong(expected0, 1)) {14    acquired→ 1 += 1;15} else {
  4. status ← (empty)

    20std::string status→ (empty);21if (acquired == 0) {
  5. status ← guarded

    24    status = "blocked";25} else {26    status→ guarded = "guarded";27}
  6. std::cout << "attempts=" << attempts

    29    std::cout << "attempts=" << attempts130              << " acquired=" << acquired131              << " blocked=" << blocked032              << " " << statusguarded << std::endl;33    return 0;34}
    outputattempts=1 acquired=1 blocked=0 guarded
  1. attempts ← 0, permit ← 0, acquired ← 0, blocked ← 0, status ← (empty)

    5int main() {6    int attempts→ 0 = 0;7    std::atomic<int> permit→ 0{0};8    int acquired→ 0 = 0;9    int blocked→ 0 = 0;1011    for (int i = 0; i < attempts; ++i) {12        int expected = 0;13        if (permit.compare_exchange_strong(expected, 1)) {14            acquired += 1;15        } else {16            blocked += 1;17        }18    }1920    std::string status→ (empty);21    if (acquired == 0) {
  2. status ← idle

    20std::string status;21if (acquired0 == 0) {22    status→ idle = "idle";23} else if (blocked > 0) {
  3. std::cout << "attempts=" << attempts

    29    std::cout << "attempts=" << attempts030              << " acquired=" << acquired031              << " blocked=" << blocked032              << " " << statusidle << std::endl;33    return 0;34}
    outputattempts=0 acquired=0 blocked=0 idle
  1. attempts ← 2, permit ← 0, acquired ← 0, blocked ← 0

    5int main() {6    int attempts→ 2 = 2;7    std::atomic<int> permit→ 0{0};8    int acquired→ 0 = 0;9    int blocked→ 0 = 0;
  2. expected ← 0

    pass 1 of 2
    11for (int i0 = 0; i < attempts2; ++i) {12    int expected→ 0 = 0;13    if (permit.compare_exchange_strong(expected, 1)) {
  3. acquired ← 1

    12int expected = 0;13if (permit1.compare_exchange_strong(expected0, 1)) {14    acquired→ 1 += 1;15} else {
  4. expected ← 0

    pass 2 of 2
    11for (int i1 = 0; i < attempts2; ++i) {12    int expected→ 0 = 0;13    if (permit.compare_exchange_strong(expected, 1)) {
  5. blocked ← 1

    14    acquired += 1;15} else {16    blocked→ 1 += 1;17}
  6. status ← (empty)

    20std::string status→ (empty);21if (acquired == 0) {
  7. status ← blocked

    22    status = "idle";23} else if (blocked1 > 0) {24    status→ blocked = "blocked";25} else {
  8. std::cout << "attempts=" << attempts

    29    std::cout << "attempts=" << attempts230              << " acquired=" << acquired131              << " blocked=" << blocked132              << " " << statusblocked << std::endl;33    return 0;34}
    outputattempts=2 acquired=1 blocked=1 blocked