Repository navigation
Conversation
…addr getters pthread_attr_getscope and pthread_attr_setscope keep the contention scope, system by default as in FreeBSD's libthr, and accept only process and system scope. pthread_attr_getinheritsched and pthread_attr_getstackaddr report the attribute's fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Progress report (f145139 → 886fd8b)📈 System libraries: 84.78% (+0.02%, +4 implemented functions) ✅ 4 implemented
|
klosixgaming-arch
left a comment
There was a problem hiding this comment.
Clean, correct addition of the missing pthread_attr accessors. Each getter validates both the attr handle and the out-pointer (EINVAL otherwise), matching the existing pthread_attr_* style in this file, and pthread_attr_setscope correctly accepts only PTHREAD_SCOPE_SELF/PTHREAD_SCOPE_SYSTEM. The new _scope field defaults to PTHREAD_SCOPE_SYSTEM (2), the POSIX default. The PosixAttributes test covers the happy path, the EINVAL paths (null out-pointer, null attr), and scope validation (0 and 2 accepted, 1 rejected).
Written with AI assistance.
|
Closing: ccleste (PPSA59322) stops at |
|
Additional Windows validation of PR head Windows 11 Enterprise 26200, WinLibs r7 MinGW-w64 GCC 15.2.0, Release, BUILD_TESTING=ON. Full system-library build passed; existing An additional scope-query probe failed 5/5: create a thread with explicit system scope (2); set the destination attribute to process scope (0); query that thread with This is a limitation of combining the proposed new scope field with existing query paths, not a regression claim against main where that scope export is absent. For the POSIX query, FreeBSD 11 thr_attr.c copies the thread's attribute state into the destination. Its setters accept both scope values, and thr_create.c inherits scope when inherited scheduling is selected. These are source references, not measurements on PS5. Probe source, linked to the locally built unpatched libkernel/libc with the repository's Windows unwind setup ( #include "SceTypes.hpp"
#include <atomic>
#include <cstdio>
#include <thread>
extern "C" {
int APS5_VABI pthread_attr_init_nid_postfix(PthreadAttr*);
int APS5_VABI pthread_attr_destroy_nid_postfix(PthreadAttr*);
int APS5_VABI pthread_attr_setscope_nid_postfix(PthreadAttr*, int);
int APS5_VABI pthread_attr_getscope_nid_postfix(const PthreadAttr*, int*);
int APS5_VABI pthread_attr_setinheritsched_nid_postfix(PthreadAttr*, int);
int APS5_VABI pthread_create_nid_postfix(Pthread*, const PthreadAttr*, PthreadEntry, void*);
int APS5_VABI pthread_join_nid_postfix(Pthread, void**);
int APS5_VABI pthread_attr_get_np_nid_postfix(Pthread, PthreadAttr*);
int APS5_VABI scePthreadAttrGet(Pthread, PthreadAttr*);
}
static void* APS5_VABI Worker(void* argument) {
auto& release = *static_cast<std::atomic<bool>*>(argument);
while (!release.load()) std::this_thread::yield();
return nullptr;
}
int main() {
PthreadAttr created = nullptr;
PthreadAttr queried = nullptr;
if (pthread_attr_init_nid_postfix(&created) != 0 || pthread_attr_init_nid_postfix(&queried) != 0) return 10;
if (pthread_attr_setscope_nid_postfix(&created, 2) != 0 || pthread_attr_setinheritsched_nid_postfix(&created, 0) != 0) return 11;
std::atomic<bool> release{false};
Pthread thread = nullptr;
if (pthread_create_nid_postfix(&thread, &created, Worker, &release) != 0) return 12;
int posix = -1;
int sce = -1;
if (pthread_attr_setscope_nid_postfix(&queried, 0) != 0) return 13;
const int posixResult = pthread_attr_get_np_nid_postfix(thread, &queried);
const int posixRead = pthread_attr_getscope_nid_postfix(&queried, &posix);
if (pthread_attr_setscope_nid_postfix(&queried, 0) != 0) return 14;
const int sceResult = scePthreadAttrGet(thread, &queried);
const int sceRead = pthread_attr_getscope_nid_postfix(&queried, &sce);
release.store(true);
const int joined = pthread_join_nid_postfix(thread, nullptr);
pthread_attr_destroy_nid_postfix(&created);
pthread_attr_destroy_nid_postfix(&queried);
std::printf("expected=2 posix_query=%d posix_read=%d posix_scope=%d sce_query=%d sce_read=%d sce_scope=%d joined=%d\n", posixResult, posixRead, posix, sceResult, sceRead, sce, joined);
return posixResult == 0 && posixRead == 0 && posix == 2 && sceResult == 0 && sceRead == 0 && sce == 2 && joined == 0 ? 0 : 1;
}
In a separate local diagnostic change, I reset queried scope to system scope and explicitly throw on thread creation requesting process scope with explicit scheduling. Only system-scope threads are represented in that local model; inherited scheduling therefore inherits system scope. This does not implement process-scope scheduling or establish PS5 scope semantics. The expanded behavioral test checks non-null stack-address readback, null arguments, invalid scope values, stale destination scope replacement in both query paths, inherited scope, and the exact unsupported-process-scope exception with no worker creation or errno mutation. Full system libraries built; PPSA99902 reaches the missing scope import only with a stack of other local fixes/placeholders. It is not the title's next stop on unchanged main, so this is not a request to reopen under the first-stop rule. At the time of the original validation, no guest entry or gameplay had been reached. AI-assisted investigation and local changes: Codex. Follow-up (2026-10-10): integrating the attribute proposal plus the local scope-query correction into the broader diagnostic stack reached actual guest entry with |
|
@TheAggie
All three go on to @pushkarreddyy opened #3377 an hour ago with |
What
Four POSIX attribute functions were not exported:
pthread_attr_getscopeandpthread_attr_setscopekeep the contention scope. It is system scope by default, as in FreeBSD's libthr. Only process (0) and system (2) scope are accepted; anything else isEINVAL.pthread_attr_getinheritschedandpthread_attr_getstackaddrreport the attribute's existing fields.A null attribute or a null output pointer is
EINVAL. The scope is stored on the attribute (Pthread.hpp); it does not change how threads are created.ccleste (PPSA59322) imports these.
Test (
guest_pthread_attr): inheritsched reads its default and a set value; scope defaults to system, reads back process scope after a set, and rejects 1 without changing; stackaddr is null by default; null outputs and a null attribute returnEINVAL.Tested
Windows 11 Pro (26200), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release.
mainwith this PR and four other small PRs of mine merged together (SCHED_OTHER priority range, MAP_ALIGNED_SUPER, the compatible pad vibration mode, empty-PT_TLS stack-guard reads, pthread_attr scope/getters). It was run from the generatedCTestTestfile.cmakecommands because antivirus blocksctest.exeon this machine.tools/check_conventions.py --base origin/mainpasses on this branch alone.Not tested on Linux or macOS.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code