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

bounded permit pool A coordination report can record how a shared pool is occupied. An `java.util.concurrent.atomic.AtomicInteger` started at the slot count models a pool of shared read permits, and a `getAndDecrement` that returns a positive prior value takes one permit without blocking; a draw past the last permit is returned with `getAndIncrement`. With no permits taken the pool is writable for an exclusive writer, with one permit taken access is single, and with every permit taken access is fully shared. The status line summarizes the mode, and `get` reports the free permits.

Permit Pool Coordination Report

readers
PermitPoolCoordinationReport.kt
Replay: real traced execution (multi-file project)
import java.util.concurrent.atomic.AtomicInteger

fun main() {
    val readers = 1
    val slots = 3
    val permits = AtomicInteger(slots)
    var held = 0

    for (i in 0 until readers) {
        if (permits.getAndDecrement() > 0) {
            held++
        } else {
            permits.getAndIncrement()
        }
    }

    val free = permits.get()

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

    println("readers=$readers held=$held free=$free $status")
}
import java.util.concurrent.atomic.AtomicInteger

fun main() {
    val readers = 0
    val slots = 3
    val permits = AtomicInteger(slots)
    var held = 0

    for (i in 0 until readers) {
        if (permits.getAndDecrement() > 0) {
            held++
        } else {
            permits.getAndIncrement()
        }
    }

    val free = permits.get()

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

    println("readers=$readers held=$held free=$free $status")
}
import java.util.concurrent.atomic.AtomicInteger

fun main() {
    val readers = 3
    val slots = 3
    val permits = AtomicInteger(slots)
    var held = 0

    for (i in 0 until readers) {
        if (permits.getAndDecrement() > 0) {
            held++
        } else {
            permits.getAndIncrement()
        }
    }

    val free = permits.get()

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

    println("readers=$readers held=$held free=$free $status")
}
  1. readers ← 1, slots ← 3, permits ← 3, held ← 0

    3fun main() {4    val readers→ 1 = 1 //@readers=0, 35    val slots→ 3 = 36    val permits→ 3 = AtomicInteger(slots3)7    var held→ 0 = 0
  2. for (i in 0 until readers)

    9for (i0 in 0 until readers1) {10    if (permits.getAndDecrement() > 0) {
  3. if (permits.getAndDecrement() > 0)

    9for (i in 0 until readers) {10    if (permits2.getAndDecrement() > 0) {11        held0++12    } else {13        permits.getAndIncrement()
  4. free ← 2, status ← single

    17    val free→ 2 = permits2.get()1819    val status→ single = if (held1 == 0) {20        "writable"21    } else if (held1 == slots3) {22        "shared"23    } else {24        "single"25    }2627    println("readers=$readers1 held=$held1 free=$free2 $statussingle")28}
    outputreaders=1 held=1 free=2 single
  1. readers ← 0, slots ← 3, permits ← 3, held ← 0, free ← 3, status ← writable

    3fun main() {4    val readers→ 0 = 05    val slots→ 3 = 36    val permits→ 3 = AtomicInteger(slots3)7    var held→ 0 = 089    for (i in 0 until readers) {10        if (permits.getAndDecrement() > 0) {11            held++12        } else {13            permits.getAndIncrement()14        }15    }1617    val free→ 3 = permits3.get()1819    val status→ writable = if (held0 == 0) {20        "writable"21    } else if (held0 == slots3) {22        "shared"23    } else {24        "single"25    }2627    println("readers=$readers0 held=$held0 free=$free3 $statuswritable")28}
    outputreaders=0 held=0 free=3 writable
  1. readers ← 3, slots ← 3, permits ← 3, held ← 0

    3fun main() {4    val readers→ 3 = 35    val slots→ 3 = 36    val permits→ 3 = AtomicInteger(slots3)7    var held→ 0 = 0
  2. for (i in 0 until readers)

    pass 1 of 3
    9for (i0 in 0 until readers3) {10    if (permits.getAndDecrement() > 0) {
    All 3 passes — pass 1 is the card above
    passi
    10
    21
    32
  3. if (permits.getAndDecrement() > 0)

    pass 1 of 3
    9for (i in 0 until readers) {10    if (permits2.getAndDecrement() > 0) {11        held0++12    } else {13        permits.getAndIncrement()
    All 3 passes — pass 1 is the card above
    passpermitsheld
    120
    211
    302
  4. free ← 0, status ← shared

    17    val free→ 0 = permits0.get()1819    val status→ shared = if (held3 == 0) {20        "writable"21    } else if (held3 == slots3) {22        "shared"23    } else {24        "single"25    }2627    println("readers=$readers3 held=$held3 free=$free0 $statusshared")28}
    outputreaders=3 held=3 free=0 shared