mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
kernel: exit syscall
This commit is contained in:
@@ -12,6 +12,7 @@ extern syscall_fstat
|
|||||||
extern syscall_fstatat
|
extern syscall_fstatat
|
||||||
extern syscall_fork
|
extern syscall_fork
|
||||||
extern syscall_execve
|
extern syscall_execve
|
||||||
|
extern syscall_exit
|
||||||
syscalltab:
|
syscalltab:
|
||||||
dq syscall_print
|
dq syscall_print
|
||||||
dq syscall_mmap
|
dq syscall_mmap
|
||||||
@@ -26,7 +27,8 @@ dq syscall_fstat
|
|||||||
dq syscall_fstatat
|
dq syscall_fstatat
|
||||||
dq syscall_fork
|
dq syscall_fork
|
||||||
dq syscall_execve
|
dq syscall_execve
|
||||||
syscallcount equ 13
|
dq syscall_exit
|
||||||
|
syscallcount equ 14
|
||||||
section .text
|
section .text
|
||||||
global arch_syscall_entry
|
global arch_syscall_entry
|
||||||
; on entry:
|
; on entry:
|
||||||
|
|||||||
@@ -5,12 +5,16 @@
|
|||||||
#include <kernel/vmm.h>
|
#include <kernel/vmm.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
#define SCHED_THREAD_FLAGS_QUEUED 1
|
#define SCHED_THREAD_FLAGS_QUEUED 1
|
||||||
#define SCHED_THREAD_FLAGS_RUNNING 2
|
#define SCHED_THREAD_FLAGS_RUNNING 2
|
||||||
#define SCHED_THREAD_FLAGS_SLEEP 4
|
#define SCHED_THREAD_FLAGS_SLEEP 4
|
||||||
#define SCHED_THREAD_FLAGS_INTERRUPTIBLE 8
|
#define SCHED_THREAD_FLAGS_INTERRUPTIBLE 8
|
||||||
|
|
||||||
|
#define SCHED_PROC_STATE_NORMAL 0
|
||||||
|
#define SCHED_PROC_STATE_ZOMBIE 1
|
||||||
|
|
||||||
#define STACK_TOP (void *)0x0000800000000000
|
#define STACK_TOP (void *)0x0000800000000000
|
||||||
#define INTERP_BASE (void *)0x00000beef0000000
|
#define INTERP_BASE (void *)0x00000beef0000000
|
||||||
|
|
||||||
@@ -39,6 +43,8 @@ typedef struct thread_t {
|
|||||||
|
|
||||||
typedef struct proc_t {
|
typedef struct proc_t {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
int status;
|
||||||
|
int state;
|
||||||
struct proc_t *sibling;
|
struct proc_t *sibling;
|
||||||
struct proc_t *parent;
|
struct proc_t *parent;
|
||||||
struct proc_t *child;
|
struct proc_t *child;
|
||||||
@@ -56,13 +62,16 @@ typedef struct proc_t {
|
|||||||
vnode_t *cwd;
|
vnode_t *cwd;
|
||||||
vnode_t *root;
|
vnode_t *root;
|
||||||
spinlock_t nodeslock;
|
spinlock_t nodeslock;
|
||||||
|
semaphore_t waitsem;
|
||||||
} proc_t;
|
} proc_t;
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
|
||||||
|
extern proc_t *sched_initproc;
|
||||||
|
|
||||||
void sched_init();
|
void sched_init();
|
||||||
void sched_runinit();
|
void sched_runinit();
|
||||||
void sched_threadexit();
|
__attribute__((noreturn)) void sched_threadexit();
|
||||||
void sched_queue(thread_t *thread);
|
void sched_queue(thread_t *thread);
|
||||||
void sched_stopcurrentthread();
|
void sched_stopcurrentthread();
|
||||||
int sched_yield();
|
int sched_yield();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/elf.h>
|
#include <kernel/elf.h>
|
||||||
#include <kernel/file.h>
|
#include <kernel/file.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
#define QUANTUM_US 100000
|
#define QUANTUM_US 100000
|
||||||
#define SCHEDULER_STACK_SIZE 4096
|
#define SCHEDULER_STACK_SIZE 4096
|
||||||
@@ -26,6 +27,7 @@ static rqueue_t runqueue[RUNQUEUE_COUNT];
|
|||||||
static uint64_t runqueuebitmap;
|
static uint64_t runqueuebitmap;
|
||||||
static spinlock_t runqueuelock;
|
static spinlock_t runqueuelock;
|
||||||
|
|
||||||
|
proc_t *sched_initproc;
|
||||||
static pid_t currpid = 1;
|
static pid_t currpid = 1;
|
||||||
|
|
||||||
proc_t *sched_newproc() {
|
proc_t *sched_newproc() {
|
||||||
@@ -46,6 +48,7 @@ proc_t *sched_newproc() {
|
|||||||
proc->fdcount = 3;
|
proc->fdcount = 3;
|
||||||
proc->fdfirst = 3;
|
proc->fdfirst = 3;
|
||||||
SPINLOCK_INIT(proc->fdlock);
|
SPINLOCK_INIT(proc->fdlock);
|
||||||
|
SEMAPHORE_INIT(&proc->waitsem, 0);
|
||||||
|
|
||||||
proc->fd = alloc(sizeof(fd_t) * 3);
|
proc->fd = alloc(sizeof(fd_t) * 3);
|
||||||
if (proc->fd == NULL) {
|
if (proc->fd == NULL) {
|
||||||
@@ -189,31 +192,13 @@ __attribute__((noreturn)) void sched_stopcurrentthread() {
|
|||||||
switchthread(next);
|
switchthread(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_threadexit() {
|
__attribute__((noreturn)) void sched_threadexit() {
|
||||||
interrupt_set(false);
|
interrupt_set(false);
|
||||||
thread_t *thread = _cpu()->thread;
|
thread_t *thread = _cpu()->thread;
|
||||||
proc_t *proc = thread->proc;
|
proc_t *proc = thread->proc;
|
||||||
|
|
||||||
if (proc) {
|
if (proc)
|
||||||
spinlock_acquire(&proc->lock);
|
__atomic_fetch_sub(&currpid, 1, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
int toffset = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < proc->threadtablesize; ++i) {
|
|
||||||
if (proc->threads[i] == thread) {
|
|
||||||
toffset = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__assert(toffset != -1);
|
|
||||||
--proc->runningthreadcount;
|
|
||||||
|
|
||||||
if (proc->runningthreadcount == 0) {
|
|
||||||
// TODO prepare proc state to be left as a zombie
|
|
||||||
}
|
|
||||||
spinlock_release(&proc->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
_cpu()->thread = NULL;
|
_cpu()->thread = NULL;
|
||||||
|
|
||||||
@@ -373,6 +358,8 @@ void sched_runinit() {
|
|||||||
proc_t *proc = sched_newproc();
|
proc_t *proc = sched_newproc();
|
||||||
__assert(proc);
|
__assert(proc);
|
||||||
|
|
||||||
|
sched_initproc = proc;
|
||||||
|
|
||||||
vnode_t *initnode;
|
vnode_t *initnode;
|
||||||
__assert(vfs_open(vfsroot, "/usr/bin/bash", 0, &initnode) == 0);
|
__assert(vfs_open(vfsroot, "/usr/bin/bash", 0, &initnode) == 0);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include <kernel/syscalls.h>
|
||||||
|
#include <kernel/scheduler.h>
|
||||||
|
#include <kernel/file.h>
|
||||||
|
#include <kernel/vfs.h>
|
||||||
|
#include <logging.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
__attribute__((noreturn)) void syscall_exit(context_t *context, int status) {
|
||||||
|
thread_t *thread = _cpu()->thread;
|
||||||
|
proc_t *proc = thread->proc;
|
||||||
|
__assert(proc != sched_initproc);
|
||||||
|
|
||||||
|
// TODO stop other threads
|
||||||
|
|
||||||
|
for (int fd = 0; fd < proc->fdcount; ++fd)
|
||||||
|
fd_close(fd);
|
||||||
|
|
||||||
|
spinlock_acquire(&proc->lock);
|
||||||
|
|
||||||
|
VOP_RELEASE(proc->root);
|
||||||
|
VOP_RELEASE(proc->cwd);
|
||||||
|
|
||||||
|
proc->status = status;
|
||||||
|
proc->state = SCHED_PROC_STATE_ZOMBIE;
|
||||||
|
proc_t *lastchild = proc->child;
|
||||||
|
|
||||||
|
spinlock_acquire(&sched_initproc->lock);
|
||||||
|
|
||||||
|
bool haszombie = false;
|
||||||
|
|
||||||
|
while (lastchild && lastchild->sibling) {
|
||||||
|
if (lastchild->state == SCHED_PROC_STATE_ZOMBIE)
|
||||||
|
haszombie = true;
|
||||||
|
|
||||||
|
lastchild->parent = sched_initproc;
|
||||||
|
lastchild = lastchild->sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastchild) {
|
||||||
|
if (lastchild->sibling->state == SCHED_PROC_STATE_ZOMBIE)
|
||||||
|
haszombie = true;
|
||||||
|
|
||||||
|
lastchild->sibling = sched_initproc->child;
|
||||||
|
sched_initproc->child = proc->child;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_release(&sched_initproc->lock);
|
||||||
|
spinlock_release(&proc->lock);
|
||||||
|
|
||||||
|
semaphore_signal(&proc->parent->waitsem);
|
||||||
|
if (haszombie)
|
||||||
|
semaphore_signal(&sched_initproc->waitsem);
|
||||||
|
|
||||||
|
sched_threadexit();
|
||||||
|
}
|
||||||
@@ -133,10 +133,10 @@ index 0000000..e5b087a
|
|||||||
+
|
+
|
||||||
diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..e108341
|
index 0000000..f212b93
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||||
@@ -0,0 +1,190 @@
|
@@ -0,0 +1,189 @@
|
||||||
+#include <bits/ensure.h>
|
+#include <bits/ensure.h>
|
||||||
+#include <mlibc/debug.hpp>
|
+#include <mlibc/debug.hpp>
|
||||||
+#include <mlibc/all-sysdeps.hpp>
|
+#include <mlibc/all-sysdeps.hpp>
|
||||||
@@ -244,8 +244,7 @@ index 0000000..e108341
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ [[noreturn]] void sys_exit(int status) {
|
+ [[noreturn]] void sys_exit(int status) {
|
||||||
+ sys_libc_log("mlibc: program requested exit");
|
+ syscall(SYSCALL_EXIT, NULL, status);
|
||||||
+ sys_libc_panic();
|
|
||||||
+ __builtin_unreachable();
|
+ __builtin_unreachable();
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@@ -346,10 +345,10 @@ index 0000000..990eca0
|
|||||||
+#endif
|
+#endif
|
||||||
diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..e23be0d
|
index 0000000..8a8d77d
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||||
@@ -0,0 +1,36 @@
|
@@ -0,0 +1,37 @@
|
||||||
+#ifndef _SYSCALL_H_INCLUDE
|
+#ifndef _SYSCALL_H_INCLUDE
|
||||||
+#define _SYSCALL_H_INCLUDE
|
+#define _SYSCALL_H_INCLUDE
|
||||||
+
|
+
|
||||||
@@ -366,6 +365,7 @@ index 0000000..e23be0d
|
|||||||
+#define SYSCALL_FSTATAT 10
|
+#define SYSCALL_FSTATAT 10
|
||||||
+#define SYSCALL_FORK 11
|
+#define SYSCALL_FORK 11
|
||||||
+#define SYSCALL_EXECVE 12
|
+#define SYSCALL_EXECVE 12
|
||||||
|
+#define SYSCALL_EXIT 13
|
||||||
+
|
+
|
||||||
+#include <stddef.h>
|
+#include <stddef.h>
|
||||||
+#include <stdint.h>
|
+#include <stdint.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user