feat: extend kmain with listInit and listEmpty

This commit is contained in:
dualfroz committed 2026-09-06 14:17:13 +02:00
1 parent 21f2719413
commit 8101704cc3
2 files changed
+167 -1

No files matched your search

+106 -1
View File
@@ -1960,8 +1960,113 @@ void kmain(uint32 magic, uint64 multibootInfo)
spawnUser("/bin/counter", "counter", 0x58000000, 0);
spawnUser("/bin/sbrktest", "sbrktest", 0x68000000, 0x64000000);
spawnUser("/bin/fileread", "fileread", 0x78000000, 0);
spawnUser("/bin/pipetest", "pipetest", 0x88000000, 0);
spawnUser("/bin/disktest", "disktest", 0x98000000, 0);
spawnUser("/bin/fstest", "fstest", 0xA8000000, 0);
spawnUser("/bin/linktest", "linktest", 0xB8000000, 0);
spawnUser("/bin/fifomaster", "fifomaster", 0x118000000, 0);
spawnUser("/bin/killtest", "killtest", 0x148000000, 0);
spawnUser("/bin/namedreader", "namedreader", 0x168000000, 0);
spawnUser("/bin/namedwriter", "namedwriter", 0x178000000, 0);
spawnUser("/bin/consolereader1", "consolereader1", 0x188000000, 0);
spawnUser("/bin/consolereader2", "consolereader2", 0x198000000, 0);
threadCreate("consoleInjector", consoleInjectorThread);
spawnUser("/bin/sigtest", "sigtest", 0x1A8000000, 0);
spawnUser("/bin/jobtest", "jobtest", 0x1D8000000, 0);
spawnUser("/bin/nesttest", "nesttest", 0x1F8000000, 0);
spawnUser("/bin/eintrtest", "eintrtest", 0x218000000, 0);
spawnUser("/bin/restarttest", "restarttest", 0x238000000, 0);
spawnUser("/bin/masktest", "masktest", 0x258000000, 0);
spawnUser("/bin/sigchldtest", "sigchldtest", 0x278000000, 0);
spawnUser("/bin/waitanytest", "waitanytest", 0x298000000, 0);
spawnUser("/bin/stopchldtest", "stopchldtest", 0x2C8000000, 0);
spawnUser("/bin/nodefertest", "nodefertest", 0x2E8000000, 0);
spawnUser("/bin/alarmtest", "alarmtest", 0x2F8000000, 0);
spawnUser("/bin/siginfotest", "siginfotest", 0x318000000, 0);
spawnUser("/bin/selfstoptest", "selfstoptest", 0x3F8000000, 0);
spawnUser("/bin/cwdtest", "cwdtest", 0x458000000, 0);
spawnUser("/bin/nicetest", "nicetest", 0x4A8000000, 0);
spawnUser("/bin/date", "date", 0x4B8000000, 0);
spawnUser("/bin/timetest", "timetest", 0x4D8000000, 0);
spawnUser("/bin/rmtest", "rmtest", 0x508000000, 0);
spawnUser("/bin/permtest", "permtest", 0x518000000, 0);
spawnUser("/bin/identtest", "identtest", 0x528000000, 0);
spawnUser("/bin/dirpermtest", "dirpermtest", 0x538000000, 0);
spawnUser("/bin/grouptest", "grouptest", 0x548000000, 0);
spawnUser("/bin/pidfdtest", "pidfdtest", 0x558000000, 0);
/* mmapprotvictim and mmapexecvictim are deliberately NOT spawned here
-- like killvictim (killtest's own runtime-spawned target, elsewhere
in this function), both are only ever loaded at runtime, by
mmaptest itself (userSpawn), never directly by kmain.c. */
spawnUser("/bin/mmaptest", "mmaptest", 0x568000000, 0);
spawnUser("/bin/polltest", "polltest", 0x378000000, 0);
pgroupfgPid = spawnUser("/bin/pgroupfg", "pgroupfg", 0x338000000, 0);
pgroupbgPid = spawnUser("/bin/pgroupbg", "pgroupbg", 0x348000000, 0);
if (pgroupfgPid != threadInvalidId) {
/* Real shell/tcsetpgrp behavior: whichever job was just launched in
the foreground claims the terminal explicitly -- pgroupbg is
deliberately left alone (its own default group, never named
here), the same way a background job never touches the
controlling terminal at all. */
keyboardSetForegroundPgid(pgroupfgPid);
}
if (pgroupfgPid != threadInvalidId && pgroupbgPid != threadInvalidId)
threadCreate("pgroupInjector", pgroupInjectorThread);
/* jobctlfg/jobctlbg are deliberately NOT spawned here -- unlike every
program above, they are only ever loaded on demand, at runtime, by
the real interactive shell (shellRun, threadCreate'd near the top of
this function) once jobctlDriverThread types their names at it. */
threadCreate("jobctlDriver", jobctlDriverThread);
/* pipesrc/pipesink are, like jobctlfg/jobctlbg just above, deliberately
NOT spawned here -- loaded on demand by the real shell once
pipelineDriverThread types "pipesrc | pipesink" at it. */
threadCreate("pipelineDriver", pipelineDriverThread);
/* redirwriter/redirreader are, like pipesrc/pipesink just above,
deliberately NOT spawned here -- loaded on demand by the real shell
once redirDriverThread types the redirected commands at it. */
threadCreate("redirDriver", redirDriverThread);
/* stderrwriter/stderrreader are, like redirwriter/redirreader just
above, deliberately NOT spawned here -- loaded on demand by the real
shell once stderrDriverThread types the stderr-redirected commands
at it. */
threadCreate("stderrDriver", stderrDriverThread);
/* herestest is, like stderrwriter/stderrreader just above, deliberately
NOT spawned here -- loaded on demand by the real shell once
hereDriverThread types the here-string command at it. */
threadCreate("hereDriver", hereDriverThread);
/* hcat/hsink are, like herestest just above, deliberately NOT spawned
here -- loaded on demand by the real shell once
hereStringPipelineDriverThread types the here-string-into-pipeline
command at it. */
threadCreate("hereStringPipelineDriver", hereStringPipelineDriverThread);
/* pipecat is, like hcat/hsink just above, deliberately NOT spawned here
-- loaded on demand by the real shell once
threeStagePipelineDriverThread types the three-stage pipeline
command at it (pipesrc/pipesink themselves are also on-demand-only,
unchanged since FALA 29). */
threadCreate("threeStagePipelineDriver", threeStagePipelineDriverThread);
/* envprint is, like pipecat just above, deliberately NOT spawned here
-- loaded on demand by the real shell once envDriverThread types
"export GREETING=frostbyte" then "envprint" at it. */
threadCreate("envDriver", envDriverThread);
/* globcat is, like envprint just above, deliberately NOT spawned here
-- loaded on demand by the real shell once globDriverThread types
"globcat /tmp/gd/ *.txt" at it (shell.c's new wildcard glob
expansion). */
threadCreate("globDriver", globDriverThread);
/* No new /bin binary here -- lsDriverThread only exercises shell.c's
existing mkdir/echo/ls builtins, never spawns anything. */
threadCreate("lsDriver", lsDriverThread);
/* false is, like globcat above, deliberately NOT spawned here --
loaded on demand by the real shell once andOrDriverThread types the
`&&`/`||`-chained command at it (shell.c's new conditional
chaining). */
threadCreate("andOrDriver", andOrDriverThread);
execDemoPid = spawnUser("/bin/proctest", "proctest", 0xF8000000, 0);
if (execDemoPid != threadInvalidId)
threadCreate("execReaper", execReaperThread);
kprintf("[sched] %u threads total (idle, shell, 2 workers, user programs)\n",
kprintf("[sched] %u threads total (idle, shell, 2 workers, priority verifier, user programs)\n",
threadCount());
kprintf("\n[boot] enabling interrupts, starting preemptive scheduler\n\n");
+61
View File
@@ -0,0 +1,61 @@
#include "list.h"
void listInit(ListNode* head)
{
head->next = head;
head->prev = head;
}
bool listEmpty(const ListNode* head)
{
return head->next == head;
}
void listInsertAfter(ListNode* pos, ListNode* newNode)
{
newNode->prev = pos;
newNode->next = pos->next;
pos->next->prev = newNode;
pos->next = newNode;
}
void listInsertBefore(ListNode* pos, ListNode* newNode)
{
listInsertAfter(pos->prev, newNode);
}
void listPushBack(ListNode* head, ListNode* newNode)
{
listInsertBefore(head, newNode);
}
void listPushFront(ListNode* head, ListNode* newNode)
{
listInsertAfter(head, newNode);
}
void listRemove(ListNode* node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
node->next = node;
node->prev = node;
}
usize listLen(const ListNode* head)
{
usize count = 0;
for (const ListNode* cursor = head->next; cursor != head; cursor = cursor->next)
count++;
return count;
}
ListNode* listFront(const ListNode* head)
{
return listEmpty(head) ? nullptr : head->next;
}
ListNode* listBack(const ListNode* head)
{
return listEmpty(head) ? nullptr : head->prev;
}