Skip to content

feat(libkernel): implement msync - #1857

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
hikazey:feat/msync
Oct 9, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
hikazey:feat/msync

Conversation

@hikazey

@hikazey hikazey commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

What

Adds msync to libkernel, next to mmap, munmap and mprotect in DirectMemory/PosixMemory.cpp. It follows FreeBSD 11's kern_msync and vm_map_sync over the guest's mappings as sceKernelVirtualQuery reports them:

  • The address is rounded down to the page and the length rounded up, with the same unsigned arithmetic as kern_msync. A range whose end wraps is EINVAL.
  • MS_ASYNC | MS_INVALIDATE is EINVAL. Other flag bits are not checked, as in FreeBSD.
  • An unmapped start, or any unmapped page in the range, is ENOMEM. Length 0 checks the mapping that holds the address (vm_map_sync widens start == end to that entry). Reservations count as mapped, since FreeBSD has a map entry for them.
  • Success writes nothing back: the guest's mmap only creates private anonymous mappings, so there are no file mappings to sync.
  • MS_INVALIDATE on a mapped range throws. FreeBSD returns EBUSY there when the range holds mlocked pages, and locked pages are not tracked. The ENOMEM check comes first, as in vm_map_sync.

One limitation is recorded in TechnicalDebt with the rest: a page munmaped from inside a larger mapping still counts as mapped, because sceKernelVirtualQuery keeps reporting the whole mapping after a partial unmap (on main too).

EVO-PLAYER PPSA99039 v0.11.0 (sainsaji/EVO-PLAYER-PS5) imports it for a mapped-file benchmark (projects/evoplayer/src/evo_iobench.c, msync(p, len, MS_SYNC)). It's also in the absent lists of other titles in #1578, where it was claimed.

Tested

  • Title. EVO-PLAYER PPSA99039 v0.11.0 (release ZIP sha256 687c0f0f…5349, eboot.bin and the bundled libc.prx unwrapped from their SELFs), relinked with --windows on Windows 11. On main 364a56b with feat(libSceNet): implement sceNetResolverStartNtoaMultipleRecordsEx #1838, feat(libkernel): implement getdents and getdirentries #1634, feat(videoout): implement sceVideoOutGetResolutionStatus #1714 and feat(libkernel): implement the sigset functions #1641 merged locally (its earlier stops):
  • New guest_msync test (Windows and Linux): success for the whole range, MS_ASYNC, an unaligned address inside the mapping, a range crossing a page boundary, length 0, an unknown flag bit and a reserved range, with errno untouched on success; EINVAL for MS_ASYNC | MS_INVALIDATE and a wrapping range; ENOMEM after munmap for the start, a range, length 0 and MS_INVALIDATE; the MS_INVALIDATE throw on a mapped range.
  • Windows 11 Pro (26200), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release, configured like CI: guest_msync 5/5; full suite 482/482. Mutations, each with the test kept, all fail: the mapped check removed, the MS_ASYNC | MS_INVALIDATE check removed, the throw moved before the mapped check, and the wrap check removed.
  • Linux (Ubuntu 24.04 container, GCC 14.2, Release): guest_msync 5/5; full suite 488/488; the mapped-check mutation fails.
  • Rebased onto main ae91d97: guest_msync 3/3 on Windows; tools/check_conventions.py --base origin/main passes.
  • Not measured on a console: the semantics come from FreeBSD's source, as the TechnicalDebt line says.

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

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Progress report (8d47cfb → 0bff6da)

➖ System libraries: 85.46% (+0.0%, +1 implemented functions)

✅ 1 implemented
Library Name
libkernel msync_nid_postfix

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#1633 core/libs/prx/libkernel/DirectMemory/PosixMemory.cpp L1-2, L17, L115
#1909 core/libs/prx/libkernel/DirectMemory/PosixMemory.cpp L17

msync follows FreeBSD 11's kern_msync and vm_map_sync over the guest's
mappings as sceKernelVirtualQuery reports them: the address is rounded
down to the page, a range that wraps and MS_ASYNC with MS_INVALIDATE are
EINVAL, an unmapped start or page is ENOMEM, and length 0 checks the
mapping that holds the address. The guest has no file mappings, so a
successful call has nothing to write back. MS_INVALIDATE on a mapped
range throws, since FreeBSD's EBUSY for mlocked pages needs lock state
that is not tracked.

EVO-PLAYER PPSA99039 v0.11.0 imports it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked msync against FreeBSD 11 kern_msync/vm_map_sync (page rounding, wrap and MS_ASYNC | MS_INVALIDATE give EINVAL, unmapped range gives ENOMEM, MS_INVALIDATE on a mapped range throws).

The branch conflicted with main only by adjacency (mlock/munlock in PosixMemory.cpp, the test block in libkernel/CMakeLists.txt). I rebased it keeping both sides, no logic changes. Full build and ctest on the rebased head: 525/525, guest_msync passes, and without the change it doesn't link, so it does exercise the code.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 9, 2026
@adriadam10
adriadam10 merged commit fa899a3 into boykopovar:main Oct 9, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants