mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
vk_exec_held_ready runs without sub_lock (vk_backend.c held_resume and submit_sync). It followed evq[s].head into the continuation and read the wait in the continuation's private copy of the recording. Meanwhile another submitting thread, inside vk_sync_submit, could run evo_resume and cont_free that continuation. A reused block then gave vk_exec_event_met an event address pointing anywhere, so the unlocked reader could fault, not only read a stale state. Now the holder of sub_lock publishes what the decision needs into a per-queue sequence lock (runtime/vk_evo_peek.h), wherever a queue's first continuation, or that continuation's wait or stop, changes: in cont_push when the pushed one becomes the first, in evo_resume after the head moves on, and after cont_walk stops at another wait. The copy holds the wait by value. vk_exec_held_ready decides from a copy taken from one publish. It never waits for the writer: after three tries that overlap a publish it answers "not ready", which is what losing that race answered before. This fixes F-1-06 without the front-end lock. F-2-01's lock is still the answer for the other unlocked front-end state. Not reproduced before the change. Checks that passed: the new tests/evo_peek_check (one writer publishing 1,000,000 times while three readers copy: no copy mixed two publishes, and the decision cont_ready makes, with a stand-in for vk_exec_event_met; with the sequence check removed it reports over a million mixed copies), pass_cc_check on every runtime file (a header was added), no new -Wall -Wextra warnings in vk_exec.c, target_frames_check, oq_hold_check, sync_hw_check, mesh_path_check and gpa_check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
"""Build and run tests/evo_peek_check.c: runtime/vk_evo_peek.h, the copy of each event-ordered queue's first held wait
|
|
that vk_exec.c vk_exec_held_ready reads without the submission lock, and the decision it makes from that copy. One
|
|
writer republishes while three readers copy: no copy may mix two publishes, and no reader waits for the writer.
|
|
|
|
No GPU, no game files, any Python.
|
|
|
|
Usage: evo_peek_check.py
|
|
"""
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
MSYS_BIN = Path(r'C:\msys64\ucrt64\bin')
|
|
|
|
|
|
def compiler():
|
|
"""$CC, else MSYS2 UCRT64's clang, else clang on PATH (as tests/diff/common.py picks it, without its Unicorn)."""
|
|
if os.environ.get('CC'):
|
|
return os.environ['CC']
|
|
if os.name == 'nt' and (MSYS_BIN / 'clang.exe').exists():
|
|
return str(MSYS_BIN / 'clang.exe')
|
|
return shutil.which('clang') or 'clang'
|
|
|
|
|
|
def main():
|
|
work = ROOT / 'build' / 'test' / 'evo_peek'
|
|
work.mkdir(parents=True, exist_ok=True)
|
|
exe = work / ('evo_peek_check.exe' if os.name == 'nt' else 'evo_peek_check')
|
|
env = dict(os.environ)
|
|
if os.name == 'nt' and MSYS_BIN.exists():
|
|
env['PATH'] = str(MSYS_BIN) + os.pathsep + env.get('PATH', '')
|
|
extra = [] if os.name == 'nt' else ['-pthread']
|
|
subprocess.check_call([compiler(), '-std=gnu11', '-O2', '-Wall', '-Werror', '-I', str(ROOT / 'runtime'),
|
|
str(ROOT / 'tests' / 'evo_peek_check.c'), '-o', str(exe), *extra], env=env)
|
|
try:
|
|
return subprocess.run([str(exe)], env=env, timeout=120).returncode
|
|
except subprocess.TimeoutExpired:
|
|
print('evo_peek_check: FAIL: the check did not end within 120 s')
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|