Skip to content

perf(libc): set TZ once on Linux - #2031

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
Aryansh1520:fix/libc-tz-once
Oct 10, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
Aryansh1520:fix/libc-tz-once

Conversation

@Aryansh1520

Copy link
Copy Markdown
Contributor

What

Without TZ, glibc's localtime and mktime run tzset on every call, and each tzset re-checks /etc/localtime. PPSA28997 (God of War Sons of Sparta) calls them every frame during its intro, which then spent most of its time there and played back far below speed. libc now sets TZ to :/etc/localtime when it is unset and calls tzset once at load, so the zone file is read once. A TZ set by the user is left as it is. Windows is unchanged.

Tested

  • Linux (CachyOS, kernel 7.2), GCC: PPSA28997's intro plays at normal speed; local times are unchanged.
  • tools/check_conventions.py --base origin/main passes.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

Without TZ, glibc's localtime and mktime run tzset on every call and
re-check /etc/localtime each time. PPSA28997 calls them every frame
during its intro, which then spent most of its time there. TZ is set
to :/etc/localtime when unset, so the zone is read once.
@MarcZX10

MarcZX10 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

The optimization and evidence are Linux/glibc-specific, but #ifndef _WIN32 also runs this initializer on macOS. That changes the process environment there and forces an explicit /etc/localtime zone-file path without Darwin validation. Could you gate this with __linux__ (or provide a macOS behavior test and evidence) so the change only affects the platform described in the PR? I’m holding approval pending that.

@github-actions github-actions Bot added the libc label Oct 9, 2026
@Aryansh1520

Copy link
Copy Markdown
Contributor Author

Agreed. The initializer is now behind #ifdef __linux__, so macOS and Windows are unchanged and the change only affects the platform the PR describes.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for limiting the initializer to __linux__. I built exact head 631654b6 on Linux with GCC 12 and ran guest_time_conversion with TZ unset; it passed 1/1 in 0.46 s. Conventions and git diff --check pass. GitHub currently reports no checks on this head, so please get the required CI jobs running (or have a maintainer approve any held workflow) before merge. I will hold approval until checks are visible.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Could you add numbers for the PPSA28997 intro, main against main plus this (fps or frame time over a few runs)? Perf changes need before/after figures for the change itself (#218).

@Aryansh1520

Copy link
Copy Markdown
Contributor Author

PPSA28997, Linux (CachyOS, kernel 7.2), GCC, same build with and without this change: the time from the Sony logo to the Santa Monica logo drops from about 2 minutes to about 15–20 seconds, which is normal speed. Without it, the intro plays far below speed the whole time because localtime/mktime re-read the zone each frame.

@popcoder565

Copy link
Copy Markdown
Contributor

Native Windows run, since no Windows results were posted. Setup: Windows 10 (19045), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head 631654b6, merged onto main d70b899 in one build with 38 other PRs that had no Windows run.

No title was run.

🤖 Addressed by Claude Code

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the diff against glibc (tzset_internal has no early return when TZ is unset, so every localtime/mktime re-reads the zone file), built the libc tests on Linux and ran them (42/43; guest_time_conversion passes, the one not run is guest_wcsrtombs, whose executable isn't in the scoped build). Numbers for PPSA28997 are in the thread, Linux-only gating is in, and Windows builds per @popcoder565. Merging.

@adriadam10
adriadam10 merged commit 2337e0d into boykopovar:main Oct 10, 2026
6 checks passed
SleglJan pushed a commit to SleglJan/AnyPS5 that referenced this pull request Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants