Admit shared readers up to a fixed pool and report whether a writer could still run.

shared admission count A reader pool admits several shared holders at once but excludes a writer while any reader is active. A `std::atomic<int>` active count is incremented with `fetch_add` for each admitted reader as long as it stays under the pool capacity, so the count is the number of concurrent readers a writer would have to wait behind. Because the increments run in a single deterministic pass with no blocking, the report shows how many slots are held versus free and labels the section writable when empty, single for one reader, or shared for many.

Reader Pool Coordination Report

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

int main() {
    int readers = 1;
    const int capacity = 3;
    std::atomic<int> active{0};
    int held = 0;

    for (int i = 0; i < readers; ++i) {
        if (active.load() < capacity) {
            active.fetch_add(1);
            held += 1;
        }
    }

    int idle = capacity - held;

    std::string status;
    if (held == 0) {
        status = "writable";
    } else if (held == 1) {
        status = "single";
    } else {
        status = "shared";
    }

    std::cout << "readers=" << readers
              << " held=" << held
              << " free=" << idle
              << " " << status << std::endl;
    return 0;
}
#include <atomic>
#include <iostream>
#include <string>

int main() {
    int readers = 0;
    const int capacity = 3;
    std::atomic<int> active{0};
    int held = 0;

    for (int i = 0; i < readers; ++i) {
        if (active.load() < capacity) {
            active.fetch_add(1);
            held += 1;
        }
    }

    int idle = capacity - held;

    std::string status;
    if (held == 0) {
        status = "writable";
    } else if (held == 1) {
        status = "single";
    } else {
        status = "shared";
    }

    std::cout << "readers=" << readers
              << " held=" << held
              << " free=" << idle
              << " " << status << std::endl;
    return 0;
}
#include <atomic>
#include <iostream>
#include <string>

int main() {
    int readers = 3;
    const int capacity = 3;
    std::atomic<int> active{0};
    int held = 0;

    for (int i = 0; i < readers; ++i) {
        if (active.load() < capacity) {
            active.fetch_add(1);
            held += 1;
        }
    }

    int idle = capacity - held;

    std::string status;
    if (held == 0) {
        status = "writable";
    } else if (held == 1) {
        status = "single";
    } else {
        status = "shared";
    }

    std::cout << "readers=" << readers
              << " held=" << held
              << " free=" << idle
              << " " << status << std::endl;
    return 0;
}
  1. readers ← 1, capacity ← 3, active ← 0, held ← 0

    5int main() {6    int readers→ 1 = 1; //@readers=0, 37    const int capacity→ 3 = 3;8    std::atomic<int> active→ 0{0};9    int held→ 0 = 0;
  2. for (int i = 0; i < readers; ++i)

    11for (int i0 = 0; i < readers1; ++i) {12    if (active.load() < capacity) {
  3. active ← 1, held ← 1

    11for (int i = 0; i < readers; ++i) {12    if (active0.load() < capacity3) {13        active→ 1.fetch_add(1);14        held→ 1 += 1;15    }
  4. idle ← 2, status ← (empty)

    18int idle→ 2 = capacity3 - held1;1920std::string status→ (empty);21if (held == 0) {
  5. status ← single

    22    status = "writable";23} else if (held1 == 1) {24    status→ single = "single";25} else {
  6. std::cout << "readers=" << readers

    29    std::cout << "readers=" << readers130              << " held=" << held131              << " free=" << idle232              << " " << statussingle << std::endl;33    return 0;34}
    outputreaders=1 held=1 free=2 single
  1. readers ← 0, capacity ← 3, active ← 0, held ← 0, idle ← 3, status ← (empty)

    5int main() {6    int readers→ 0 = 0;7    const int capacity→ 3 = 3;8    std::atomic<int> active→ 0{0};9    int held→ 0 = 0;1011    for (int i = 0; i < readers; ++i) {12        if (active.load() < capacity) {13            active.fetch_add(1);14            held += 1;15        }16    }1718    int idle→ 3 = capacity3 - held0;1920    std::string status→ (empty);21    if (held == 0) {
  2. status ← writable

    20std::string status;21if (held0 == 0) {22    status→ writable = "writable";23} else if (held == 1) {
  3. std::cout << "readers=" << readers

    29    std::cout << "readers=" << readers030              << " held=" << held031              << " free=" << idle332              << " " << statuswritable << std::endl;33    return 0;34}
    outputreaders=0 held=0 free=3 writable
  1. readers ← 3, capacity ← 3, active ← 0, held ← 0

    5int main() {6    int readers→ 3 = 3;7    const int capacity→ 3 = 3;8    std::atomic<int> active→ 0{0};9    int held→ 0 = 0;
  2. for (int i = 0; i < readers; ++i)

    pass 1 of 3
    11for (int i0 = 0; i < readers3; ++i) {12    if (active.load() < capacity) {
    All 3 passes — pass 1 is the card above
    passi
    10
    21
    32
  3. active ← 1, held ← 1

    pass 1 of 3
    11for (int i = 0; i < readers; ++i) {12    if (active0.load() < capacity3) {13        active→ 1.fetch_add(1);14        held→ 1 += 1;15    }
    All 3 passes — pass 1 is the card above
    passactiveheld
    10 10 1
    21 21 2
    32 32 3
  4. idle ← 0, status ← (empty)

    18int idle→ 0 = capacity3 - held3;1920std::string status→ (empty);21if (held == 0) {
  5. status ← shared

    24    status = "single";25} else {26    status→ shared = "shared";27}
  6. std::cout << "readers=" << readers

    29    std::cout << "readers=" << readers330              << " held=" << held331              << " free=" << idle032              << " " << statusshared << std::endl;33    return 0;34}
    outputreaders=3 held=3 free=0 shared