mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added the _exit() system call.
exit() will not call _exit() yet, we need support for wait() in the shell.
This commit is contained in:
parent
09b1252821
commit
cfd7648ca9
8 changed files with 136 additions and 10 deletions
|
@ -45,9 +45,8 @@ typedef int div_t, ldiv_t, lldiv_t;
|
|||
|
||||
/* TODO: WEXITSTATUS, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED is missing here */
|
||||
|
||||
/* TODO: _Exit(int) is missing here */
|
||||
|
||||
void exit(int);
|
||||
void _Exit(int status);
|
||||
void free(void*);
|
||||
void* malloc(size_t);
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ char* crypt(const char*, const char*);
|
|||
char* ctermid(char*);
|
||||
int dup(int);
|
||||
int dup2(int, int);
|
||||
void _exit(int);
|
||||
void encrypt(char [64], int);
|
||||
int execl(const char*, const char*, ...);
|
||||
int execle(const char*, const char*, ...);
|
||||
|
@ -163,6 +162,7 @@ extern char* optarg;
|
|||
extern int opterr, optind, optopt;
|
||||
#endif
|
||||
|
||||
void _exit(int);
|
||||
pid_t fork(void);
|
||||
pid_t getpid(void);
|
||||
pid_t getppid(void);
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace Maxsi
|
|||
{
|
||||
namespace Process
|
||||
{
|
||||
DEFN_SYSCALL1_VOID(SysExit, 1, int);
|
||||
DEFN_SYSCALL3(int, SysExecute, 10, const char*, int, const char**);
|
||||
DEFN_SYSCALL0_VOID(SysPrintPathFiles, 11);
|
||||
DEFN_SYSCALL0(pid_t, SysFork, 12);
|
||||
|
@ -66,16 +67,21 @@ namespace Maxsi
|
|||
|
||||
extern "C" void abort() { return Abort(); }
|
||||
|
||||
void Exit(int code)
|
||||
extern "C" void _exit(int status)
|
||||
{
|
||||
SysExit(status);
|
||||
}
|
||||
|
||||
DUAL_FUNCTION(void, exit, Exit, (int status))
|
||||
{
|
||||
// TODO: Once wait() works and is used in the shell, call _exit!
|
||||
//_exit(status);
|
||||
const char* sh = "sh";
|
||||
const char* argv[] = { sh };
|
||||
Execute("sh", 1, argv);
|
||||
while(true);
|
||||
}
|
||||
|
||||
extern "C" void exit(int code) { return Exit(code); }
|
||||
|
||||
DUAL_FUNCTION(pid_t, fork, Fork, ())
|
||||
{
|
||||
return SysFork();
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <libmaxsi/sortedlist.h>
|
||||
#include "thread.h"
|
||||
#include "process.h"
|
||||
#include "scheduler.h"
|
||||
#include "memorymanagement.h"
|
||||
#include "initrd.h"
|
||||
#include "elf.h"
|
||||
|
@ -345,12 +346,94 @@ namespace Sortix
|
|||
pidlist->Remove(index);
|
||||
}
|
||||
|
||||
void SysExit(int status)
|
||||
{
|
||||
// Status codes can only contain 8 bits according to ISO C and POSIX.
|
||||
status %= 256;
|
||||
|
||||
Process* process = CurrentProcess();
|
||||
Process* init = Scheduler::GetInitProcess();
|
||||
|
||||
if ( process->pid == 0 ) { Panic("System idle process exited"); }
|
||||
|
||||
// If the init process terminated successfully, time to halt.
|
||||
if ( process == init )
|
||||
{
|
||||
switch ( status )
|
||||
{
|
||||
case 0: CPU::ShutDown();
|
||||
case 1: CPU::Reboot();
|
||||
default: PanicF("The init process exited abnormally with status code %u\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
// Take care of the orphans, so give them to init.
|
||||
while ( process->firstchild )
|
||||
{
|
||||
Process* orphan = process->firstchild;
|
||||
process->firstchild = orphan->nextsibling;
|
||||
if ( process->firstchild ) { process->firstchild->prevsibling = NULL; }
|
||||
orphan->parent = init;
|
||||
orphan->prevsibling = NULL;
|
||||
orphan->nextsibling = init->firstchild;
|
||||
if ( orphan->nextsibling ) { orphan->nextsibling->prevsibling = orphan; }
|
||||
init->firstchild = orphan;
|
||||
}
|
||||
|
||||
// Remove the current process from the family tree.
|
||||
if ( !process->prevsibling )
|
||||
{
|
||||
process->parent->firstchild = process->nextsibling;
|
||||
}
|
||||
else
|
||||
{
|
||||
process->prevsibling->nextsibling = process->nextsibling;
|
||||
}
|
||||
|
||||
if ( process->nextsibling )
|
||||
{
|
||||
process->nextsibling->prevsibling = process->prevsibling;
|
||||
}
|
||||
|
||||
// TODO: Close all the file descriptors!
|
||||
|
||||
// Make all threads belonging to process unrunnable.
|
||||
for ( Thread* t = process->firstthread; t; t = t->nextsibling )
|
||||
{
|
||||
Scheduler::EarlyWakeUp(t);
|
||||
Scheduler::SetThreadState(t, Thread::State::NONE);
|
||||
}
|
||||
|
||||
// Delete the threads.
|
||||
while ( process->firstthread )
|
||||
{
|
||||
Thread* todelete = process->firstthread;
|
||||
process->firstthread = process->firstthread->nextsibling;
|
||||
delete todelete;
|
||||
}
|
||||
|
||||
// Now clean up the address space.
|
||||
process->ResetAddressSpace();
|
||||
|
||||
// TODO: Actually delete the address space. This is a small memory leak
|
||||
// of a couple pages.
|
||||
|
||||
// TODO: Zombification!
|
||||
delete process;
|
||||
|
||||
// And so, the process had vanished from existence. But as fate would
|
||||
// have it, soon a replacement took its place.
|
||||
Scheduler::ProcessTerminated(Syscall::InterruptRegs());
|
||||
Syscall::AsIs();
|
||||
}
|
||||
|
||||
void Process::Init()
|
||||
{
|
||||
Syscall::Register(SYSCALL_EXEC, (void*) SysExecute);
|
||||
Syscall::Register(SYSCALL_FORK, (void*) SysFork);
|
||||
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
|
||||
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
|
||||
Syscall::Register(SYSCALL_EXIT, (void*) SysExit);
|
||||
|
||||
nextpidtoallocate = 0;
|
||||
|
||||
|
|
|
@ -132,6 +132,12 @@ namespace Sortix
|
|||
LogEndContextSwitch(currentthread, regs);
|
||||
}
|
||||
|
||||
void ProcessTerminated(CPU::InterruptRegisters* regs)
|
||||
{
|
||||
currentthread = dummythread;
|
||||
Switch(regs);
|
||||
}
|
||||
|
||||
const bool DEBUG_BEGINCTXSWITCH = false;
|
||||
const bool DEBUG_CTXSWITCH = false;
|
||||
const bool DEBUG_ENDCTXSWITCH = false;
|
||||
|
@ -240,6 +246,32 @@ namespace Sortix
|
|||
}
|
||||
}
|
||||
|
||||
void EarlyWakeUp(Thread* thread)
|
||||
{
|
||||
uintmax_t now = Time::MicrosecondsSinceBoot();
|
||||
if ( thread->sleepuntil < now ) { return; }
|
||||
thread->sleepuntil = now;
|
||||
|
||||
SetThreadState(thread, Thread::State::RUNNABLE);
|
||||
|
||||
if ( firstsleepingthread == thread )
|
||||
{
|
||||
firstsleepingthread = thread->nextsleepingthread;
|
||||
thread->nextsleepingthread = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( Thread* tmp = firstsleepingthread; tmp->nextsleepingthread != NULL; tmp = tmp->nextsleepingthread )
|
||||
{
|
||||
if ( tmp->nextsleepingthread == thread )
|
||||
{
|
||||
tmp->nextsleepingthread = thread->nextsleepingthread;
|
||||
thread->nextsleepingthread = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WakeSleeping()
|
||||
{
|
||||
uintmax_t now = Time::MicrosecondsSinceBoot();
|
||||
|
@ -247,7 +279,9 @@ namespace Sortix
|
|||
while ( firstsleepingthread && firstsleepingthread->sleepuntil < now )
|
||||
{
|
||||
SetThreadState(firstsleepingthread, Thread::State::RUNNABLE);
|
||||
firstsleepingthread = firstsleepingthread->nextsleepingthread;
|
||||
Thread* next = firstsleepingthread->nextsleepingthread;
|
||||
firstsleepingthread->nextsleepingthread = NULL;
|
||||
firstsleepingthread = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Sortix
|
|||
void Init();
|
||||
void MainLoop() SORTIX_NORETURN;
|
||||
void Switch(CPU::InterruptRegisters* regs);
|
||||
void ProcessTerminated(CPU::InterruptRegisters* regs);
|
||||
void SetIdleThread(Thread* thread);
|
||||
void SetDummyThreadOwner(Process* process);
|
||||
void SetInitProcess(Process* init);
|
||||
|
@ -42,6 +43,7 @@ namespace Sortix
|
|||
void SetThreadState(Thread* thread, Thread::State state);
|
||||
Thread::State GetThreadState(Thread* thread);
|
||||
void PutThreadToSleep(Thread* thread, uintmax_t usecs);
|
||||
void EarlyWakeUp(Thread* thread);
|
||||
|
||||
void SigIntHack();
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@ namespace Sortix
|
|||
prevsibling = NULL;
|
||||
nextsibling = NULL;
|
||||
sleepuntil = 0;
|
||||
nextsleepingthread = 0;
|
||||
schedulerlist = NULL;
|
||||
nextsleepingthread = NULL;
|
||||
schedulerlistprev = NULL;
|
||||
schedulerlistnext = NULL;
|
||||
state = NONE;
|
||||
|
@ -60,11 +59,15 @@ namespace Sortix
|
|||
ready = false;
|
||||
stackpos = forkfrom->stackpos;
|
||||
stacksize = forkfrom->stacksize;
|
||||
nextsleepingthread = NULL;
|
||||
schedulerlistprev = NULL;
|
||||
schedulerlistnext = NULL;
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
ASSERT(CurrentProcess() == process);
|
||||
ASSERT(nextsleepingthread == NULL);
|
||||
|
||||
Memory::UnmapRangeUser(stackpos, stacksize);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ namespace Sortix
|
|||
// These are some things used internally by the scheduler and should not be
|
||||
// touched by anything but it. Consider it private.
|
||||
public:
|
||||
Thread** schedulerlist;
|
||||
Thread* schedulerlistprev;
|
||||
Thread* schedulerlistnext;
|
||||
State state;
|
||||
|
|
Loading…
Reference in a new issue