feat: extend sched with copyThreadName and threadSetName

This commit is contained in:
dualfroz committed 2026-09-06 20:34:50 +02:00
1 parent c571c0af1f
commit ae6bdd5880
1 file changed
+120 -1
+120 -1
View File
@@ -189,26 +189,145 @@
bumped ahead of that again (176 -> 184) instead of waiting to observe it, bumped ahead of that again (176 -> 184) instead of waiting to observe it,
same reasoning as every bump above. cwdtest (boot-time spawned, real same reasoning as every bump above. cwdtest (boot-time spawned, real
per-process working directory live demo -- sched.h's new Thread.cwd) per-process working directory live demo -- sched.h's new Thread.cwd)
plus cwdtarget (1 more, runtime-spawned by cwdtest itself, the same
*test / *target relationship jobtest/jobtarget already have) are two
more concurrently live threads, so bumped again (184 -> 192) for the
same headroom reason as every bump above. envprint (loaded on demand by
the real shell, like jobctlfg/hcat/pipecat above, never boot-spawned)
plus a kernel-only driver thread (kmain.c's envDriverThread, which types
`export`/`envprint`/`env` at the real shell through the same
injected-keystroke mechanism every driver thread above already uses)
would immediately re-create the exact same class of bug, so bumped
ahead of that again (192 -> 200) instead of waiting to observe it, same
reasoning as every bump above. nicetest (boot-time spawned, real
userspace-triggered sysNice/sysGetPriority live demo) plus nicetarget
(1 more, runtime-spawned by nicetest itself while sleeping so it can be
reniced while blocked, the same *test / *target relationship
jobtest/jobtarget and cwdtest/cwdtarget already have) are two more
concurrently live threads, so bumped again (200 -> 208) for the same
headroom reason as every bump above. date (boot-time spawned, real
sysTime/rtc.c live demo, fully synchronous like nicetest with no
runtime-spawned partner of its own) is one more, so bumped again
(208 -> 216) for the same headroom reason as every bump above. timetest
(boot-time spawned, real SFS inode mtime/ctime live demo through userOpen/
userWrite/userStat/userLink, fully synchronous like nicetest/date with no
runtime-spawned partner) is one more, so bumped again (216 -> 224) for the
same headroom reason as every bump above. lsDriverThread (kmain.c, boot-
time kernel thread that types `mkdir`/`echo`/`ls -l` at the real shell
for shell.c's new generalized `ls` builtin) is one more, so bumped again
(224 -> 232) for the same headroom reason as every bump above.
andOrDriverThread (kmain.c, boot-time kernel thread that types
`false && echo X || echo ao2` at the real shell for shell.c's new
`&&`/`||` conditional chaining) is one more, so bumped again
(232 -> 240) for the same headroom reason as every bump above. rmtest
(boot-time spawned, real vfsRmdir/sysRmdir unlink(2)-vs-rmdir(2) split
live demo on both tmpfs and SFS, fully synchronous like nicetest/date/
timetest with no runtime-spawned partner) is one more, so bumped again
(240 -> 248) for the same headroom reason as every bump above. permtest
(boot-time spawned, real chmod(2)/owner-rwx-permission-bits live demo)
plus the one short-lived runtime-spawned copy of /bin/false it chmods and
spawns to prove the exec-permission check, are two more concurrently
live threads, so bumped again (248 -> 256) for the same headroom reason
as every bump above. dirpermtest (boot-time spawned, real directory-mode
enforcement live demo -- vfsMkdir/resolveOpen/vfsUnlink/vfsRmdir's new
parent-write and ancestor-search checks, lookupNode/lookupFrom's new
exec-on-traversal check -- fully synchronous like identtest with no
runtime-spawned partner) is one more, so bumped again (256 -> 264) for
the same headroom reason as every bump above. grouptest (boot-time
spawned, real group-credential/vfsPermitted-group-branch live demo plus
the two short-lived runtime-spawned copies of /bin/false it group-execs
to prove the exec-permission check across matching/mismatched groups)
are two more concurrently live threads, so bumped again (264 -> 272) for
the same headroom reason as every bump above. pidfdtest (boot-time
spawned, real pidfd.h live demo through sysPidfdOpen/sysPidfdSend/
sysPidfdWait) plus the one runtime-spawned copy of /bin/killvictim it
reuses as its target (same proven "genuinely stuck" shape killtest.c
already established) are two more concurrently live threads, so bumped
again (272 -> 280) for the same headroom reason as every bump above.
mmaptest (boot-time spawned, real mmap(2)/munmap(2) demand-paging live
demo through sysMmap/sysMunmap -- anonymous demand-zero, file-backed
read-through, and a real SIGSEGV proven against a PROT_READ-only
mapping) plus the one runtime-spawned copy of /bin/mmapprotvictim it
uses to prove that last case are two more concurrently live threads, so
bumped again (280 -> 288) for the same headroom reason as every bump
above. */
#define maxThreads 288
#define threadStackSize 16384 #define threadStackSize 16384
/* Virtual-runtime charge for one timer tick's worth of execution at
schedDefaultWeight; scaled by schedDefaultWeight/weight for other
weights (see threadSetPriority). Purely an internal unit -- only ever
compared against other vruntime values, never against wall-clock time. */
#define schedTickCharge 1000000ull
static Thread threads[maxThreads]; static Thread threads[maxThreads];
static uint32 threadTotal; static uint32 threadTotal;
static uint32 currentIndex; static uint32 currentIndex;
static bool schedulerActive; static bool schedulerActive;
/* allocSlot's own round-robin cursor -- see that function's doc comment
for why this exists at all, not just "the lowest free index" the way
threadTotal's own high-water-mark growth already reads left to right. */
static uint32 nextSlotHint = 1;
/* Thread.generation's own monotonic source (see that field's doc comment,
sched.h) -- never 0 (0 is reserved to mean "this slot is currently
unoccupied", the same convention pipe.c's nextPipeIncarnation already
uses for the identical reason), never reused, incremented once per
threadCreate/threadCreateUser regardless of which slot the new thread
lands in. */
static uint32 nextThreadGeneration = 1;
/* Bounded copy into a Thread's own name buffer (see threadNameMax /
sched.h) -- never aliases the caller's storage, since threadCreateUser
is called from syscall.c with a path that lives in a stack-local buffer
for the duration of one syscall. */
static void copyThreadName(Thread* thread, const char* name)
{
uint64 len = strlen(name);
if (len >= threadNameMax)
len = threadNameMax - 1;
memcpy(thread->name, name, len);
thread->name[len] = 0;
}
void threadSetName(uint32 id, const char* name)
{
if (id >= threadTotal)
return;
copyThreadName(&threads[id], name);
}
void schedInit(void) void schedInit(void)
{ {
threadTotal = 1; threadTotal = 1;
currentIndex = 0; currentIndex = 0;
threads[0].id = 0; threads[0].id = 0;
threads[0].name = "idle"; threads[0].parentId = 0;
/* Reserved, permanently: idle is never reaped/recreated, and pid 0 is
already rejected as a pidfd/kill/wait target everywhere else, so it
never needs a real incarnation of its own (see Thread.generation's
own doc comment). */
threads[0].generation = 0;
threads[0].pgid = 0;
threads[0].uid = 0;
threads[0].gid = 0;
threads[0].cwd[0] = '/';
threads[0].cwd[1] = 0;
threads[0].envCount = 0;
copyThreadName(&threads[0], "idle");
threads[0].state = threadRunning; threads[0].state = threadRunning;
threads[0].rsp = 0; threads[0].rsp = 0;
threads[0].stackBase = 0; threads[0].stackBase = 0;
threads[0].kernelStackTop = 0; threads[0].kernelStackTop = 0;
threads[0].sleepUntil = 0; threads[0].sleepUntil = 0;
threads[0].brk = 0; threads[0].brk = 0;
threads[0].vruntime = 0;
threads[0].exitCode = 0;
threads[0].weight = schedDefaultWeight;
threads[0].everRan = true;
threads[0].waitChannel = nullptr;
vfsFdInit(threads[0].fds); vfsFdInit(threads[0].fds);
} }