diff --git a/.github/workflows/build-proton.yml b/.github/workflows/build-proton.yml index 6b1b2ab9aed9..1541c8b4fe5a 100644 --- a/.github/workflows/build-proton.yml +++ b/.github/workflows/build-proton.yml @@ -331,7 +331,7 @@ jobs: Single SDK 28 build with 16KB page size support (works on Android 9+ and Android 15+). ### Features - - Experimental userspace ntsync (via [ntsync-android](https://github.com/GameNative/ntsync-android), commit [`8ebe2ea`](https://github.com/GameNative/ntsync-android/commit/8ebe2ea0cb88ad93b64ed95eed1c01ce537a3fe3)) + fsync, with wineserver-side `ntsync_event_set` support + - Experimental userspace ntsync (via [ntsync-android](https://github.com/GameNative/ntsync-android), commit [`7ce6435`](https://github.com/GameNative/ntsync-android/commit/7ce6435e5979b1cb5341aa4b299f31e8937fe121)) + fsync, with wineserver-side `ntsync_event_set` support - `WINE_FAST_YIELD` fast-yield hook in `NtYieldExecution` - FEX integration (stats shm, `SkipThreadAttach` detach guard) via bylaws' arm64ec patches - FEX unixlib loader: `MemoryWineLoadUnixLibByName` / wow64 / unload support with `$PREFIX/lib/wine` fallback @@ -339,12 +339,15 @@ jobs: - Integrated lsteamclient built into Proton (supports GameNative bionic Steam) - Stripped, `-g0 -O2` build: smaller tree, faster install (zstd-packed `.wcp`) - ### ntsync-android changelog ([`d00ac47`..`8ebe2ea`](https://github.com/GameNative/ntsync-android/compare/d00ac47491f2a5505d2ea3a2c8533f498a9811b0...8ebe2ea0cb88ad93b64ed95eed1c01ce537a3fe3)) - - **Auto-sweep of dead processes' objects (layout v9)** — signal ops and wait timeouts now run a rate-limited region-wide sweep (default 30 s, `NTSYNC_SWEEP_INTERVAL_SEC` to tune, `0` to disable), replacing manual `ntsync_sweep_dead()` reliance; the stuck-wait debug dump shows creator pid liveness. Fixes a plausible cause of 60 s `RtlpWaitForCriticalSection ... blocked by 0000` stalls after a Wine process crashes. + ### ntsync-android changelog ([`d00ac47`..`7ce6435`](https://github.com/GameNative/ntsync-android/compare/d00ac47491f2a5505d2ea3a2c8533f498a9811b0...7ce6435e5979b1cb5341aa4b299f31e8937fe121)) + - **Adaptive spin-before-block (`NTSYNC_SPIN_ITERS`, default off)** — a waiter spins briefly on a read-only acquire check before sleeping on the futex; a signal landing in the window avoids a sleep+wake pair entirely. Per-thread adaptive credit (JVM-style) self-throttles threads with long waits. Measured on device: Persona 5 Royal avoids 25-28% of blocked-wait sleeps during sync bursts (60-76% spin win rate); Dishonored / Lies of P / Hades II correctly self-throttle to ~0.2% CPU. See the README per-game tuning guide. + - **Wait-path trims + sweep-trigger RSS fix** — WAIT_ALL rollback no longer zeroes 1 KB of stack per call; auto-sweep triggers moved off the lock-free signal ops into wait paths only (a dead-process scan can never land on a latency-critical signaler); bounded sweep scans fix a sparse-page RSS spike (664 kB -> 112 kB when a sweep ran). + - **Auto-sweep of dead processes' objects (layout v9)** — wait paths run a rate-limited region-wide sweep (default 30 s, `NTSYNC_SWEEP_INTERVAL_SEC` to tune, `0` to disable), replacing manual `ntsync_sweep_dead()` reliance; the stuck-wait debug dump shows creator pid liveness. Fixes a plausible cause of 60 s `RtlpWaitForCriticalSection ... blocked by 0000` stalls after a Wine process crashes. - **Wait-path CPU reductions** — wake-latency instrumentation is now debug-gated, `futex_wake` wakes exactly one waiter, and all per-wait heap allocations became fixed stack arrays. Measured vs. baseline: cross-process RPC **-17%**, multi-process contention **-25%**, Wine mixed load **-8%** CPU per op. - **Lazy region init (layout v8)** — the ~960 KB shm file is no longer bulk-zeroed at init: mapped RSS drops from 976 kB to ~16 kB (sparse pages, negligible flash writeback), growing only as objects/waiters actually arrive. - **`NTSYNC_NO_SIGUSR1_BLOCK=1` opt-out** — skips the two `pthread_sigmask` syscalls per region-lock acquisition (~13% per-op under multi-process contention). Default stays on; only safe outside Wine. - **Wine-workload benchmark suite** — 7 benches (shm footprint, signaled fast path, cross-process RPC, mixed load, fork/exec multi-process contention) with a JSON baseline for regression gating. + - **On-device stats (`NTSYNC_DEBUG=1`)** — per-process counters (waits, fast-path hits, sleeps, wake walks, wake latency, spin wins/exhaustion) dumped every 10 s; validated at scale in four games with zero lock contention and zero EAGAIN churn. ### Android / bionic fixes - Anonymous PE-image mapping for bionic (vc4 devices); `LC_ALL=C.UTF-8` default; shell32 drive-root path fix diff --git a/android/patches/common/server_token_c.patch b/android/patches/common/server_token_c.patch index 02d908119f9a..a095bd597d93 100644 --- a/android/patches/common/server_token_c.patch +++ b/android/patches/common/server_token_c.patch @@ -2,14 +2,19 @@ diff --git a/server/token.c b/server/token.c index 31fc4b8..48c15ce 100644 --- a/server/token.c +++ b/server/token.c -@@ -221,12 +221,33 @@ void init_user_sid(void) +@@ -221,12 +221,44 @@ void init_user_sid(void) size_t n; FILE *f; +#ifdef __ANDROID__ + /* /etc/machine-id is absent on Android. Fall back to a per-prefix -+ * file so the machine SID stays stable across reboots/restarts. */ ++ * file so the machine SID stays stable across reboots/restarts. ++ * GameNative sets PREFIX rather than WINEPREFIX; accept both, and ++ * bail out cleanly when neither is set or the file cannot be ++ * opened (previously f was used uninitialized when WINEPREFIX was ++ * unset -> intermittent fread(garbage) crash at wineserver start). */ + const char *prefix = getenv("WINEPREFIX"); ++ if (!prefix) prefix = getenv("PREFIX"); + if (prefix) + { + char path[4096]; @@ -25,6 +30,12 @@ index 31fc4b8..48c15ce 100644 + } + } + } ++ if (!f) ++ { ++ fprintf( stderr, "init_user_sid: no WINEPREFIX/PREFIX, using zero machine id.\n" ); ++ memset( machine_id, 0, sizeof(machine_id) ); ++ return; ++ } +#else f = fopen( "/etc/machine-id", "r" ); if (!f)