Repository navigation
v0.0.190
rePIU v0.0.190
이전 릴리스 v0.0.189 이후의 변경입니다(Tasks 718–734). Linux x64에서 pumpit2a가 곡 선택
화면을 지나 곡을 고르고 플레이에 들어갑니다. 렌더 단계 게임 시계가 기본으로 흐르고, Glide
호출이 trap 없이 직접 디스패치됩니다. Windows에서는 pumpit1 legacy 실행의 간헐 종료 크래시를
고쳤습니다.
Linux x64: 어디까지 왔나
| v0.0.189 | v0.0.190 | |
|---|---|---|
| 렌더 단계 게임 시계 | 옵션을 켜야 흐름 | 기본값으로 흐름 |
| Glide 호출 | 전부 ud2 trap (180초에 242만 회) |
직접 디스패치 (trap 0) |
| 180초 실행 swap 수 | 10,344 | 15,832 |
| 곡 선택 화면 | 정지 | 통과 → 곡 선택 → step 데이터 로드 → 곡 재생 |
고친 것
pumpit2a 곡 선택 정지 (Task 734) — Linux x64 return thunk가 guest의 ret과 간접
call/jump 뒤 EFLAGS를 복원하지 않아, 이 경로를 지나는 모든 ret이 CF=0으로 돌아왔습니다.
Watcom C 런타임의 sin/cos helper는 결과를 CF로 알려 주므로 게임이 fsin을 끝없이
재시도했습니다. thunk가 저장한 flags를 jmp 직전에 복원합니다. 이 결함은 ret 뒤에 flags를
읽는 모든 guest 코드에 영향을 줬을 수 있습니다.
Linux x64 렌더 단계 시계 (Task 718) — safe point tick 주입이 기본값입니다. 끄려면
REPIU_LINUX_X64_SAFE_POINT_INJECTION=0을 씁니다. 이전에는 변수가 있기만 하면 켜져서 =0도
켜짐이었습니다.
Linux x64 Glide 직접 디스패치 (Task 720) — direct-dispatch thunk가 i386 assembly에만 있어서
Linux x64의 모든 Glide 호출이 ud2 signal을 거쳤습니다. RepiuLinuxX64GlideGateThunk가
guest x87 상태를 저장·복원하며 export를 직접 부릅니다. 로딩 구간의 1~3.6초 정지는 그대로이며,
Glide trap이 원인이 아니라는 것도 이것으로 확인했습니다.
종료 회수
- x64 종료 회수 판정이 RIP 전체를 봅니다(Task 730). 전에는 하위 32비트만 봐서, host 라이브러리
주소의 하위 절반이 guest 범위에 들면 host frame에서 "회수"할 수 있었습니다. - Windows: pumpit1 legacy 실행이 약 절반 확률로 종료 시
0xC0000005로 죽던 문제를
고쳤습니다(Task 733). 원인은SetThreadContext시점에 커널이 이미 전달 중이던 예외였고,
종료 구간 전용 redirect guard로 막습니다. 수정 뒤 40회 연속 정상 종료했습니다.
바뀐 것 — 로그와 소스 위치
- 공용 로더가
src/host/win32/main.cpp에서 **src/host/loader/main.cpp**로 옮겨졌습니다
(Task 731, 내용 동일). - 로더 로그 줄의
Win32접두어가 없어졌습니다(Task 732).[loader] Win32 minimal execution timed out은 이제[loader] minimal execution timed out입니다. 저장소의 스크립트·가이드
230곳은 함께 고쳤습니다. 외부에서 로그를 파싱한다면 패턴을 고쳐야 합니다. scripts/test_all.ps1의 낡은 pumpit1 단정을 현재 동작에 맞췄습니다(Task 733).
성능 실험 (기본값 꺼짐)
Glide LFB write lock마다 하던 framebuffer 역읽기를, 3dfx page flip처럼 color buffer별 사본을
swap에서 교환하는 방식으로 대신할 수 있습니다(Tasks 728–729). 30초 실행에서 seed가 304회에서
2회로, 역읽기 비용이 약 65억 cycle에서 4,690만 cycle로 줄었지만 이 구간 fps는 거의 그대로
(27.7 → 28.0)여서 기본값은 끈 채로 둡니다. REPIU_GLIDE_LFB_STAGING_REUSE로 켭니다.
새 진단 (설정하지 않으면 동작 없음)
| 변수 / 도구 | 내용 |
|---|---|
REPIU_GLIDE_PIXEL_DIAG_INTERVAL_MS |
시간 간격으로 back buffer를 표본(4×4 밝기 격자). 두 host의 장면을 맞춰 볼 때 |
REPIU_LINUX_X64_NATIVE_SAMPLE, REPIU_LINUX_X64_NATIVE_SAMPLE_TRACE |
Linux x64 guest thread 위치 표본과 표본별 RIP·guest EIP 로그 |
REPIU_GLIDE_LFB_TIME_PROFILE, REPIU_GLIDE_LFB_WRITE_CENSUS |
LFB lock 단계별 비용과 write 범위 |
REPIU_LINUX_X64_LFB_STORE_CENSUS, ..._SOURCE_CENSUS |
LFB에 쓰는 guest 명령과 그 출처 |
REPIU_GLIDE_LFB_STAGING_SHADOW_CENSUS, REPIU_GLIDE_LFB_LOCK_INTERVAL_CENSUS |
역읽기를 건너뛸 수 있는 lock 수와 lock 사이 구간 분류 |
REPIU_LINUX_X64_MEMORY_WRITE_TRACE |
Linux x64 guest 메모리 쓰기 추적 |
REPIU_SHUTDOWN_RECOVERY_TRACE |
Windows 종료 회수 직후 도착한 예외 기록 |
[repiu-shutdown] 줄 |
host_ip=, decision=, aliased=와 Windows redirect guard 개입 횟수 |
scripts/task734_songselect_stall_capture.sh |
곡 선택 정지 같은 대화형 상태를 프레임률·위치 표본·cache map과 함께 기록 |
알려진 것
build_win32_x86.ps1은 설치된 가장 새 Visual Studio를 고르는데, VS 2026(toolset v145)으로
빌드한 binary는dos4gw_hello시작에서 크래시합니다(3/3). VS 2022(v143) binary는 정상입니다.
그래서test_all.ps1을 end-to-end로 끝까지 돌리지 못했습니다.- 사용자 환경에서 CD 미리듣기 음악이 들리지 않았다는 보고는 개발 머신에서 재현되지 않았습니다.
WSLg 출력에는 CD 재생 구간에 소리가 있습니다. - Linux x64 로딩 구간의 1~3.6초 정지는 남아 있습니다(Glide가 원인은 아님).
- Linux x64에서
repiu_instruction_census도구가 GL 심볼 링크 오류로 빌드되지 않습니다. - Linux 측정은 WSLg에서 했습니다.
검증: Linux x64 core probe 31/31(새 guest_return_preserves_flags 포함), Windows x86 core probe
29/29, WSL 자동 입력으로 pumpit2a 곡 선택 → 곡 재생 재현, Windows pumpit1 legacy 종료 40회 연속
정상.
rePIU v0.0.190
Changes since v0.0.189 (Tasks 718–734). On Linux x64, pumpit2a now gets past the song-select
screen, chooses a song and starts playing it. The render-phase game clock runs by default, and Glide
calls dispatch directly instead of trapping. On Windows, an intermittent shutdown crash in pumpit1
legacy runs is fixed.
Where Linux x64 stands
| v0.0.189 | v0.0.190 | |
|---|---|---|
| Game clock in the render phase | runs only with the opt-in | runs by default |
| Glide calls | all through a ud2 trap (2.42 million in 180 s) |
direct dispatch (no traps) |
| Swaps in a 180-second run | 10,344 | 15,832 |
| Song-select screen | freezes | passes → song choice → step data loaded → song plays |
Fixed
pumpit2a song-select freeze (Task 734): the Linux x64 return thunk did not restore EFLAGS after a
guest ret or indirect call/jump, so every ret through it came back with CF=0. The Watcom C runtime's
sin/cos helper reports its result in CF, so the game retried fsin forever. The thunk now restores
the saved flags right before its jmp. The defect may have affected any guest code that reads flags
after a ret.
Linux x64 render-phase clock (Task 718): safe-point tick injection is on by default. Turn it off
with REPIU_LINUX_X64_SAFE_POINT_INJECTION=0; the variable used to be tested for presence, so =0
meant on.
Linux x64 Glide direct dispatch (Task 720): the direct-dispatch thunk existed only as i386 assembly,
so every Glide call on Linux x64 went through a ud2 signal. RepiuLinuxX64GlideGateThunk now calls
the export directly, saving and restoring the guest's x87 state. The 1–3.6 s stalls while loading are
unchanged, which also established that Glide traps are not their cause.
Shutdown recovery
- The x64 shutdown recovery decision reads the full RIP (Task 730). It used to read only the low 32
bits, so a host-library address whose low half fell in the guest range could be "recovered" from a
host frame. - Windows: pumpit1 legacy runs crashed with
0xC0000005at shutdown about half the time; fixed
(Task 733). The cause was an exception the kernel was already delivering whenSetThreadContextran,
now handled by a redirect guard installed only for the shutdown window. After the fix, 40
consecutive runs ended cleanly.
Changed — logs and source layout
- The shared loader moved from
src/host/win32/main.cpptosrc/host/loader/main.cpp(Task 731,
byte-identical). - Loader log lines no longer start with
Win32(Task 732):[loader] Win32 minimal execution timed outis now[loader] minimal execution timed out. The 230 uses in the repository's scripts and
guides were updated with it. External log parsers need their patterns updated. scripts/test_all.ps1's stale pumpit1 assertions were brought up to current behavior (Task 733).
Performance experiment (off by default)
The framebuffer readback each Glide LFB write lock did can be replaced by one copy per color buffer,
exchanged at the swap like a 3dfx page flip (Tasks 728–729). In a 30-second run seeds fell from 304 to
2 and readback cost from about 6.5 billion cycles to 46.9 million, but that stretch's fps barely moved
(27.7 → 28.0), so it stays off. Turn it on with REPIU_GLIDE_LFB_STAGING_REUSE.
New diagnostics (inert when unset)
| Variable / tool | What it does |
|---|---|
REPIU_GLIDE_PIXEL_DIAG_INTERVAL_MS |
samples the back buffer by time (4×4 brightness grid), to line the two hosts up on the same scenes |
REPIU_LINUX_X64_NATIVE_SAMPLE, REPIU_LINUX_X64_NATIVE_SAMPLE_TRACE |
Linux x64 guest-thread position samples, and a per-sample RIP / guest EIP log |
REPIU_GLIDE_LFB_TIME_PROFILE, REPIU_GLIDE_LFB_WRITE_CENSUS |
LFB lock cost by phase, and write extents |
REPIU_LINUX_X64_LFB_STORE_CENSUS, ..._SOURCE_CENSUS |
the guest instructions that store to the LFB, and where they come from |
REPIU_GLIDE_LFB_STAGING_SHADOW_CENSUS, REPIU_GLIDE_LFB_LOCK_INTERVAL_CENSUS |
locks whose readback could be skipped, and what happens between locks |
REPIU_LINUX_X64_MEMORY_WRITE_TRACE |
Linux x64 guest memory write tracing |
REPIU_SHUTDOWN_RECOVERY_TRACE |
Windows: logs the exceptions that arrive right after the shutdown redirect |
[repiu-shutdown] line |
host_ip=, decision=, aliased=, and the Windows redirect guard's intervention counts |
scripts/task734_songselect_stall_capture.sh |
records an interactive state such as the song-select freeze with frame rate, position samples and a cache map |
Known
build_win32_x86.ps1picks the newest installed Visual Studio, and a binary built with VS 2026
(toolset v145) crashes at the start ofdos4gw_hello(3 of 3); the VS 2022 (v143) binary is fine.
test_all.ps1therefore could not be run end to end.- A user report that the CD preview music is inaudible did not reproduce on the development
machine, where the WSLg output carries sound during CD play. - The 1–3.6 s stalls while loading on Linux x64 remain (not caused by Glide).
- The
repiu_instruction_censustool does not link on Linux x64 (unresolved GL symbols). - Linux figures were measured under WSLg.
Verified by Linux x64 core probe 31/31 (including the new guest_return_preserves_flags), Windows x86
core probe 29/29, an automated WSL reproduction of pumpit2a from song select to song playback, and 40
consecutive clean pumpit1 legacy shutdowns on Windows.