ReviewOS

home-lang/home

fix(threading): honor ThreadAttr, implement CPU affinity and `Semaphore.getValue`

#803
Open chris opened this 8 days ago ·
8 days ago

Problem

Thread.spawn ignores its allocator and never uses ThreadAttr, so stack size and priority are dropped. setAffinity / getAffinity return NotSupported on every OS, which blocks thread-per-core designs.

Evidence (origin/main @ d4b219507)

Scope

  • Apply stack size / priority from ThreadAttr.
  • Implement affinity on Linux (sched_setaffinity) and Windows; document macOS (affinity tags only).
  • Implement Semaphore.getValue.

Acceptance criteria

  • Stack size verified via pthread_attr_getstacksize in a test.
  • Affinity round-trips on Linux.

Depends on: #802 Part of #814.

8 days ago

Semaphore slice pushed to origin/main as 4c623eb. getValue now returns the atomic permit count with acquire ordering, values outside the signed API range report SemaphoreOverflow, post reports u32 overflow instead of silently succeeding, and tryWait retries weak-CAS misses instead of spuriously returning false. BinarySemaphore is now exported by the public threading facade and the documented API matches the implementation. Guarded WASI semaphore suite: 5/5 passed at 197 MB; full threading module compile check passed. The ThreadAttr and platform-affinity acceptance work remains open.

8 days ago

ThreadAttr stack-size slice pushed as 96e154d. Thread.spawn now routes through spawnWithAttr, the caller allocator is no longer discarded, and validated stack_size reaches std.Thread.SpawnConfig. Values below 16 KiB fail with StackTooSmall. Focused WASI mapping tests passed (1/1 in thread.zig and 1/1 through the public facade, peaks 178/185 MB); the full native thread module compile check passed. Priority application and platform affinity remain open; the OS-level stack-size round-trip acceptance still needs a runnable native test host.

8 days ago

Linux-affinity checkpoint pushed as bfe0d9e20 (feat(threading): add Linux affinity support). setAffinity/getAffinity now round-trip the current Linux thread through sched_setaffinity(0, …) / sched_getaffinity(0), reject bits beyond the native mask, map unsupported platforms to the real OperationNotSupported error, and are exported by the public threading facade. A Linux-only test saves the permitted cpuset, pins to one permitted CPU, verifies the observed mask, and restores the original set. Verification on this macOS host: native threading 22 passed / 1 Linux-only skipped at 168 MB peak; the Linux test artifact cross-compiles for x86_64-linux; scoped Pickier and diff checks pass. Docker exists but its daemon is not running, so I am not claiming a local Linux runtime pass. #803 remains open for that run, Windows affinity, priority application, and OS-level stack-size round-trip.

8 days ago

Progress landed on origin/main in 4e4ec5d (feat(threading): support Windows processor groups).\n\nImplemented:\n- Windows current-thread affinity through GetThreadGroupAffinity and SetThreadGroupAffinity.\n- Lossless mapping between CpuSet words and Windows processor groups.\n- Explicit InvalidCpuSet rejection for empty masks, multi-group masks that the selected Win32 API cannot represent, and out-of-range groups.\n- Platform-independent conversion and rejection tests, plus a Windows-gated runtime round-trip test.\n- Public-facade coverage for unsupported platforms and updated implementation-status documentation.\n\nVerification:\n- Native threading suite: 25/27 passed, with only the Linux- and Windows-only runtime tests skipped on macOS; guarded peak 168 MB.\n- x86_64-windows scheduler test artifact cross-compiled successfully.\n- x86_64-linux scheduler regression artifact cross-compiled successfully.\n- Scoped Pickier check passed.\n- Exactly 3 files changed.\n\nThis does not claim a live Windows runtime pass; #803 remains open for that, priority application, macOS affinity-tag behavior/documentation, and OS-level stack-size verification.

8 days ago

Stack-size acceptance progress landed on origin/main in b5c1962 (test(threading): verify applied pthread stack size).\n\nThe new child-thread test inspects the actual pthread stack after spawnWithAttr:\n- Linux uses pthread_getattr_np followed by pthread_attr_getstacksize, matching the issue acceptance criterion.\n- macOS uses pthread_get_stacksize_np.\n- The assertion verifies that the OS granted at least the requested 512 KiB while remaining below Zig's 16 MiB default, proving the custom stack reached the child without assuming undocumented platform rounding. On this Apple Silicon host, pthread reported 536,576 bytes for a 524,288-byte request.\n\nVerification:\n- Native threading suite: 26/28 passed, with only Linux/Windows affinity runtime tests skipped; guarded peak 161 MB.\n- pthread-backed x86_64-linux thread tests cross-compiled successfully with libc.\n- x86_64-windows thread regression target cross-compiled successfully.\n- Scoped Pickier and diff checks passed.\n- Exactly 3 files changed.\n\nThis is a live macOS stack-size pass and a compile-checked Linux pthread path; a live Linux execution is still explicitly pending. #803 remains open for that, live Windows affinity, priority application, and macOS affinity-tag work.

8 days ago

macOS affinity-tag support landed on origin/main in f88e9c1 (feat(threading): expose macOS affinity tags).

Implemented:

  • Added explicit current-thread setAffinityTag/getAffinityTag APIs using the Mach THREAD_AFFINITY_POLICY ABI.
  • Kept advisory tags separate from hard CpuSet masks: equal non-zero tags are only scheduler hints for sharing an L2 cache and do not pin a thread to a CPU.
  • Deallocated the mach_thread_self port right on every path.
  • Mapped XNU KERN_NOT_SUPPORTED (46) to OperationNotSupported rather than claiming the hint was applied.
  • Exported the APIs through the public threading facade and documented the hardware-dependent behavior.

Verification:

  • Native threading suite: 41/44 passed, with only platform-gated skips; guarded peak 152 MB.
  • This Apple Silicon host returned KERN_NOT_SUPPORTED from both tag operations, and the live test verifies that exact result. XNU gates this policy through thread_affinity_is_supported: https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/thread_policy.c
  • Complete threading graphs cross-compiled for x86_64-linux and x86_64-windows.
  • Scoped Pickier and diff checks passed.
  • Zig format inspection showed only the two known pre-existing builtin migrations outside this slice.
  • Exactly 3 files changed.

#803 remains open for priority application and live Linux affinity/stack plus live Windows affinity validation.

8 days ago

Priority application landed directly on origin/main in 9cbd77b (feat(threading): apply thread priorities).

Implemented:

  • ThreadAttr.priority is now optional, so default spawning does not silently change scheduler state.
  • Values are validated in the inclusive abstract 0-100 range and mapped to Linux nice levels, Win32 thread priorities, or macOS QoS classes.
  • spawnWithAttr applies priority inside the child before user code begins.
  • A futex startup handshake reports InvalidPriority, PermissionDenied, OperationNotSupported, or SchedParamFailed synchronously to the spawning thread; no spin loop and no false success.
  • The handshake keeps caller-owned startup data alive until the child explicitly releases it.
  • Added native priority-before-user-code and invalid-priority regressions plus platform-independent mapping checks.

Verification:

  • Final native threading suite: 44/47 passed with only platform-gated skips; guarded peak 168 MB.
  • The live macOS worker observed abstract priority 25 before entering user code.
  • Complete x86_64-linux and x86_64-windows threading graphs cross-compiled successfully.
  • Scoped Pickier and staged diff checks passed.
  • Formatter inspection showed only the known pre-existing builtin migrations outside this slice.
  • Exactly 3 files changed.

#803 remains open only for live Linux affinity/priority/stack execution and live Windows affinity/priority execution.

Sign in to comment on this issue.