DSP callers were charged the local SDK CPU server budget, whose command representation is larger than the Horizon service representation. For Age of Calamity the service requires 0x61d000 while the local SDK requires 0x760000, exhausting the fixed sound heap. Calculate the service requirement through renderer revision 15 and supply larger local backend storage separately, with cleanup on failed open and after renderer close. Remove the two game heap cuts and add sizing, nested-open, failure and lifetime regression coverage. Validation: 360 seeded cases match isolated Horizon machine-code execution across REV1-REV15; the original game heaps initialize all five players and produce audio; the host suite, documentation and patch checks, SDK 8/20 smoke checks and iOS C compilation pass. iOS runtime and long battles remain untested.
146 lines
8.4 KiB
Makefile
146 lines
8.4 KiB
Makefile
# dm/host unit tests in one command: make -C dm/host/tests GAME=<base game title ID> run (takes seconds; build output goes to build/ and is not committed)
|
|
B = build
|
|
PYTHON ?= python3
|
|
# game profile header (dm.h needs game_profile.h, generated by the host Makefile into ../gen/<profile>/)
|
|
# tests that use the game profile need GAME=<base game title ID> (there is no default game); GINC only expands when used, so tests without the profile build as before
|
|
GINC = $(if $(strip $(GAME)),-I../gen/$(GAME) -I../../games/$(GAME),$(error GAME is not set: make GAME=<base game title ID>: $(shell python3 ../../games/game.py list | awk -F'\t' '{printf "%s (%s) ", $$1, $$3}')))
|
|
GAME_H = ../gen/$(GAME)/game_profile.h
|
|
run: $(B)/t_heap_size $(B)/t_touch $(B)/t_gesture $(B)/t_oe $(B)/t_fs $(B)/t_fs_commit_list $(B)/t_thread_leak $(B)/t_fs_case $(B)/t_audio $(B)/t_audio_spsc $(B)/t_swkbd $(B)/t_altstack $(B)/t_condvar $(B)/t_condvar_old $(B)/t_pctl $(B)/t_time $(B)/t_shared_font $(B)/t_vorbis $(B)/t_vorbis_divides $(B)/t_hid $(B)/t_haptics $(B)/t_haptics_apple
|
|
$(B)/t_heap_size
|
|
$(B)/t_touch
|
|
$(B)/t_gesture
|
|
$(B)/t_oe 2>/dev/null
|
|
$(B)/t_fs 2>/dev/null
|
|
TMPDIR="$(abspath $(B))" $(B)/t_fs_commit_list
|
|
$(B)/t_thread_leak
|
|
TMPDIR="$(abspath $(B))" $(B)/t_fs_case 2>/dev/null
|
|
$(B)/t_audio
|
|
$(B)/t_audio_spsc
|
|
$(B)/t_audren_work
|
|
$(B)/t_swkbd
|
|
$(B)/t_altstack
|
|
$(B)/t_condvar
|
|
$(B)/t_condvar_old
|
|
$(B)/t_preempt
|
|
$(B)/t_preempt --all-peers
|
|
$(B)/t_pctl
|
|
$(B)/t_time
|
|
$(B)/t_shared_font
|
|
$(B)/t_system_event
|
|
$(B)/t_vorbis
|
|
$(B)/t_vorbis_divides
|
|
$(B)/t_hid
|
|
$(B)/t_haptics
|
|
$(B)/t_haptics_apple
|
|
$(B)/t_nro
|
|
run: $(B)/t_nro
|
|
run: $(B)/t_system_event
|
|
run: $(B)/t_audren_work
|
|
$(B)/t_audren_work: t_audren_work.c ../hle_audren.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -g -Wall -Werror -Wno-unused-function -I.. $(GINC) -o $@ t_audren_work.c
|
|
.PHONY: audren-work
|
|
audren-work: $(B)/t_audren_work
|
|
$(B)/t_audren_work
|
|
$(B)/t_system_event: t_system_event.c ../hle_thread.c ../hle_sdk16.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -g -Wall -Werror -Wno-unused-function -Wno-frame-address -I.. $(GINC) -o $@ t_system_event.c
|
|
.PHONY: system-event
|
|
system-event: $(B)/t_system_event
|
|
$(B)/t_system_event
|
|
$(B)/t_nro: t_nro.c ../loader.c ../hle_ro.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -g -Wall -Wno-unused-function -Wno-deprecated-declarations -I.. $(GINC) -o $@ t_nro.c
|
|
.PHONY: nro
|
|
nro: $(B)/t_nro
|
|
$(B)/t_nro
|
|
$(GAME_H):
|
|
$(MAKE) -C .. game_profile GAME=$(GAME)
|
|
$(B)/t_heap_size: t_heap_size.c ../hle_svc.c ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Werror -Wno-unused-function -fsanitize=undefined -I.. $(GINC) -o $@ t_heap_size.c
|
|
.PHONY: heap_size
|
|
heap_size: $(B)/t_heap_size
|
|
$(B)/t_heap_size
|
|
$(B)/t_touch: t_touch.c ../hle_touch.c ../front.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_touch.c ../hle_touch.c
|
|
$(B)/t_gesture: t_gesture.c ../hle_touch.c ../front.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Wno-unused-function -I.. $(GINC) -o $@ t_gesture.c ../hle_touch.c
|
|
$(B)/t_thread_leak: t_thread_leak.c ../thread.c ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_thread_leak.c
|
|
$(B)/t_fs: t_fs.c t_fs_stub.c ../hle_fs.c ../hle_bigstack.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_fs.c t_fs_stub.c ../hle_bigstack.c
|
|
$(B)/t_fs_commit_list: t_fs_commit_list.c t_fs_stub.c ../hle_fs.c ../hle_bigstack.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Wno-unused-function -I.. $(GINC) -o $@ t_fs_commit_list.c t_fs_stub.c ../hle_bigstack.c
|
|
$(B)/t_fs_case: t_fs_case.c ../hle_fs.c ../hle_bigstack.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_fs_case.c ../hle_bigstack.c
|
|
$(B)/t_audio: t_audio.c ../hle_audio.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_audio.c -framework AudioToolbox
|
|
$(B)/t_audio_spsc: t_audio_spsc.c ../hle_audio.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_audio_spsc.c -framework AudioToolbox
|
|
$(B)/t_audio_spsc_tsan: t_audio_spsc.c ../hle_audio.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -g -O1 -fsanitize=thread -Wno-unused-function -I.. $(GINC) -o $@ t_audio_spsc.c -framework AudioToolbox
|
|
$(B)/t_swkbd: t_swkbd.c ../hle_swkbd.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_swkbd.c ../hle_swkbd.c
|
|
$(B)/t_altstack: t_altstack.c t_altstack_stub.c ../crash.c ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_altstack.c t_altstack_stub.c ../crash.c
|
|
$(B)/t_pctl: t_pctl.c ../hle_misc.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Werror -Wno-unused-function -I.. $(GINC) -o $@ t_pctl.c
|
|
$(B)/t_shared_font: t_shared_font.c ../hle_sdk16.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Werror -Wno-unused-function -Wno-frame-address -I.. $(GINC) -o $@ t_shared_font.c
|
|
$(B)/t_hid: t_hid.c ../hle_hid.c ../hle_haptics.c ../hle_haptics.h ../pad_slots.h ../dm_input.h ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Werror -Wno-unused-function -I.. $(GINC) -o $@ t_hid.c ../hle_haptics.c
|
|
$(B)/t_hid_tsan: t_hid.c ../hle_hid.c ../hle_haptics.c ../hle_haptics.h ../pad_slots.h ../dm_input.h ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -g -fsanitize=thread -Wall -Werror -Wno-unused-function -I.. $(GINC) -o $@ t_hid.c ../hle_haptics.c
|
|
$(B)/t_haptics: t_haptics.c ../hle_haptics.c ../hle_haptics.h ../dm_input.h | $(B)
|
|
clang -O1 -g -Wall -Werror -I.. -o $@ t_haptics.c ../hle_haptics.c
|
|
$(B)/t_haptics_apple: t_haptics_apple.m ../haptics_apple.m ../haptics_apple.h ../hle_haptics.c ../hle_haptics.h | $(B)
|
|
clang -O1 -g -fobjc-arc -Wall -Werror -I.. -o $@ t_haptics_apple.m ../hle_haptics.c -framework Cocoa -framework GameController -framework CoreHaptics
|
|
$(B)/t_time: t_time.c ../hle_time.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wall -Werror -Wno-unused-function -I.. $(GINC) -o $@ t_time.c
|
|
$(B)/t_oe: t_oe.c ../hle_oe.c ../hle.h ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -I.. $(GINC) -o $@ t_oe.c
|
|
$(B)/t_condvar: t_condvar.c t_condvar_stub.c ../hle_thread.c ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -DDM_TEST_HOOKS -I.. $(GINC) -o $@ t_condvar.c t_condvar_stub.c ../hle_thread.c
|
|
$(B)/t_condvar_old: t_condvar.c t_condvar_stub.c ../hle_thread.c ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -Wno-unused-function -DDM_TEST_HOOKS -DDM_TEST_CV_OLD_ORDER -I.. $(GINC) -o $@ t_condvar.c t_condvar_stub.c ../hle_thread.c
|
|
$(B)/t_preempt: t_preempt.c t_condvar_stub.c ../hle_thread.c ../dm.h $(GAME_H) | $(B)
|
|
clang -O1 -g -Wall -Werror -Wno-unused-function -I.. $(GINC) -o $@ t_preempt.c t_condvar_stub.c
|
|
.PHONY: preempt
|
|
preempt: $(B)/t_preempt
|
|
$(B)/t_preempt
|
|
$(B)/t_preempt --all-peers
|
|
run: $(B)/t_preempt
|
|
# the Vorbis tests build their own packets and need no game profile (they build without GAME)
|
|
$(B)/t_vorbis: t_vorbis.c ../../third_party/stb_vorbis/stb_vorbis.c | $(B)
|
|
clang -O1 -g -Wno-unused-function -Wno-tautological-compare -o $@ t_vorbis.c
|
|
$(B)/t_vorbis_divides: t_vorbis.c ../../third_party/stb_vorbis/stb_vorbis.c | $(B)
|
|
clang -O1 -g -DSTB_VORBIS_DIVIDES_IN_RESIDUE -Wno-unused-function -Wno-tautological-compare -o $@ t_vorbis.c
|
|
$(B):
|
|
mkdir -p $@
|
|
.PHONY: run tsan
|
|
tsan: $(B)/t_audio_spsc_tsan $(B)/t_hid_tsan
|
|
$(B)/t_audio_spsc_tsan
|
|
$(B)/t_hid_tsan
|
|
|
|
MEM_FLAGS = -O1 -Wall -Werror -Wno-unused-function -Imemory_profile -I..
|
|
MEM_DEPS = t_svc_memory.c memory_profile/game_profile.h ../hle_svc.c ../hle_guestthread.c ../hle.h ../dm.h
|
|
$(B)/t_svc_memory: $(MEM_DEPS) | $(B)
|
|
clang $(MEM_FLAGS) -fsanitize=undefined -o $@ t_svc_memory.c
|
|
$(B)/t_svc_memory_unlimited: $(MEM_DEPS) | $(B)
|
|
clang $(MEM_FLAGS) -fsanitize=undefined -DDM_GAME_MEM_MAP_LIMIT=0 -o $@ t_svc_memory.c
|
|
$(B)/t_svc_memory_16k: $(MEM_DEPS) | $(B)
|
|
clang $(MEM_FLAGS) -fsanitize=address,undefined -DTEST_PAGE_16K -o $@ t_svc_memory.c
|
|
$(B)/t_svc_memory_tsan: $(MEM_DEPS) | $(B)
|
|
clang $(MEM_FLAGS) -fsanitize=thread -o $@ t_svc_memory.c
|
|
$(B)/t_svc_memory_dirty: $(MEM_DEPS) ../../gfx/nvn/nvn_dirty.c ../../gfx/nvn/nvn_dirty.h | $(B)
|
|
clang $(MEM_FLAGS) -DTEST_REAL_DIRTY -o $@ t_svc_memory.c ../../gfx/nvn/nvn_dirty.c
|
|
.PHONY: memory memory-tsan memory-dirty memory-profile
|
|
memory: $(B)/t_svc_memory $(B)/t_svc_memory_unlimited $(B)/t_svc_memory_16k
|
|
$(B)/t_svc_memory
|
|
$(B)/t_svc_memory_unlimited
|
|
$(B)/t_svc_memory_16k
|
|
memory-tsan: $(B)/t_svc_memory_tsan
|
|
$(B)/t_svc_memory_tsan
|
|
memory-dirty: $(B)/t_svc_memory_dirty
|
|
$(B)/t_svc_memory_dirty
|
|
memory-profile: $(B)/t_svc_memory
|
|
$(PYTHON) test_memory_profile.py
|
|
run: memory memory-dirty memory-profile
|