Conversation
Close the last narrow gap in the PSE51-oriented userspace surface. A portable libc that promises pthread_attr_t needs both the attribute accessors and a way to honor PTHREAD_EXPLICIT_SCHED without the SYS_THREAD_SETSCHEDPARAM race window; ship both in one branch. Library lives at include/mazu/pthread.h as a header-only set of static inline functions: pthread_attr_init / _destroy, _set/_get for detachstate, inheritsched, schedpolicy, schedparam, stacksize, stack. All entry points NULL-guard, validate inputs, and return positive errno (POSIX convention). pthread_attr_destroy stamps every field so use-after-destroy is debugger-visible. Stack accessors are constrained by the shared address-space model: the kernel assigns each thread slot a fixed VA band, so a caller-supplied stack cannot be honored. pthread_attr_setstack always returns ENOTSUP, and pthread_attr_setstacksize succeeds only for USER_STACK_SIZE; both signal the constraint up front instead of letting a portable caller observe a stack contract the kernel will not satisfy. pthread_attr_getstack / _getstacksize still round-trip the init-time defaults so feature probes work. Kernel ABI adds a dedicated syscall, SYS_THREAD_CREATE_EXPLICIT (slot 101), rather than repurposing SYS_THREAD_CREATE's a2 register. Reusing the original syscall risked misinterpreting garbage a2 from pre-existing callers who never cleared unused registers. The new syscall reads a (prio + 1) encoding from a2 (0 inherits; 1..CONFIG_SCHED_NPRIO sets explicit prio = a2 - 1; anything else returns EINVAL), enforces the same privilege bound as pthread_setschedparam (cannot raise above creator's base priority, EPERM otherwise), and shares its body with sys_thread_create_h via sys_thread_create_common(use_explicit_prio_abi). td_base_prio is snapshotted with __atomic_load_n(__ATOMIC_RELAXED) so a cross-hart setschedparam against the creator cannot make the EPERM gate disagree with the inherit-default fallback. pthread_attr_resolve_create_syscall and _resolve_prio_arg let a future pthread_create wrapper hand the attr straight to the right syscall. The prio resolver bounds-checks before the (u64) cast: a negative i32 cast to u64 plus 1 wraps to 0, which would have mimicked the inherit encoding and silently demoted an EXPLICIT_SCHED request from a caller who bypassed the setters. The resolver returns a sentinel above CONFIG_SCHED_NPRIO for any out-of-range value so the kernel's own bound check surfaces EINVAL. ENOTSUP joins the rest of the errno constants in include/mazu/errordef.h (value 95, matching the Linux EOPNOTSUPP numeric) with a matching error_code_str branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Close the last narrow gap in the PSE51-oriented userspace surface. A portable libc that promises pthread_attr_t needs both the attribute accessors and a way to honor PTHREAD_EXPLICIT_SCHED without the SYS_THREAD_SETSCHEDPARAM race window; ship both in one branch.
Library lives at include/mazu/pthread.h as a header-only set of static inline functions: pthread_attr_init / _destroy, _set/_get for detachstate, inheritsched, schedpolicy, schedparam, stacksize, stack. All entry points NULL-guard, validate inputs, and return positive errno (POSIX convention). pthread_attr_destroy stamps every field so use-after-destroy is debugger-visible.
Stack accessors are constrained by the shared address-space model: the kernel assigns each thread slot a fixed VA band, so a caller-supplied stack cannot be honored. pthread_attr_setstack always returns ENOTSUP, and pthread_attr_setstacksize succeeds only for USER_STACK_SIZE; both signal the constraint up front instead of letting a portable caller observe a stack contract the kernel will not satisfy. pthread_attr_getstack / _getstacksize still round-trip the init-time defaults so feature probes work.
Kernel ABI adds a dedicated syscall, SYS_THREAD_CREATE_EXPLICIT (slot 101), rather than repurposing SYS_THREAD_CREATE's a2 register. Reusing the original syscall risked misinterpreting garbage a2 from pre-existing callers who never cleared unused registers. The new syscall reads a (prio + 1) encoding from a2 (0 inherits; 1..CONFIG_SCHED_NPRIO sets explicit prio = a2 - 1; anything else returns EINVAL), enforces the same privilege bound as pthread_setschedparam (cannot raise above creator's base priority, EPERM otherwise), and shares its body with sys_thread_create_h via sys_thread_create_common(use_explicit_prio_abi). td_base_prio is snapshotted with __atomic_load_n(__ATOMIC_RELAXED) so a cross-hart setschedparam against the creator cannot make the EPERM gate disagree with the inherit-default fallback.
pthread_attr_resolve_create_syscall and _resolve_prio_arg let a future pthread_create wrapper hand the attr straight to the right syscall. The prio resolver bounds-checks before the (u64) cast: a negative i32 cast to u64 plus 1 wraps to 0, which would have mimicked the inherit encoding and silently demoted an EXPLICIT_SCHED request from a caller who bypassed the setters. The resolver returns a sentinel above CONFIG_SCHED_NPRIO for any out-of-range value so the kernel's own bound check surfaces EINVAL.
ENOTSUP joins the rest of the errno constants in
include/mazu/errordef.h (value 95, matching the Linux EOPNOTSUPP numeric) with a matching error_code_str branch.
Summary by cubic
Implements a header-only
pthread_attr_*library and addsSYS_THREAD_CREATE_EXPLICITto supportPTHREAD_EXPLICIT_SCHEDwithout the post-create race. This closes the last gap in the PSE51 userspace surface.New Features
pthread_attr_*atinclude/mazu/pthread.h(init/destroy; get/set for detachstate, inheritsched, schedpolicy, schedparam, stacksize, stack). All calls NULL-guarded and return positive errno.pthread_attr_setstackreturnsENOTSUP;pthread_attr_setstacksizeaccepts onlyUSER_STACK_SIZE. Getters round-trip defaults.SYS_THREAD_CREATE_EXPLICIT(slot 101): a2=0 inherits, 1..CONFIG_SCHED_NPRIOsets prio (a2−1), elseEINVAL;EPERMif above creator’s base. LegacySYS_THREAD_CREATEunchanged.ENOTSUP(95) and error string; updates docs (PSE51 matrix) and selftests for attrs and the new syscall.Migration
pthread_createwrapper, usepthread_attr_resolve_create_syscallandpthread_attr_resolve_prio_argto pick the syscall and a2 encoding.pthread_attr_setstackas unsupported.Written for commit 6b5ed23. Summary will update on new commits.