java-topology/defects/allegro5/unit/Allegro5SamplePoolTest.java
russell@unturf.com 9934133dcf whitepaper: 312 sites / 151 ecosystems — wave2+3 defect tables and PDF rebuild
Add 88 new defect entries to HIGH and MEDIUM tables:
  HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
        vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
        tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
        allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
        mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
        linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
        perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002

  MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
          cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
          pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
          ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
          r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
          ovs-0001, onos-0003, odl-0002, jetty-0001

PDF: 976K
2026-03-27 15:23:43 -04:00

170 lines
6.1 KiB
Java

package unit;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* Allegro5SamplePoolTest — CWE-407 allegro5-0001
*
* Models al_play_sample() free-slot acquisition:
* slow() = O(n) linear scan of auto_samples pool (current defect)
* fast() = O(1) amortized free-slot stack pop (patch)
*
* Assert: slowOps > fastOps * Nx at N=256 reserved samples.
*/
public class Allegro5SamplePoolTest {
static class SampleSlot {
boolean playing;
boolean locked;
int id;
SampleSlot() { playing = false; locked = false; id = 0; }
}
static long slowOps;
static long fastOps;
/**
* slow: O(n) linear scan — models al_play_sample defect.
* Returns slot index found, or -1 if no free slot.
*/
static int playSampleSlow(SampleSlot[] pool) {
for (int i = 0; i < pool.length; i++) {
slowOps++;
if (!pool[i].playing && !pool[i].locked) {
pool[i].playing = true;
return i;
}
}
return -1;
}
/**
* Simulate sample finishing: mark slot as not playing (called on timeout/stop).
* In the defect version, slot is simply cleared — no tracking.
*/
static void stopSampleSlow(SampleSlot[] pool, int idx) {
pool[idx].playing = false;
}
/**
* fast: O(1) amortized free-slot stack — models patched al_play_sample.
* Returns slot index found, or -1 if no free slot.
*/
static int playSampleFast(SampleSlot[] pool, Deque<Integer> freeStack) {
while (!freeStack.isEmpty()) {
fastOps++;
int idx = freeStack.pop();
if (!pool[idx].playing && !pool[idx].locked) {
pool[idx].playing = true;
return idx;
}
// Slot was reused — discard stale entry, keep scanning stack
}
return -1;
}
static void stopSampleFast(SampleSlot[] pool, Deque<Integer> freeStack, int idx) {
pool[idx].playing = false;
freeStack.push(idx); // return to free stack
}
public static void main(String[] args) {
final int N = 256; // al_reserve_samples count
final int NX = 5; // minimum required speedup factor
final int PLAYS = 2000; // play calls to measure
// Build pool — all slots initially free
SampleSlot[] pool = new SampleSlot[N];
for (int i = 0; i < N; i++) pool[i] = new SampleSlot();
// Build free stack — all slots free at start
Deque<Integer> freeStack = new ArrayDeque<>();
for (int i = N - 1; i >= 0; i--) freeStack.push(i);
slowOps = 0;
fastOps = 0;
// Simulate: play PLAYS samples, immediately stopping them.
// Worst case for linear scan: all slots occupied except the last one.
// Set all slots except the last as playing.
for (int i = 0; i < N - 1; i++) pool[i].playing = true;
// Reset free stack to only have the last slot
freeStack.clear();
freeStack.push(N - 1);
for (int p = 0; p < PLAYS; p++) {
// slow: always scans N-1 busy slots before finding free one
// (reset pool each call to keep it worst-case)
for (int i = 0; i < N - 1; i++) pool[i].playing = true;
pool[N - 1].playing = false;
int idxSlow = playSampleSlow(pool);
if (idxSlow >= 0) stopSampleSlow(pool, idxSlow);
}
long totalSlowOps = slowOps;
// Reset for fast
for (SampleSlot s : pool) { s.playing = false; s.locked = false; }
freeStack.clear();
for (int i = N - 1; i >= 0; i--) freeStack.push(i);
// Mark all but last as playing; fast stack has only last index
for (int i = 0; i < N - 1; i++) pool[i].playing = true;
freeStack.clear();
freeStack.push(N - 1);
for (int p = 0; p < PLAYS; p++) {
for (int i = 0; i < N - 1; i++) pool[i].playing = true;
pool[N - 1].playing = false;
freeStack.push(N - 1);
int idxFast = playSampleFast(pool, freeStack);
if (idxFast >= 0) stopSampleFast(pool, freeStack, idxFast);
}
long totalFastOps = fastOps;
// Correctness: both should find a free slot
for (SampleSlot s : pool) { s.playing = false; s.locked = false; }
pool[0].playing = true; // make index 0 busy
// slow should find index 1 (scan 0=busy, 1=free)
SampleSlot[] poolB = new SampleSlot[N];
for (int i = 0; i < N; i++) poolB[i] = new SampleSlot();
poolB[0].playing = true;
int slowIdx = playSampleSlow(poolB);
for (SampleSlot s : pool) { s.playing = false; }
pool[0].playing = true;
Deque<Integer> fsB = new ArrayDeque<>();
fsB.push(1); // free stack knows slot 1 is free
int fastIdx = playSampleFast(pool, fsB);
boolean correctnessOk = (slowIdx == 1 && fastIdx == 1);
boolean speedupOk = totalSlowOps > totalFastOps * NX;
System.out.printf("N=%d pool slots, PLAYS=%d%n", N, PLAYS);
System.out.printf("slow (linear) ops: %d%n", totalSlowOps);
System.out.printf("fast (stack) ops: %d%n", totalFastOps);
System.out.printf("speedup ratio: %.1fx (required >%dx)%n",
(double) totalSlowOps / totalFastOps, NX);
System.out.printf("correctness: slow found slot %d, fast found slot %d%n",
slowIdx, fastIdx);
int passed = 0, total = 2;
if (correctnessOk) {
System.out.println("1/2 PASS correctness: both found slot 1");
passed++;
} else {
System.out.printf("1/2 FAIL correctness: slow=%d fast=%d%n", slowIdx, fastIdx);
}
if (speedupOk) {
System.out.printf("2/2 PASS speedup: %d > %d * %d%n",
totalSlowOps, totalFastOps, NX);
passed++;
} else {
System.out.printf("2/2 FAIL speedup: %d not > %d * %d%n",
totalSlowOps, totalFastOps, NX);
}
System.out.printf("%d/%d PASS%n", passed, total);
if (passed < total) System.exit(1);
}
}