Files
erofs-freebsd-out-tree/tests/pre15/gates/P15-038.sh
T
2026-08-18 09:20:44 +02:00

1110 lines
40 KiB
Bash
Executable File

#!/bin/sh
set -eu
umask 022
gate_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
root=$(CDPATH= cd -- "$gate_dir/../../../.." && pwd -P)
input=$gate_dir/P15-038-input.json
base=
output=
while test "$#" -gt 0; do
case "$1" in
--base)
test "$#" -ge 2 || { printf '%s\n' '--base requires a commit' >&2; exit 2; }
base=$2
shift 2
;;
--output)
test "$#" -ge 2 || { printf '%s\n' '--output requires a directory' >&2; exit 2; }
output=$2
shift 2
;;
*)
printf 'unknown argument: %s\n' "$1" >&2
exit 2
;;
esac
done
test -n "$base" || { printf '%s\n' '--base is required' >&2; exit 2; }
test -n "$output" || { printf '%s\n' '--output is required' >&2; exit 2; }
test -f "$input" || { printf 'missing input: %s\n' "$input" >&2; exit 2; }
for tool in cc git pkg-config python3 sha256sum; do
command -v "$tool" >/dev/null 2>&1 || {
printf 'missing required host tool: %s\n' "$tool" >&2
exit 2
}
done
case "$output" in
/*) ;;
*) output=$PWD/$output ;;
esac
test ! -e "$output" || { printf 'refusing existing output: %s\n' "$output" >&2; exit 2; }
mkdir -p "$output"
PYTHONDONTWRITEBYTECODE=1 python3 -B - "$root" "$input" "$base" "$output" <<'PY'
from __future__ import annotations
import hashlib
import json
import os
from pathlib import Path
import statistics
import subprocess
import sys
import tempfile
import threading
from typing import Any
ROOT = Path(sys.argv[1])
INPUT = Path(sys.argv[2])
REQUESTED_BASE = sys.argv[3]
OUTPUT = Path(sys.argv[4])
SPEC = json.loads(INPUT.read_text(encoding="ascii"))
class GateFailure(RuntimeError):
def __init__(self, status: str, reason: str):
super().__init__(reason)
self.status = status
self.reason = reason
def sha256_bytes(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def sha256_path(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for block in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(block)
return digest.hexdigest()
def write_json(path: Path, value: Any) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="ascii")
def run(
argv: list[str], *, timeout: int, log: Path | None = None,
allowed: set[int] | None = None,
) -> subprocess.CompletedProcess[str]:
try:
completed = subprocess.run(
argv,
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
timeout=timeout,
)
except subprocess.TimeoutExpired as error:
if log is not None:
log.write_text(
"$ " + " ".join(argv) + f"\n[TIMEOUT after {timeout}s]\n",
encoding="utf-8",
)
raise GateFailure("INFRA_BLOCKED", f"timeout after {timeout}s: {' '.join(argv)}") from error
if log is not None:
log.write_text(
"$ " + " ".join(argv) + "\n" + completed.stdout +
f"\n[exit {completed.returncode}]\n",
encoding="utf-8",
)
expected = {0} if allowed is None else allowed
if completed.returncode not in expected:
raise GateFailure(
"RUNNER_FAIL",
f"command failed ({completed.returncode}): {' '.join(argv)}",
)
return completed
def git(*args: str) -> str:
return run(["git", "-C", str(ROOT), *args], timeout=30).stdout.strip()
def source_at(commit: str, relative: str) -> bytes:
completed = run(
["git", "-C", str(ROOT), "show", f"{commit}:{relative}"],
timeout=30,
)
return completed.stdout.encode("utf-8")
def verify_identity() -> tuple[str, dict[str, Any]]:
if SPEC.get("schema") != 1 or SPEC.get("candidate") != "P15-038":
raise GateFailure("INFRA_BLOCKED", "invalid P15-038 input identity")
if SPEC.get("gate") != "G05" or SPEC.get("scope") != (
"host-codec-cost-oracle-not-guest-vnode-performance"
):
raise GateFailure("INFRA_BLOCKED", "invalid G05 scope")
resolved = git("rev-parse", f"{REQUESTED_BASE}^{{commit}}")
if resolved != SPEC["required_base"]:
raise GateFailure(
"INFRA_BLOCKED",
f"P15-038 must replay {SPEC['required_base']}, got {resolved}",
)
hashes = {
relative: sha256_bytes(source_at(resolved, relative))
for relative in SPEC["source_sha256"]
}
if hashes != SPEC["source_sha256"]:
raise GateFailure("INFRA_BLOCKED", "frozen B32/source identity changed")
package_names = {
"liblz4": "liblz4",
"liblzma": "liblzma",
"zlib": "zlib",
"libzstd": "libzstd",
}
versions = {
name: run(["pkg-config", "--modversion", package], timeout=30).stdout.strip()
for name, package in package_names.items()
}
if versions != SPEC["libraries"]:
raise GateFailure(
"INFRA_BLOCKED",
f"host codec library identity changed: {versions!r}",
)
zdata = source_at(resolved, "repo-pre-15/src/zdata.c").decode("utf-8")
internal = source_at(resolved, "repo-pre-15/src/internal.h").decode("utf-8")
required_tokens = (
"cache->nid == vi->nid",
"cache->decoded_size == decoded_size",
"cache->map.m_pa == map->m_pa",
"cache->map.m_la == map->m_la",
"cache->map.m_plen == map->m_plen",
"cache->map.m_llen == map->m_llen",
"cache->map.m_deviceid == map->m_deviceid",
"cache->map.m_algorithmformat == map->m_algorithmformat",
"cache->map.m_flags == map->m_flags",
"cache->state == EROFS_ZCACHE_INFLIGHT || cache->waiters != 0",
"cache->error = error",
"cache->closing = true",
"Z_EROFS_CACHE_BYPASS",
)
missing = [token for token in required_tokens if token not in zdata]
if missing:
raise GateFailure("STOP", f"B32 key/inflight/failure contract is not closed: {missing!r}")
if zdata.count("map->m_algorithmformat == Z_EROFS_COMPRESSION_LZMA") != 1:
raise GateFailure("STOP", "frozen admission is not exactly LZMA-only")
for token in ("EROFS_ZCACHE_EMPTY", "EROFS_ZCACHE_INFLIGHT", "EROFS_ZCACHE_READY", "EROFS_ZCACHE_FAILED"):
if token not in internal:
raise GateFailure("STOP", f"B32 state is missing: {token}")
return resolved, {"libraries": versions, "source_sha256": hashes}
class Budget:
def __init__(self, limit: int):
self.limit = limit
self.used = 0
self.peak = 0
self.lock = threading.Lock()
def reserve(self, amount: int) -> bool:
with self.lock:
if amount > self.limit - self.used:
return False
self.used += amount
self.peak = max(self.peak, self.used)
return True
def release(self, amount: int) -> None:
with self.lock:
if amount > self.used:
raise GateFailure("STOP", "global budget accounting underflow")
self.used -= amount
class Cache:
def __init__(self, budget: Budget, local_limit: int, minimum_work: int, enabled: bool = True):
self.budget = budget
self.local_limit = local_limit
self.minimum_work = minimum_work
self.enabled = enabled
self.condition = threading.Condition()
self.state = "EMPTY"
self.key: tuple[int, ...] | None = None
self.data: bytes | None = None
self.error = 0
self.waiters = 0
self.charged = 0
self.peak = 0
self.closing = False
self.owners = 0
self.evictions = 0
self.reclaims = 0
self.bypasses = 0
def eligible(self, decoded_size: int, decode_work: int) -> bool:
return (
self.enabled
and decoded_size <= self.local_limit
and decode_work >= self.minimum_work
)
def _release_locked(self) -> None:
if self.charged:
self.budget.release(self.charged)
self.charged = 0
self.data = None
def claim(self, key: tuple[int, ...], decoded_size: int, decode_work: int) -> tuple[str, bytes | int | None]:
if not self.eligible(decoded_size, decode_work):
self.bypasses += 1
return "BYPASS", None
with self.condition:
if self.closing:
self.bypasses += 1
return "BYPASS", None
if self.state != "EMPTY" and self.key == key:
if self.state == "READY":
if self.data is None:
raise GateFailure("STOP", "READY cache has no data")
return "HIT", self.data
if self.state == "INFLIGHT":
self.waiters += 1
self.condition.notify_all()
while self.state == "INFLIGHT":
self.condition.wait()
if self.key != key:
raise GateFailure("STOP", "waiter generation key changed")
if self.state == "READY":
result: tuple[str, bytes | int | None] = ("HIT", self.data)
elif self.state == "FAILED" and self.error > 0:
result = ("ERROR", self.error)
else:
raise GateFailure("STOP", "waiter received untyped publication")
self.waiters -= 1
if self.state == "FAILED" and self.waiters == 0:
self.error = 0
self.state = "EMPTY"
if self.waiters == 0:
self.condition.notify_all()
return result
if self.state == "FAILED":
if self.waiters:
self.bypasses += 1
return "BYPASS", None
self.error = 0
self.state = "EMPTY"
if self.state == "INFLIGHT" or self.waiters:
self.bypasses += 1
return "BYPASS", None
if self.state == "READY":
self._release_locked()
self.evictions += 1
self.state = "EMPTY"
if not self.budget.reserve(decoded_size):
self.bypasses += 1
return "BYPASS", None
self.charged = decoded_size
self.peak = max(self.peak, self.charged)
self.key = key
self.error = 0
self.state = "INFLIGHT"
self.owners += 1
return "OWNER", None
def wait_for_waiters(self, expected: int) -> None:
with self.condition:
if not self.condition.wait_for(lambda: self.waiters == expected, timeout=10):
raise GateFailure("STOP", "same-key waiters did not register")
def complete(self, key: tuple[int, ...], data: bytes | None, error: int) -> None:
if (error == 0) != (data is not None):
raise GateFailure("STOP", "owner completion is untyped")
with self.condition:
if self.state != "INFLIGHT" or self.key != key:
raise GateFailure("STOP", "owner lost inflight key")
if error == 0:
assert data is not None
if len(data) != self.charged:
raise GateFailure("STOP", "published bytes do not match reservation")
self.data = data
self.state = "READY"
else:
if error < 1:
raise GateFailure("STOP", "published errno is not positive")
self._release_locked()
self.error = error
self.state = "FAILED"
if self.waiters == 0:
self.error = 0
self.state = "EMPTY"
self.condition.notify_all()
def reclaim(self) -> str:
with self.condition:
if self.state == "INFLIGHT" or self.waiters:
return "BUSY"
if self.state == "READY":
self._release_locked()
self.state = "EMPTY"
self.reclaims += 1
return "RECLAIMED"
return "EMPTY"
def fini(self, closing: threading.Event | None = None) -> None:
with self.condition:
self.closing = True
if closing is not None:
closing.set()
while self.state == "INFLIGHT" or self.waiters:
self.condition.wait()
self._release_locked()
self.error = 0
self.state = "EMPTY"
def payload(key: tuple[int, ...], size: int) -> bytes:
seed = sum((index + 1) * value for index, value in enumerate(key)) & 0xFF
return bytes(((seed + index * 29) & 0xFF) for index in range(size))
def run_wave(cache: Cache, key: tuple[int, ...], size: int, error: int) -> dict[str, Any]:
workers = 16
barrier = threading.Barrier(workers)
results: list[tuple[str, bytes | int | None] | None] = [None] * workers
expected = payload(key, size)
def worker(index: int) -> None:
barrier.wait(timeout=10)
result = cache.claim(key, size, size * 2)
if result[0] == "OWNER":
cache.wait_for_waiters(workers - 1)
cache.complete(key, None if error else expected, error)
results[index] = ("ERROR", error) if error else ("HIT", expected)
else:
results[index] = result
threads = [threading.Thread(target=worker, args=(index,)) for index in range(workers)]
for thread in threads:
thread.start()
for thread in threads:
thread.join(timeout=15)
if any(thread.is_alive() for thread in threads):
raise GateFailure("STOP", "state-model worker did not terminate")
if error:
if any(result != ("ERROR", error) for result in results):
raise GateFailure("STOP", "same-key waiters did not receive one typed failure")
elif any(result != ("HIT", expected) for result in results):
raise GateFailure("STOP", "same-key waiters did not receive identical bytes")
return {"error": error, "owners": 1, "waiters": workers - 1}
def run_state_model() -> dict[str, Any]:
config = SPEC["budget"]
extent = SPEC["benchmark"]["extent_bytes"]
global_budget = Budget(config["global_bytes"])
cache = Cache(
global_budget,
config["per_mount_bytes"],
config["minimum_decode_work_bytes"],
)
key = (42, extent, 4096, 0, 8192, extent, 0, 1, 1)
success = run_wave(cache, key, extent, 0)
failure_key = (43, extent, 8192, 0, 8192, extent, 0, 2, 1)
failure = run_wave(cache, failure_key, extent, 97)
retry = cache.claim(failure_key, extent, extent * 2)
if retry[0] != "OWNER":
raise GateFailure("STOP", "typed failure is not retryable")
retry_payload = payload(failure_key, extent)
cache.complete(failure_key, retry_payload, 0)
before = sha256_bytes(retry_payload)
changed = list(failure_key)
changed[2] += 4096
changed_key = tuple(changed)
result = cache.claim(changed_key, extent, extent * 2)
if result[0] != "OWNER":
raise GateFailure("STOP", "ready key eviction did not create an owner")
cache.complete(changed_key, payload(changed_key, extent), 0)
result = cache.claim(failure_key, extent, extent * 2)
if result[0] != "OWNER":
raise GateFailure("STOP", "evicted key reuse did not create a fresh owner")
after_payload = payload(failure_key, extent)
cache.complete(failure_key, after_payload, 0)
after = sha256_bytes(after_payload)
if before != after:
raise GateFailure("STOP", "eviction changed decoded bytes")
inflight_key = (44, extent, 12288, 0, 8192, extent, 0, 3, 1)
if cache.claim(inflight_key, extent, extent * 2)[0] != "OWNER":
raise GateFailure("STOP", "reclaim setup did not create owner")
if cache.reclaim() != "BUSY":
raise GateFailure("STOP", "reclaim did not refuse inflight state")
fallback_key = (45, extent, 16384, 0, 8192, extent, 0, 0, 1)
if cache.claim(fallback_key, extent, extent * 2)[0] != "BYPASS":
raise GateFailure("STOP", "different-key inflight miss did not bypass")
fallback_hash = sha256_bytes(payload(fallback_key, extent))
cache.complete(inflight_key, payload(inflight_key, extent), 0)
if cache.reclaim() != "RECLAIMED" or global_budget.used != 0:
raise GateFailure("STOP", "ready reclaim did not release budget")
first = Cache(global_budget, extent, config["minimum_decode_work_bytes"])
second = Cache(global_budget, extent, config["minimum_decode_work_bytes"])
if first.claim(key, extent, extent * 2)[0] != "OWNER":
raise GateFailure("STOP", "global budget setup failed")
first.complete(key, payload(key, extent), 0)
if second.claim(changed_key, extent, extent * 2)[0] != "OWNER":
raise GateFailure("STOP", "global budget should fit two reservations")
second.complete(changed_key, payload(changed_key, extent), 0)
third = Cache(global_budget, extent, config["minimum_decode_work_bytes"])
if third.claim(fallback_key, extent, extent * 2)[0] != "BYPASS":
raise GateFailure("STOP", "global exhaustion did not use no-cache fallback")
exhausted_hash = sha256_bytes(payload(fallback_key, extent))
if first.reclaim() != "RECLAIMED":
raise GateFailure("STOP", "global reclaim did not free a reservation")
if third.claim(fallback_key, extent, extent * 2)[0] != "OWNER":
raise GateFailure("STOP", "reclaimed global budget was not reusable")
third.complete(fallback_key, payload(fallback_key, extent), 0)
second.fini()
third.fini()
shutdown = Cache(global_budget, extent, config["minimum_decode_work_bytes"])
shutdown_key = (46, extent, 20480, 0, 8192, extent, 0, 1, 1)
if shutdown.claim(shutdown_key, extent, extent * 2)[0] != "OWNER":
raise GateFailure("STOP", "unmount setup did not create owner")
closing = threading.Event()
finished = threading.Event()
def finish_cache() -> None:
shutdown.fini(closing)
finished.set()
thread = threading.Thread(target=finish_cache)
thread.start()
if not closing.wait(timeout=10) or finished.is_set():
raise GateFailure("STOP", "unmount did not wait for inflight owner")
if shutdown.claim(changed_key, extent, extent * 2)[0] != "BYPASS":
raise GateFailure("STOP", "closing cache accepted a new owner")
shutdown.complete(shutdown_key, payload(shutdown_key, extent), 0)
thread.join(timeout=10)
if thread.is_alive() or not finished.is_set() or global_budget.used != 0:
raise GateFailure("STOP", "unmount drain did not close cleanly")
disabled = Cache(global_budget, extent, config["minimum_decode_work_bytes"], enabled=False)
if disabled.claim(key, extent, extent * 2)[0] != "BYPASS":
raise GateFailure("STOP", "disabled policy did not bypass")
low_work = Cache(global_budget, extent, config["minimum_decode_work_bytes"])
if low_work.claim(key, extent, config["minimum_decode_work_bytes"] - 1)[0] != "BYPASS":
raise GateFailure("STOP", "low-cost request did not bypass")
oversized = Cache(global_budget, extent // 2, config["minimum_decode_work_bytes"])
if oversized.claim(key, extent, extent * 2)[0] != "BYPASS":
raise GateFailure("STOP", "oversized request did not bypass")
no_cache_hash = sha256_bytes(payload(key, extent))
if global_budget.peak > global_budget.limit or cache.peak > cache.local_limit:
raise GateFailure("STOP", "state model exceeded hard budget")
return {
"budget": {
"global_limit": global_budget.limit,
"global_peak": global_budget.peak,
"global_remaining": global_budget.used,
"mount_limit": cache.local_limit,
"mount_peak": cache.peak,
},
"correctness": {
"eviction_sha256_before": before,
"eviction_sha256_after": after,
"fallback_sha256": fallback_hash,
"global_exhaustion_fallback_sha256": exhausted_hash,
"no_cache_sha256": no_cache_hash,
},
"coverage": [
"owner-waiter-success",
"typed-failure-retry",
"exact-key-reuse",
"ready-eviction",
"inflight-reclaim-busy",
"ready-reclaim",
"global-exhaustion-fallback",
"unmount-drain",
"disabled-policy",
"low-work-bypass",
"oversize-bypass",
],
"failure_wave": failure,
"lock_order": SPEC["lock_order"],
"status": "PASS",
"success_wave": success,
}
BENCH_SOURCE = r'''
#define _POSIX_C_SOURCE 200809L
#include <inttypes.h>
#include <limits.h>
#include <lz4.h>
#include <lzma.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <zlib.h>
#include <zstd.h>
enum codec_id { CODEC_LZ4, CODEC_LZMA, CODEC_DEFLATE, CODEC_ZSTD, CODEC_COUNT };
struct fixture {
enum codec_id id;
const char *name;
unsigned char *compressed;
size_t compressed_size;
};
static void
fail(const char *message)
{
fprintf(stderr, "P15-038 codec oracle failure: %s\n", message);
exit(10);
}
static uint64_t
now_ns(void)
{
struct timespec time;
if (clock_gettime(CLOCK_MONOTONIC, &time) != 0)
fail("clock_gettime");
return ((uint64_t)time.tv_sec * UINT64_C(1000000000) + (uint64_t)time.tv_nsec);
}
static uint32_t
xorshift32(uint32_t *state)
{
uint32_t value = *state;
value ^= value << 13;
value ^= value >> 17;
value ^= value << 5;
*state = value;
return (value);
}
static uint64_t
hash_update(uint64_t hash, const unsigned char *data, size_t size)
{
size_t index;
for (index = 0; index < size; ++index) {
hash ^= data[index];
hash *= UINT64_C(1099511628211);
}
return (hash);
}
static void
write_file(const char *path, const void *data, size_t size)
{
FILE *stream = fopen(path, "wb");
if (stream == NULL || fwrite(data, 1, size, stream) != size || fclose(stream) != 0)
fail("write fixture artifact");
}
static void
make_payload(unsigned char *payload, size_t size, uint32_t seed)
{
unsigned char block[4096];
size_t index;
for (index = 0; index < sizeof(block); ++index)
block[index] = (unsigned char)xorshift32(&seed);
for (index = 0; index < size; ++index)
payload[index] = block[index % sizeof(block)];
}
static struct fixture
compress_fixture(enum codec_id id, const char *name, const unsigned char *payload, size_t size)
{
struct fixture fixture = { .id = id, .name = name };
size_t capacity, output_position;
uLongf zlib_size;
int amount;
switch (id) {
case CODEC_LZ4:
capacity = (size_t)LZ4_compressBound((int)size);
fixture.compressed = malloc(capacity);
amount = LZ4_compress_default((const char *)payload,
(char *)fixture.compressed, (int)size, (int)capacity);
if (amount <= 0)
fail("LZ4 compression");
fixture.compressed_size = (size_t)amount;
break;
case CODEC_LZMA:
capacity = lzma_stream_buffer_bound(size);
fixture.compressed = malloc(capacity);
output_position = 0;
if (lzma_easy_buffer_encode(6, LZMA_CHECK_NONE, NULL, payload, size,
fixture.compressed, &output_position, capacity) != LZMA_OK)
fail("LZMA compression");
fixture.compressed_size = output_position;
break;
case CODEC_DEFLATE:
capacity = (size_t)compressBound((uLong)size);
fixture.compressed = malloc(capacity);
zlib_size = (uLongf)capacity;
if (compress2(fixture.compressed, &zlib_size, payload, (uLong)size, 6) != Z_OK)
fail("Deflate compression");
fixture.compressed_size = (size_t)zlib_size;
break;
case CODEC_ZSTD:
capacity = ZSTD_compressBound(size);
fixture.compressed = malloc(capacity);
fixture.compressed_size = ZSTD_compress(
fixture.compressed, capacity, payload, size, 3);
if (ZSTD_isError(fixture.compressed_size))
fail("Zstd compression");
break;
default:
fail("unknown compression codec");
}
if (fixture.compressed == NULL)
fail("compressed allocation");
return (fixture);
}
static void
decode(const struct fixture *fixture, unsigned char *output, size_t output_size)
{
size_t input_position, output_position, amount;
uint64_t memory_limit;
uLongf zlib_size;
int decoded;
switch (fixture->id) {
case CODEC_LZ4:
decoded = LZ4_decompress_safe((const char *)fixture->compressed,
(char *)output, (int)fixture->compressed_size, (int)output_size);
if (decoded != (int)output_size)
fail("LZ4 decode");
break;
case CODEC_LZMA:
memory_limit = UINT64_MAX;
input_position = 0;
output_position = 0;
if (lzma_stream_buffer_decode(&memory_limit, 0, NULL,
fixture->compressed, &input_position, fixture->compressed_size,
output, &output_position, output_size) != LZMA_OK ||
input_position != fixture->compressed_size || output_position != output_size)
fail("LZMA decode");
break;
case CODEC_DEFLATE:
zlib_size = (uLongf)output_size;
if (uncompress(output, &zlib_size, fixture->compressed,
(uLong)fixture->compressed_size) != Z_OK || zlib_size != output_size)
fail("Deflate decode");
break;
case CODEC_ZSTD:
amount = ZSTD_decompress(output, output_size,
fixture->compressed, fixture->compressed_size);
if (ZSTD_isError(amount) || amount != output_size)
fail("Zstd decode");
break;
default:
fail("unknown decompression codec");
}
}
static uint64_t
workload(const struct fixture *fixture, const unsigned char *payload,
size_t extent_size, size_t read_size, const size_t *offsets, size_t reads,
int neutral, size_t budget, size_t minimum_work, size_t *peak, uint64_t *hashp)
{
unsigned char *cached = NULL, *decoded, *slice;
uint64_t begin, end, hash = UINT64_C(1469598103934665603);
size_t index;
int admit;
admit = (fixture->id == CODEC_LZMA || neutral) && extent_size <= budget &&
fixture->compressed_size + extent_size >= minimum_work;
slice = malloc(read_size);
if (slice == NULL)
fail("slice allocation");
*peak = 0;
begin = now_ns();
for (index = 0; index < reads; ++index) {
if (cached == NULL) {
decoded = malloc(extent_size);
if (decoded == NULL)
fail("decode allocation");
decode(fixture, decoded, extent_size);
memcpy(slice, decoded + offsets[index], read_size);
if (admit) {
cached = decoded;
if (extent_size > *peak)
*peak = extent_size;
} else {
free(decoded);
}
} else {
memcpy(slice, cached + offsets[index], read_size);
}
if (memcmp(slice, payload + offsets[index], read_size) != 0)
fail("random read bytes differ");
hash = hash_update(hash, slice, read_size);
}
end = now_ns();
free(cached);
free(slice);
*hashp = hash;
return (end - begin);
}
static void
eviction_oracle(const struct fixture *first, const struct fixture *second,
size_t extent_size, const char *directory)
{
unsigned char *cache = malloc(extent_size);
char path[PATH_MAX];
if (cache == NULL)
fail("eviction allocation");
decode(first, cache, extent_size);
snprintf(path, sizeof(path), "%s/eviction-before.bin", directory);
write_file(path, cache, extent_size);
free(cache);
cache = malloc(extent_size);
if (cache == NULL)
fail("second eviction allocation");
decode(second, cache, extent_size);
free(cache);
cache = malloc(extent_size);
if (cache == NULL)
fail("reused eviction allocation");
decode(first, cache, extent_size);
snprintf(path, sizeof(path), "%s/eviction-after.bin", directory);
write_file(path, cache, extent_size);
free(cache);
}
int
main(int argc, char **argv)
{
static const char *names[CODEC_COUNT] = { "lz4", "lzma", "deflate", "zstd" };
struct fixture fixtures[CODEC_COUNT];
unsigned char *payload, *verification;
size_t *offsets;
size_t extent_size, read_size, reads, samples, budget, minimum_work;
size_t codec, sample, peak_current, peak_candidate;
uint32_t seed;
uint64_t current_ns, candidate_ns, current_hash, candidate_hash;
char path[PATH_MAX];
if (argc != 9)
fail("usage");
extent_size = (size_t)strtoull(argv[1], NULL, 10);
read_size = (size_t)strtoull(argv[2], NULL, 10);
reads = (size_t)strtoull(argv[3], NULL, 10);
samples = (size_t)strtoull(argv[4], NULL, 10);
budget = (size_t)strtoull(argv[5], NULL, 10);
minimum_work = (size_t)strtoull(argv[6], NULL, 10);
seed = (uint32_t)strtoul(argv[7], NULL, 10);
if (extent_size == 0 || extent_size > INT_MAX || read_size == 0 ||
read_size > extent_size || reads == 0 || samples != 5)
fail("invalid fixed workload");
payload = malloc(extent_size);
verification = malloc(extent_size);
offsets = malloc(reads * sizeof(*offsets));
if (payload == NULL || verification == NULL || offsets == NULL)
fail("workload allocation");
make_payload(payload, extent_size, seed);
for (codec = 0; codec < CODEC_COUNT; ++codec) {
fixtures[codec] = compress_fixture((enum codec_id)codec, names[codec],
payload, extent_size);
decode(&fixtures[codec], verification, extent_size);
if (memcmp(payload, verification, extent_size) != 0)
fail("full decode verification");
snprintf(path, sizeof(path), "%s/%s.compressed", argv[8], names[codec]);
write_file(path, fixtures[codec].compressed, fixtures[codec].compressed_size);
}
snprintf(path, sizeof(path), "%s/payload.bin", argv[8]);
write_file(path, payload, extent_size);
for (sample = 0; sample < reads; ++sample)
offsets[sample] = (size_t)xorshift32(&seed) % (extent_size - read_size + 1);
printf("{\"schema\":1,\"scope\":\"host-codec-cost-only\",\"samples\":%zu,\"reads_per_sample\":%zu,\"codecs\":[", samples, reads);
for (codec = 0; codec < CODEC_COUNT; ++codec) {
if (codec != 0)
printf(",");
printf("{\"codec\":\"%s\",\"compressed_bytes\":%zu,\"current_ns\":[",
fixtures[codec].name, fixtures[codec].compressed_size);
for (sample = 0; sample < samples; ++sample) {
if ((sample & 1) == 0) {
current_ns = workload(&fixtures[codec], payload, extent_size,
read_size, offsets, reads, 0, budget, minimum_work,
&peak_current, &current_hash);
candidate_ns = workload(&fixtures[codec], payload, extent_size,
read_size, offsets, reads, 1, budget, minimum_work,
&peak_candidate, &candidate_hash);
} else {
candidate_ns = workload(&fixtures[codec], payload, extent_size,
read_size, offsets, reads, 1, budget, minimum_work,
&peak_candidate, &candidate_hash);
current_ns = workload(&fixtures[codec], payload, extent_size,
read_size, offsets, reads, 0, budget, minimum_work,
&peak_current, &current_hash);
}
if (sample != 0)
printf(",");
printf("%" PRIu64, current_ns);
if (current_hash != candidate_hash || peak_candidate > budget)
fail("sample hash or budget mismatch");
/* Keep paired values for the second fixed-size arrays. */
snprintf(path, sizeof(path), "%s/sample-%zu-%zu.tmp", argv[8], codec, sample);
FILE *record = fopen(path, "w");
if (record == NULL || fprintf(record, "%" PRIu64 " %zu %zu %" PRIu64 "\n",
candidate_ns, peak_current, peak_candidate, current_hash) < 0 || fclose(record) != 0)
fail("sample record");
}
printf("],\"candidate_ns\":[");
for (sample = 0; sample < samples; ++sample) {
uint64_t saved_candidate, saved_hash;
FILE *record;
snprintf(path, sizeof(path), "%s/sample-%zu-%zu.tmp", argv[8], codec, sample);
record = fopen(path, "r");
if (record == NULL || fscanf(record, "%" SCNu64 " %zu %zu %" SCNu64,
&saved_candidate, &peak_current, &peak_candidate, &saved_hash) != 4 || fclose(record) != 0)
fail("read sample record");
if (sample != 0)
printf(",");
printf("%" PRIu64, saved_candidate);
}
printf("],\"current_peak_bytes\":[");
for (sample = 0; sample < samples; ++sample) {
uint64_t saved_candidate, saved_hash;
FILE *record;
snprintf(path, sizeof(path), "%s/sample-%zu-%zu.tmp", argv[8], codec, sample);
record = fopen(path, "r");
if (record == NULL || fscanf(record, "%" SCNu64 " %zu %zu %" SCNu64,
&saved_candidate, &peak_current, &peak_candidate, &saved_hash) != 4 || fclose(record) != 0)
fail("read current peak");
if (sample != 0)
printf(",");
printf("%zu", peak_current);
}
printf("],\"candidate_peak_bytes\":[");
for (sample = 0; sample < samples; ++sample) {
uint64_t saved_candidate, saved_hash;
FILE *record;
snprintf(path, sizeof(path), "%s/sample-%zu-%zu.tmp", argv[8], codec, sample);
record = fopen(path, "r");
if (record == NULL || fscanf(record, "%" SCNu64 " %zu %zu %" SCNu64,
&saved_candidate, &peak_current, &peak_candidate, &saved_hash) != 4 || fclose(record) != 0)
fail("read candidate peak");
if (sample != 0)
printf(",");
printf("%zu", peak_candidate);
remove(path);
}
printf("]}");
}
eviction_oracle(&fixtures[CODEC_DEFLATE], &fixtures[CODEC_ZSTD], extent_size, argv[8]);
printf("],\"status\":\"PASS\"}\n");
for (codec = 0; codec < CODEC_COUNT; ++codec)
free(fixtures[codec].compressed);
free(offsets);
free(verification);
free(payload);
return (0);
}
'''
def run_benchmark() -> tuple[dict[str, Any], dict[str, str]]:
artifacts = OUTPUT / "artifacts"
artifacts.mkdir()
source = artifacts / "P15-038-codec-bench.c"
source.write_text(BENCH_SOURCE.lstrip(), encoding="ascii")
config = SPEC["benchmark"]
budget = SPEC["budget"]
with tempfile.TemporaryDirectory(prefix="p15-038-") as temporary:
temp = Path(temporary)
binary = temp / "P15-038-codec-bench"
fixture_dir = temp / "fixtures"
fixture_dir.mkdir()
flags = run(
["pkg-config", "--cflags", "--libs", "liblz4", "liblzma", "zlib", "libzstd"],
timeout=30,
).stdout.split()
run(
["cc", "-std=c11", "-O2", "-Wall", "-Wextra", "-Werror", str(source), "-o", str(binary), *flags],
timeout=60,
log=artifacts / "compile.log",
)
completed = run(
[
str(binary),
str(config["extent_bytes"]),
str(config["read_bytes"]),
str(config["random_reads_per_sample"]),
str(config["samples"]),
str(budget["per_mount_bytes"]),
str(budget["minimum_decode_work_bytes"]),
str(config["seed"]),
str(fixture_dir),
],
timeout=240,
log=artifacts / "benchmark.log",
allowed={0, 10},
)
if completed.returncode != 0:
raise GateFailure("STOP", "real codec benchmark or correctness oracle failed")
try:
report = json.loads(completed.stdout)
except json.JSONDecodeError as error:
raise GateFailure("RUNNER_FAIL", f"invalid benchmark JSON: {error}") from error
hashes = {
path.name: sha256_path(path)
for path in sorted(fixture_dir.iterdir())
if path.is_file()
}
before = hashes.pop("eviction-before.bin")
after = hashes.pop("eviction-after.bin")
if before != after:
raise GateFailure("STOP", "real codec eviction changed decoded SHA-256")
hashes["eviction-before-after.sha256"] = before
write_json(artifacts / "fixture-hashes.json", hashes)
return report, hashes
def evaluate(report: dict[str, Any], state: dict[str, Any]) -> dict[str, Any]:
config = SPEC["benchmark"]
budget = SPEC["budget"]["per_mount_bytes"]
if report.get("status") != "PASS" or report.get("samples") != config["samples"]:
raise GateFailure("STOP", "benchmark did not return exactly five complete samples")
if report.get("reads_per_sample") != config["random_reads_per_sample"]:
raise GateFailure("STOP", "benchmark logical workload changed")
summaries = []
improved = 0
for codec in report.get("codecs", []):
current = codec.get("current_ns", [])
candidate = codec.get("candidate_ns", [])
peaks = codec.get("candidate_peak_bytes", [])
if len(current) != 5 or len(candidate) != 5 or len(peaks) != 5:
raise GateFailure("STOP", f"{codec.get('codec')} has a missing sample")
if any(value <= 0 for value in current + candidate):
raise GateFailure("STOP", f"{codec['codec']} has a non-positive latency")
if any(value > budget for value in peaks):
raise GateFailure("STOP", f"{codec['codec']} exceeded the hard budget")
current_median = statistics.median(current)
candidate_median = statistics.median(candidate)
improvement = (current_median - candidate_median) * 100.0 / current_median
passed = improvement >= config["minimum_latency_improvement_percent"]
if passed:
improved += 1
summaries.append(
{
"candidate_median_ns": candidate_median,
"candidate_ns": candidate,
"candidate_peak_bytes": peaks,
"codec": codec["codec"],
"compressed_bytes": codec["compressed_bytes"],
"current_median_ns": current_median,
"current_ns": current,
"improvement_percent": improvement,
"threshold_pass": passed,
}
)
if len(summaries) != 4:
raise GateFailure("STOP", "the four-codec benchmark is incomplete")
if improved < config["minimum_improved_codecs"]:
raise GateFailure("STOP", f"only {improved} codecs met the 10 percent latency threshold")
if state.get("status") != "PASS" or state["budget"]["global_remaining"] != 0:
raise GateFailure("STOP", "cache lifecycle state model did not close")
return {
"codecs_meeting_threshold": improved,
"minimum_codecs": config["minimum_improved_codecs"],
"minimum_improvement_percent": config["minimum_latency_improvement_percent"],
"samples_included_per_variant": 5,
"summaries": summaries,
}
exit_code = 2
try:
resolved, identity = verify_identity()
write_json(OUTPUT / "identity.json", {"base": resolved, **identity})
state = run_state_model()
write_json(OUTPUT / "state-model.json", state)
benchmark, fixture_hashes = run_benchmark()
write_json(OUTPUT / "benchmark.json", benchmark)
benefit = evaluate(benchmark, state)
write_json(OUTPUT / "benefit.json", benefit)
result = {
"b33": "AUTHORIZED",
"candidate": "P15-038",
"decision": "GO",
"eviction_sha256": fixture_hashes["eviction-before-after.sha256"],
"full_feature_suite": "NOT_RUN",
"gate": "G05",
"qemu": "NOT_RUN",
"reason": (
f"state model PASS; {benefit['codecs_meeting_threshold']}/4 codecs meet "
"the fixed five-sample >=10% host codec latency threshold; hard budgets and "
"eviction hashes pass"
),
"scope": SPEC["scope"],
"source_modified": False,
"status": "GO",
}
exit_code = 0
except GateFailure as error:
result = {
"b33": "STOP-NO-SOURCE" if error.status == "STOP" else "NOT_RUN",
"candidate": "P15-038",
"decision": "STOP" if error.status == "STOP" else error.status,
"full_feature_suite": "NOT_RUN",
"gate": "G05",
"qemu": "NOT_RUN",
"reason": error.reason,
"scope": SPEC.get("scope"),
"source_modified": False,
"status": error.status,
}
exit_code = 1 if error.status == "STOP" else 2
except Exception as error:
result = {
"b33": "NOT_RUN",
"candidate": "P15-038",
"decision": "RUNNER_FAIL",
"full_feature_suite": "NOT_RUN",
"gate": "G05",
"qemu": "NOT_RUN",
"reason": f"unhandled gate error: {type(error).__name__}: {error}",
"scope": SPEC.get("scope"),
"source_modified": False,
"status": "RUNNER_FAIL",
}
exit_code = 2
write_json(OUTPUT / "result.json", result)
write_json(
OUTPUT / "cleanup.json",
{
"binary_remaining": False,
"owned_processes_started": 0,
"owned_qemu_started": False,
"owned_temp_remaining": [],
"protected_pid_touched": False,
"protected_port_touched": False,
"source_modified": False,
"status": "PASS",
},
)
lines = []
for path in sorted(OUTPUT.rglob("*")):
if path.is_file() and path.name != "SHA256SUMS":
lines.append(f"{sha256_path(path)} {path.relative_to(OUTPUT)}")
(OUTPUT / "SHA256SUMS").write_text("\n".join(lines) + "\n", encoding="ascii")
print(json.dumps(result, sort_keys=True))
raise SystemExit(exit_code)
PY