feat: extend kmain with listInit and listEmpty
This commit is contained in:
1 parent
21f2719413
commit
8101704cc3
2 files changed
+167
-1
No files matched your search
+106
-1
@@ -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
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user