Record shared read permits against a fixed pool and report the access mode.

shared permits A coordination report can record how a shared pool is occupied. A `SemaphoreSlim` created with several permits models a pool of shared read slots, and `Wait(0)` takes one slot without blocking. With no slots taken the pool is writable for an exclusive writer, with one slot taken access is single, and with every slot taken access is fully shared. The status line summarizes whether the pool stayed writable, single, or shared after the recorded read attempts.

Reader Pool Coordination Report

readers
ReaderPoolCoordinationReport.cs
Replay: real traced execution (multi-file project)
using System;
using System.Threading;

class Program
{
    static void Main()
    {
        int readers = 1;
        int slots = 3;
        var pool = new SemaphoreSlim(slots, slots);
        int held = 0;

        for (int i = 0; i < readers; i++)
        {
            if (pool.Wait(0))
            {
                held++;
            }
        }

        int free = pool.CurrentCount;

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

        Console.WriteLine("readers=" + readers + " held=" + held + " free=" + free + " " + status);
    }
}
using System;
using System.Threading;

class Program
{
    static void Main()
    {
        int readers = 0;
        int slots = 3;
        var pool = new SemaphoreSlim(slots, slots);
        int held = 0;

        for (int i = 0; i < readers; i++)
        {
            if (pool.Wait(0))
            {
                held++;
            }
        }

        int free = pool.CurrentCount;

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

        Console.WriteLine("readers=" + readers + " held=" + held + " free=" + free + " " + status);
    }
}
using System;
using System.Threading;

class Program
{
    static void Main()
    {
        int readers = 3;
        int slots = 3;
        var pool = new SemaphoreSlim(slots, slots);
        int held = 0;

        for (int i = 0; i < readers; i++)
        {
            if (pool.Wait(0))
            {
                held++;
            }
        }

        int free = pool.CurrentCount;

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

        Console.WriteLine("readers=" + readers + " held=" + held + " free=" + free + " " + status);
    }
}
  1. readers ← 1, slots ← 3, pool ← System.Threading.SemaphoreSlim

    5{6    static void Main()7    {8        int readers→ 1 = 1; //@readers=0, 39        int slots→ 3 = 3;10        var pool→ System.Threading.SemaphoreSlim = new SemaphoreSlim(slots, slots);11        int held→ 0 = 0;
  2. for (int i = 0; i < readers; i++)

    13for (int i0 = 0; i < readers1; i++)14{15    if (pool.Wait(0))
  3. held ← 1

    14{15    if (poolSystem.Threading.SemaphoreSlim.Wait(0))16    {17        held→ 1++;18    }
  4. free ← 2

    21int free→ 2 = pool.CurrentCount2;2223string status;24if (held == 0)
  5. status ← single

    31}32else33{34    status→ single = "single";35}
  6. Console.WriteLine("readers=" + readers + " held=" + held + " free=" + …

    37    Console.WriteLine("readers=" + readers1 + " held=" + held1 + " free=" + free2 + " " + statussingle);38}
    outputreaders=1 held=1 free=2 single
  1. readers ← 0, slots ← 3, pool ← System.Threading.SemaphoreSlim

    5{6    static void Main()7    {8        int readers→ 0 = 0;9        int slots→ 3 = 3;10        var pool→ System.Threading.SemaphoreSlim = new SemaphoreSlim(slots, slots);11        int held→ 0 = 0;1213        for (int i = 0; i < readers; i++)14        {15            if (pool.Wait(0))16            {17                held++;18            }19        }2021        int free→ 3 = pool.CurrentCount3;2223        string status;24        if (held == 0)
  2. status ← writable

    23string status;24if (held0 == 0)25{26    status→ writable = "writable";27}
  3. Console.WriteLine("readers=" + readers + " held=" + held + " free=" + …

    37    Console.WriteLine("readers=" + readers0 + " held=" + held0 + " free=" + free3 + " " + statuswritable);38}
    outputreaders=0 held=0 free=3 writable
  1. readers ← 3, slots ← 3, pool ← System.Threading.SemaphoreSlim

    5{6    static void Main()7    {8        int readers→ 3 = 3;9        int slots→ 3 = 3;10        var pool→ System.Threading.SemaphoreSlim = new SemaphoreSlim(slots, slots);11        int held→ 0 = 0;
  2. for (int i = 0; i < readers; i++)

    pass 1 of 3
    13for (int i0 = 0; i < readers3; i++)14{15    if (pool.Wait(0))
    All 3 passes — pass 1 is the card above
    passi
    10
    21
    32
  3. held ← 1

    pass 1 of 3
    14{15    if (poolSystem.Threading.SemaphoreSlim.Wait(0))16    {17        held→ 1++;18    }
    All 3 passes — pass 1 is the card above
    passheld
    10 1
    21 2
    32 3
  4. free ← 0

    21int free→ 0 = pool.CurrentCount0;2223string status;24if (held == 0)
  5. status ← shared

    27}28else if (held3 == slots3)29{30    status→ shared = "shared";31}
  6. Console.WriteLine("readers=" + readers + " held=" + held + " free=" + …

    37    Console.WriteLine("readers=" + readers3 + " held=" + held3 + " free=" + free0 + " " + statusshared);38}
    outputreaders=3 held=3 free=0 shared