Files
parallel-gx2/.gitlab-ci.yml
T
libretroadmin 5de6d7d261 Optimization pass: no polling sleeps or locks in the hot handoffs
The recompiler thread looked for work every 10 ms, so a function the
interpreter had just run waited 5 ms on average before its translation
began, and every queued address could allocate inside std::queue. Its
queue is now a fixed retro_spsc ring with an eventcount
(PPCRecompilerWorkQueue): a push wakes the thread at once, the thread pops
without the recompiler's spinlock, and a full queue refuses the push so
the address stays unvisited and is offered again later.

Loading the Vulkan pipeline cache napped 10 ms whenever 50 pipelines were
queued and again while the last ones compiled, which held a warm driver
cache to 50 pipelines per 10 ms. The GPU thread now sleeps on an
eventcount (LatteGpuWake) that the compile threads notify after each
pipeline and that a pause request or a stop also notify, so it refills
the queue as soon as there is room and still answers a context loss at
once. The pipeline cache's save thread keeps its 15 s debounce but sleeps
on an eventcount that the renderer's destruction notifies, instead of
looking every 250 ms.

The CPU timer's TSC calibration measured for three seconds and the title
start waited for it, which in RetroArch is every boot. Both clocks are
read back to back, so 25 ms already gives about one part in 10^5: the
first estimate is published then and refined at 200 ms and 3 s by the
same measurement. The rate only divides elapsed ticks, so a refinement
changes no time already counted. The title start waits on an eventcount
instead of a 10 ms poll.

Audio goes to the frontend straight out of the ring buffer (Peek/Consume)
and AX's blocks are converted straight into it (Reserve/Commit), so the
per-frame copy into a 192 KiB flush buffer, the pull buffer and the
conversion vector are gone. The ring moves to LibretroAudioRing.h.

The frame gate and the frame handoff between the GPU thread and retro_run
are atomics and eventcounts in place of two mutexes and condition
variables, with the same predicates and the same timeout.

retro_spsc is synced from RetroArch's libretro-common. test/handoff checks
the work queue (every address once and in order from three serialised
pushers, wake-up from a parked consumer, the bound, the stop), the GPU
wake, and the audio ring (whole-frame spans across the wrap for 2 and 6
channels, a producer and a consumer thread streaming), plain, under TSan
and under ASan/UBSan, in both CIs.
2026-11-07 12:22:08 +01:00

207 lines
6.0 KiB
YAML

# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
##############################################################################
################################# BOILERPLATE ################################
##############################################################################
# Core definitions
.core-defs:
variables:
GIT_SUBMODULE_STRATEGY: recursive
CORENAME: parallel_gx2
# Inclusion templates, required for the build to work
include:
################################## DESKTOPS ################################
# Windows
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-x64-mingw.yml'
# Linux 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-x64.yml'
# Linux ARM 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-aarch64.yml'
# MacOS x64
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-x64.yml'
# MacOS arm64
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-arm64.yml'
################################## CELLULAR ################################
# Android
- project: 'libretro-infrastructure/ci-templates'
file: '/android-make.yml'
# iOS arm64
- project: 'libretro-infrastructure/ci-templates'
file: '/ios-arm64.yml'
# tvOS arm64
- project: 'libretro-infrastructure/ci-templates'
file: '/tvos-arm64.yml'
################################## MISC ####################################
# webOS aarch64
- project: 'libretro-infrastructure/ci-templates'
file: '/webos-make.yml'
# Stages for building
stages:
- build-prepare
- build-shared
- test
##############################################################################
#################################### STAGES ##################################
##############################################################################
#
################################### DESKTOPS #################################
# Linux wants the X11 and XCB headers Vulkan's surfaces are declared with
# (OpenGL needs none: the context is the frontend's); a job defining
# before_script replaces the template's, so its one line is repeated here.
.core-defs-linux:
extends: .core-defs
variables:
# Cemu is C++20
CC: gcc-12
CXX: g++-12
before_script:
- export NUMPROC=$(($(nproc)/5))
- apt-get update -qq
- apt-get install -y --no-install-recommends
libx11-dev libxrender-dev libx11-xcb-dev
# Windows 64-bit
libretro-build-windows-x64:
extends:
- .libretro-windows-x64-mingw-make-default
- .core-defs
# Linux 64-bit
libretro-build-linux-x64:
extends:
- .libretro-linux-x64-make-default
- .core-defs-linux
# Ubuntu Xenial's GCC cannot build C++20; backports is the same family
# of image with newer compilers, gcc-12 among them.
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:backports
# Linux ARM 64-bit
libretro-build-linux-aarch64:
extends:
- .libretro-linux-aarch64-make-default
- .core-defs-linux
# macOS Intel
libretro-build-osx-x64:
tags:
- mac-apple-silicon
extends:
- .libretro-osx-x64-make-default
- .core-defs
variables:
arch: x86_64
# macOS arm64
libretro-build-osx-arm64:
extends:
- .libretro-osx-arm64-make-default
- .core-defs
################################### CELLULAR #################################
# Android ARMv8a
android-arm64-v8a:
extends:
- .libretro-android-make-arm64-v8a
- .core-defs
# Android x86_64 (for play only)
android-x86_64:
extends:
- .libretro-android-make-x86_64
- .core-defs
# iOS arm64: Metal only, the Vulkan renderer needs MoltenVK and a
# frontend surface the core does not get here
libretro-build-ios-arm64:
extends:
- .libretro-ios-arm64-make-default
- .core-defs
variables:
IOS_MINVER: "13.4"
# tvOS arm64
libretro-build-tvos-arm64:
extends:
- .libretro-tvos-arm64-make-default
- .core-defs
variables:
MINVER: "13.4"
################################## MISC ####################################
# webOS aarch64
libretro-build-webos-aarch64:
extends:
- .libretro-webos-aarch64-make-default
- .core-defs
#################################### TESTS ###################################
# The network layer that stands in for libcurl and OpenSSL
# (dependencies/curl-compat), against local HTTP and TLS servers.
test-curl-compat:
stage: test
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:backports
needs: []
variables:
GIT_SUBMODULE_STRATEGY: none
CC: gcc-12
CXX: g++-12
before_script:
- apt-get update -qq
- apt-get install -y --no-install-recommends python3 openssl
script:
- ./dependencies/curl-compat/test/run_tests.sh
- make -C dependencies/curl-compat/test clean
- SANITIZER=address,undefined ./dependencies/curl-compat/test/run_tests.sh
- make -C dependencies/curl-compat/test clean
- SANITIZER=thread ./dependencies/curl-compat/test/run_tests.sh
# The OpenGL GPU as a cothread of the frontend's thread (LatteGpuCothread.h):
# the run/yield protocol, exit and restart, and libco on several threads at
# once. ThreadSanitizer does not follow stack switches, so not under it.
test-gpu-cothread:
stage: test
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:backports
needs: []
variables:
GIT_SUBMODULE_STRATEGY: none
CC: gcc-12
CXX: g++-12
script:
- ./test/gpu_cothread/run_tests.sh
- make -C test/gpu_cothread clean
- SANITIZER=address,undefined ./test/gpu_cothread/run_tests.sh
# The lock-free handoffs between the core's threads: the recompiler's work
# queue, the GPU thread's wake, the audio ring.
test-handoff:
stage: test
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:backports
needs: []
variables:
GIT_SUBMODULE_STRATEGY: none
CC: gcc-12
CXX: g++-12
script:
- ./test/handoff/run_tests.sh
- make -C test/handoff clean
- SANITIZER=thread ./test/handoff/run_tests.sh
- make -C test/handoff clean
- SANITIZER=address,undefined ./test/handoff/run_tests.sh