Spend a permit budget against a fixed capacity and turn the granted and denied counts into a spend, drain, or throttle remediation action.

budget capacity The permit capacity and budget are scalars, so the granted and denied counts that drive the remediation action stay deterministic and free of semaphore identity.

Semaphore Budget Remediation Report

requests
SemaphoreBudgetRemediationReport.cs
Replay: real traced execution (multi-file project)
using System;

class Program
{
    static void Main()
    {
        int requests = 1;
        int capacity = 2;
        int granted = 0;
        int denied = 0;

        for (int i = 0; i < requests; i++)
        {
            if (granted < capacity)
            {
                granted++;
            }
            else
            {
                denied++;
            }
        }
        int spare = capacity - granted;

        string action;
        if (denied > 0)
        {
            action = "throttle";
        }
        else if (spare == 0)
        {
            action = "drain";
        }
        else
        {
            action = "spend";
        }

        Console.WriteLine("requests=" + requests + " granted=" + granted + " denied=" + denied + " " + action);
    }
}
using System;

class Program
{
    static void Main()
    {
        int requests = 2;
        int capacity = 2;
        int granted = 0;
        int denied = 0;

        for (int i = 0; i < requests; i++)
        {
            if (granted < capacity)
            {
                granted++;
            }
            else
            {
                denied++;
            }
        }
        int spare = capacity - granted;

        string action;
        if (denied > 0)
        {
            action = "throttle";
        }
        else if (spare == 0)
        {
            action = "drain";
        }
        else
        {
            action = "spend";
        }

        Console.WriteLine("requests=" + requests + " granted=" + granted + " denied=" + denied + " " + action);
    }
}
using System;

class Program
{
    static void Main()
    {
        int requests = 4;
        int capacity = 2;
        int granted = 0;
        int denied = 0;

        for (int i = 0; i < requests; i++)
        {
            if (granted < capacity)
            {
                granted++;
            }
            else
            {
                denied++;
            }
        }
        int spare = capacity - granted;

        string action;
        if (denied > 0)
        {
            action = "throttle";
        }
        else if (spare == 0)
        {
            action = "drain";
        }
        else
        {
            action = "spend";
        }

        Console.WriteLine("requests=" + requests + " granted=" + granted + " denied=" + denied + " " + action);
    }
}
  1. requests ← 1, capacity ← 2, granted ← 0, denied ← 0

    4{5    static void Main()6    {7        int requests→ 1 = 1; //@requests=2, 48        int capacity→ 2 = 2;9        int granted→ 0 = 0;10        int denied→ 0 = 0;
  2. for (int i = 0; i < requests; i++)

    12for (int i0 = 0; i < requests1; i++)13{14    if (granted < capacity)
  3. granted ← 1

    13{14    if (granted0 < capacity2)15    {16        granted→ 1++;17    }
  4. spare ← 1

    22}23int spare→ 1 = capacity2 - granted1;2425string action;26if (denied > 0)
  5. action ← spend

    33}34else35{36    action→ spend = "spend";37}
  6. Console.WriteLine("requests=" + requests + " granted=" + granted + " d…

    39    Console.WriteLine("requests=" + requests1 + " granted=" + granted1 + " denied=" + denied0 + " " + actionspend);40}
    outputrequests=1 granted=1 denied=0 spend
  1. requests ← 2, capacity ← 2, granted ← 0, denied ← 0

    4{5    static void Main()6    {7        int requests→ 2 = 2;8        int capacity→ 2 = 2;9        int granted→ 0 = 0;10        int denied→ 0 = 0;
  2. for (int i = 0; i < requests; i++)

    pass 1 of 2
    12for (int i0 = 0; i < requests2; i++)13{14    if (granted < capacity)
  3. granted ← 1

    pass 1 of 2
    13{14    if (granted0 < capacity2)15    {16        granted→ 1++;17    }
  4. for (int i = 0; i < requests; i++)

    pass 2 of 2
    12for (int i1 = 0; i < requests2; i++)13{14    if (granted < capacity)
  5. granted ← 2

    pass 2 of 2
    13{14    if (granted1 < capacity2)15    {16        granted→ 2++;17    }
  6. spare ← 0

    22}23int spare→ 0 = capacity2 - granted2;2425string action;26if (denied > 0)
  7. action ← drain

    29}30else if (spare0 == 0)31{32    action→ drain = "drain";33}
  8. Console.WriteLine("requests=" + requests + " granted=" + granted + " d…

    39    Console.WriteLine("requests=" + requests2 + " granted=" + granted2 + " denied=" + denied0 + " " + actiondrain);40}
    outputrequests=2 granted=2 denied=0 drain
  1. requests ← 4, capacity ← 2, granted ← 0, denied ← 0

    4{5    static void Main()6    {7        int requests→ 4 = 4;8        int capacity→ 2 = 2;9        int granted→ 0 = 0;10        int denied→ 0 = 0;
  2. for (int i = 0; i < requests; i++)

    pass 1 of 4
    12for (int i0 = 0; i < requests4; i++)13{14    if (granted < capacity)
    All 4 passes — pass 1 is the card above
    passicapacitygranteddenied
    1020 1
    2121 2
    320 1
    431 2
  3. granted ← 1

    pass 1 of 2
    13{14    if (granted0 < capacity2)15    {16        granted→ 1++;17    }
  4. granted ← 2

    pass 2 of 2
    13{14    if (granted1 < capacity2)15    {16        granted→ 2++;17    }
  5. denied ← 1

    pass 1 of 2
    17}18else19{20    denied→ 1++;21}
  6. denied ← 2

    pass 2 of 2
    17}18else19{20    denied→ 2++;21}
  7. spare ← 0

    22}23int spare→ 0 = capacity2 - granted2;2425string action;26if (denied > 0)
  8. action ← throttle

    25string action;26if (denied2 > 0)27{28    action→ throttle = "throttle";29}
  9. Console.WriteLine("requests=" + requests + " granted=" + granted + " d…

    39    Console.WriteLine("requests=" + requests4 + " granted=" + granted2 + " denied=" + denied2 + " " + actionthrottle);40}
    outputrequests=4 granted=2 denied=2 throttle