Skip to content

Honor the condvar clock in pthread_cond_timedwait on Darwin - #58

Open
HashimTheArab wants to merge 1 commit into
minecraft-linux:masterfrom
HashimTheArab:darwin-condvar-clock
Open

Honor the condvar clock in pthread_cond_timedwait on Darwin#58
HashimTheArab wants to merge 1 commit into
minecraft-linux:masterfrom
HashimTheArab:darwin-condvar-clock

Conversation

@HashimTheArab

Copy link
Copy Markdown

Problem

host_condattr skips pthread_condattr_setclock under __APPLE__ (Darwin has no such call), so every game condvar is a CLOCK_REALTIME wait on the host, while the game arms deadlines on CLOCK_MONOTONIC (WebRTC / NetherNet does, via pthread_condattr_setclock — and pthread_cond_timedwait_monotonic_np was aliased straight to the realtime pthread_cond_timedwait).

A monotonic deadline interpreted as realtime is a timestamp in 1970, so the wait returns ETIMEDOUT immediately and the caller loops. Sampled on macOS 26 / Apple Silicon at the main menu of 1.26.45: the NetherNet Signal thread had 77% of its samples inside shim::pthread_cond_timedwait → _pthread_cond_wait → __gettimeofday, pinning one full core forever. This is the same class of symptom as minecraft-linux/mcpelauncher-manifest#1009.

Change

Keep the clock beside each host condvar (host_cond { pthread_cond_t cond; clockid_t clock; } — the cond stays the first member, so to_host is unchanged) and, on Apple, turn monotonic deadlines into relative waits with pthread_cond_timedwait_relative_np. Static-initialised condvars default to CLOCK_REALTIME as bionic does. pthread_cond_timedwait_monotonic_np gets its own entry point that always treats the deadline as monotonic. Non-Apple behaviour is unchanged.

Result

Main-menu CPU of mcpelauncher-client-arm64-v8a (hidden window, 10 fps cap so rendering is out of the picture): 100% → 3–4%, and gettimeofday disappears from the profile. Game plays normally.

🤖 Generated with Claude Code

https://claude.ai/code/session_012bijEWrxdPwBcdeTP6iyXj

Darwin has no pthread_condattr_setclock, so every game condvar was a
CLOCK_REALTIME wait while the game arms deadlines on CLOCK_MONOTONIC
(WebRTC/NetherNet does). A monotonic deadline read as realtime is in
1970, the wait times out instantly and the thread spins: one NetherNet
Signal thread alone burned a full core at the main menu on macOS.

Keep the clock beside each host condvar and turn monotonic deadlines
into pthread_cond_timedwait_relative_np; pthread_cond_timedwait_monotonic_np
is now its own entry point instead of aliasing the realtime one.
Measured: main-menu CPU 100% -> 3-4%.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012bijEWrxdPwBcdeTP6iyXj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant