Concurrency Coordination Reports
Permit Pool Coordination Report
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 `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
PermitPoolCoordinationReport.scala
Replay: real traced execution (multi-file project)
import java.util.concurrent.atomic.AtomicInteger
object Main {
def main(args: Array[String]): Unit = {
val readers = 1
val slots = 3
val permits = new AtomicInteger(slots)
var held = 0
for (i <- 0 until readers) {
if (permits.getAndDecrement() > 0) {
held = held + 1
} else {
permits.getAndIncrement()
}
}
val free = permits.get()
var status = "single"
if (held == 0) {
status = "writable"
}
if (held == slots) {
status = "shared"
}
println("readers=" + readers + " held=" + held + " free=" + free + " " + status)
}
}
import java.util.concurrent.atomic.AtomicInteger
object Main {
def main(args: Array[String]): Unit = {
val readers = 0
val slots = 3
val permits = new AtomicInteger(slots)
var held = 0
for (i <- 0 until readers) {
if (permits.getAndDecrement() > 0) {
held = held + 1
} else {
permits.getAndIncrement()
}
}
val free = permits.get()
var status = "single"
if (held == 0) {
status = "writable"
}
if (held == slots) {
status = "shared"
}
println("readers=" + readers + " held=" + held + " free=" + free + " " + status)
}
}
import java.util.concurrent.atomic.AtomicInteger
object Main {
def main(args: Array[String]): Unit = {
val readers = 3
val slots = 3
val permits = new AtomicInteger(slots)
var held = 0
for (i <- 0 until readers) {
if (permits.getAndDecrement() > 0) {
held = held + 1
} else {
permits.getAndIncrement()
}
}
val free = permits.get()
var status = "single"
if (held == 0) {
status = "writable"
}
if (held == slots) {
status = "shared"
}
println("readers=" + readers + " held=" + held + " free=" + free + " " + status)
}
}
readers ← 1, slots ← 3, permits ← 3, held ← 0
3object Main {4 def main(args: Array[String]): Unit = {5 val readers→ 1 = 1 //@readers=0, 36 val slots→ 3 = 37 val permits→ 3 = new AtomicInteger(slots3)8 var held→ 0 = 0910 for (i <- 0 until readers) {for (i <- 0 until readers)
10for (i0 <- 0 until readers1) {11 if (permits.getAndDecrement() > 0) {held ← 1
10for (i <- 0 until readers) {11 if (permits2.getAndDecrement() > 0) {12 held→ 1 = held + 113 } else {14 permits.getAndIncrement()free ← 2, status ← single
18 val free→ 2 = permits2.get()1920 var status→ single = "single"21 if (held == 0) {22 status = "writable"23 }24 if (held == slots) {25 status = "shared"26 }2728 println("readers=" + readers1 + " held=" + held1 + " free=" + free2 + " " + statussingle)29 }30}outputreaders=1 held=1 free=2 single
readers ← 0, slots ← 3, permits ← 3, held ← 0, free ← 3, status ← single
3object Main {4 def main(args: Array[String]): Unit = {5 val readers→ 0 = 06 val slots→ 3 = 37 val permits→ 3 = new AtomicInteger(slots3)8 var held→ 0 = 0910 for (i <- 0 until readers) {11 if (permits.getAndDecrement() > 0) {12 held = held + 113 } else {14 permits.getAndIncrement()15 }16 }1718 val free→ 3 = permits3.get()1920 var status→ single = "single"21 if (held == 0) {22 status = "writable"status ← writable
20var status = "single"21if (held0 == 0) {22 status→ writable = "writable"23}24if (held == slots) {println("readers=" + readers + " held=" + held + " free=" + free + " "…
28 println("readers=" + readers0 + " held=" + held0 + " free=" + free3 + " " + statuswritable)29 }30}outputreaders=0 held=0 free=3 writable
readers ← 3, slots ← 3, permits ← 3, held ← 0
3object Main {4 def main(args: Array[String]): Unit = {5 val readers→ 3 = 36 val slots→ 3 = 37 val permits→ 3 = new AtomicInteger(slots3)8 var held→ 0 = 0910 for (i <- 0 until readers) {for (i <- 0 until readers)
pass 1 of 310for (i0 <- 0 until readers3) {11 if (permits.getAndDecrement() > 0) {All 3 passes — pass 1 is the card above pass i1 0 2 1 3 2 held ← 1
pass 1 of 310for (i <- 0 until readers) {11 if (permits2.getAndDecrement() > 0) {12 held→ 1 = held + 113 } else {14 permits.getAndIncrement()All 3 passes — pass 1 is the card above pass permitsheld1 2 0 → 1 2 1 1 → 2 3 0 2 → 3 free ← 0, status ← single
18val free→ 0 = permits0.get()1920var status→ single = "single"21if (held == 0) {22 status = "writable"status ← shared
23}24if (held3 == slots3) {25 status→ shared = "shared"26}println("readers=" + readers + " held=" + held + " free=" + free + " "…
28 println("readers=" + readers3 + " held=" + held3 + " free=" + free0 + " " + statusshared)29 }30}outputreaders=3 held=3 free=0 shared