D523 - The thread affinity setter, and the one beside it that stays unimplemented
guest-observed - 2026-09-03 (arities from the arguments a run passes; six samples after)
Two functions, called 94 times between them, both answering a placeholder. One is now implemented and one deliberately is not, and the difference between them is the whole point of writing this down.
The arities came from the run, not from a header
Neither is declared anywhere in orbistoun, and neither is in the
POSIX crate, so there was no in-project arity to cite. The run report
prints the arguments an unimplemented call received, which is how D516
fixed sceKernelCreateEqueue at two:
scePthreadSetaffinity arg0 = 0x1d1d9000960 arg1 = 0x1ffb (and 0x1 on another call)
arg2.. address-shaped leftovers
scePthreadGetschedparam arg0 = 0x1d1d4b785e0
arg1 = 0x6000007fc88c -> stack arg2 = 0x6000007fc888 -> stack
arg3 = 0x63a6d, arg4, arg5 leftovers
Setaffinity takes a subject and a small bitmask -
arity 2, the same shape as
scePthreadAttrSetaffinity, which orbistoun already declares
at two. Getschedparam takes a subject and two
writable stack addresses four bytes apart - arity 3, two
four-byte out-parameters, with the registers after them holding
leftovers.
scePthreadSetaffinity
is accepted, and the bargain is the attribute form's own
pthread_attr_setaffinity already states it: which host
core a guest thread runs on is the host scheduler's to decide, and
orbistoun does not pin guest threads. That is a cited convention rather
than a new judgement.
The difference from the attribute form is real and is stated
rather than glossed. The attribute form owns a block, so it can
hand back what a caller set. This one has nowhere to put the mask, so a
guest that set an affinity and read it back would not get it. Nothing
observed does - the 62 calls never read one back, and there is no
scePthreadGetaffinity in the import table - but the moment
something does, this needs a per-thread record and not a wider
Ok.
Answering Ok rather than the placeholder is the point: a
caller testing a scheduling call against zero reads
0x7fff_0001 as "the affinity was refused", which
is a lie in the direction that stops a guest. Nothing here claims the
mask was applied; a setter's contract is that the request was taken.
scePthreadGetschedparam
stays unimplemented, on purpose
Its arity and its two out-parameters are established. What it should
write is not. Orbistoun keeps no per-thread scheduling
record, so a policy and a priority handed back would be
invented - and unlike sceVideoOutIsFlipPending, where the
answer followed from a model this project had already written down
(D516), there is no model here to derive one from.
The attribute form can answer because it stores what a caller set. The thread form has nothing to answer from. That is the whole difference, and it is why one of these two is code and the other is a knowledge entry saying why it is not.
Recorded in the knowledge file with the reason, so the next reader finds the decision rather than the gap.
The cost: the call count is no longer exact
Before, three runs gave 415,415 calls every time. After, six runs give 415,355 to 415,357.
415355 415355 415356 415356 415356 415357
Distinct imports stay at 181 in all six, and the fault is
identical - read of 0xa0 at 0x400001389269 - so
the FURTHER/BACK verdict, which keys on
distinct imports, is unaffected. The raw call count is now +/-2.
The likely cause is that the guest creates 32 threads and a scheduling call it now sees succeed changes how long something spins. Stated as likely, because it has not been measured - what has been measured is which numbers moved and which did not, across six samples.
D488 once claimed an oscillation "does not move the verdict" and was wrong because the distinct count moved with it (D519). This time the distinct count was checked, six times, and it did not.
And the guest reached something new
sceKernelAddUserEventEdge, two calls, which no previous
run has ever made. Small, and the kind of thing that only shows up
because the stub above it stopped answering an error.