diff --git a/README.md b/README.md index 71167c8f..0d990c82 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Astral is a 64 bit operating system with its own kernel written in C for the x86 - SMP capable preemptible kernel - Networking (UDP, DHCP) - POSIX compatibility -- Ports: mlibc, X.org, gcc, bash, doom, quake, vim, nano and more +- Ports: X.org, fvwm3, gcc, bash, quake, vim and more - Filesystems: tmpfs, devfs, ext2 - Block devices: NVMe, virtio-block - Network devices: virtio-net @@ -18,6 +18,8 @@ Astral is a 64 bit operating system with its own kernel written in C for the x86 ## Current Goals - TCP +- Fat32 +- Disk Caching ## Building diff --git a/kernel-src/include/kernel/signal.h b/kernel-src/include/kernel/signal.h index df224093..a6465099 100644 --- a/kernel-src/include/kernel/signal.h +++ b/kernel-src/include/kernel/signal.h @@ -144,6 +144,12 @@ typedef struct { #define SIG_UNBLOCK 1 #define SIG_SETMASK 2 +#define SIG_ACTION_TERM 0 +#define SIG_ACTION_IGN 1 +#define SIG_ACTION_CORE 2 +#define SIG_ACTION_STOP 3 +#define SIG_ACTION_CONT 4 + struct proc_t; struct thread_t; void signal_action(struct proc_t *proc, int signal, sigaction_t *new, sigaction_t *old); @@ -153,5 +159,6 @@ void signal_signalproc(struct proc_t *proc, int signal); void signal_signalthread(struct thread_t *thread, int signal, bool urgent); void signal_pending(struct thread_t *, sigset_t *sigset); bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno); +extern int signal_defaultactions[NSIG]; #endif diff --git a/kernel-src/sys/scheduler.c b/kernel-src/sys/scheduler.c index 6942a91c..7cd12b52 100644 --- a/kernel-src/sys/scheduler.c +++ b/kernel-src/sys/scheduler.c @@ -429,7 +429,23 @@ static void yield(context_t *context) { thread_t *next = runqueuenext(sleeping ? 0x0fffffff : thread->priority); - if (sleeping && thread->shouldexit && (thread->flags & SCHED_THREAD_FLAGS_INTERRUPTIBLE)) { + bool gotsignal = false; + for (int i = 0; i < NSIG && thread->proc; ++i) { + void *action = thread->proc->signals.actions[i].address; + if (SIGNAL_GET(&thread->signals.urgent, i)) { + gotsignal = true; + break; + } + if (action == SIG_IGN || (action == SIG_DFL && signal_defaultactions[i] == SIG_ACTION_IGN) || SIGNAL_GET(&thread->signals.mask, i)) + continue; + + if (SIGNAL_GET(&thread->signals.pending, i) || SIGNAL_GET(&thread->proc->signals.pending, i)) { + gotsignal = true; + break; + } + } + + if (sleeping && (thread->shouldexit || gotsignal) && (thread->flags & SCHED_THREAD_FLAGS_INTERRUPTIBLE)) { sleeping = false; next = NULL; thread->flags &= ~(SCHED_THREAD_FLAGS_SLEEP | SCHED_THREAD_FLAGS_INTERRUPTIBLE); diff --git a/kernel-src/sys/signal.c b/kernel-src/sys/signal.c index f8ce7076..d1bc9d02 100644 --- a/kernel-src/sys/signal.c +++ b/kernel-src/sys/signal.c @@ -8,7 +8,7 @@ #define ACTION_STOP 3 #define ACTION_CONT 4 -static int defaultactions[NSIG] = { +int signal_defaultactions[NSIG] = { [SIGABRT] = ACTION_CORE, [SIGALRM] = ACTION_TERM, [SIGBUS] = ACTION_CORE, @@ -149,7 +149,7 @@ void signal_signalthread(struct thread_t *thread, int signal, bool urgent) { SIGNAL_SETON(sigset, signal); void *address = thread->proc->signals.actions[signal].address; - bool notignored = address != SIG_IGN && ((address == SIG_DFL && defaultactions[signal] != ACTION_IGN) || address != SIG_DFL); + bool notignored = address != SIG_IGN && ((address == SIG_DFL && signal_defaultactions[signal] != ACTION_IGN) || address != SIG_DFL); if (signal == SIGKILL || signal == SIGSTOP || urgent || (SIGNAL_GET(&thread->signals.mask, signal) == 0 && notignored)) { sched_wakeup(thread, SCHED_WAKEUP_REASON_INTERRUPTED); @@ -164,11 +164,13 @@ void signal_signalproc(struct proc_t *proc, int signal) { MUTEX_ACQUIRE(&proc->mutex, false); PROCESS_ENTER(proc); void *address = proc->signals.actions[signal].address; - bool notignored = address != SIG_IGN && ((address == SIG_DFL && defaultactions[signal] != ACTION_IGN) || address != SIG_DFL); + bool notignored = address != SIG_IGN && ((address == SIG_DFL && signal_defaultactions[signal] != ACTION_IGN) || address != SIG_DFL); bool notignorable = signal == SIGKILL || signal == SIGSTOP || signal == SIGCONT; bool threadcontinued = false; bool isdefaultaction = address == SIG_DFL; - bool shouldstop = (isdefaultaction && defaultactions[signal] == ACTION_STOP) || signal == SIGSTOP; + bool shouldstop = (isdefaultaction && signal_defaultactions[signal] == ACTION_STOP) || signal == SIGSTOP; + + // TODO is one thread has a stop signal masked, the masked wait breaks completely for (int i = 0; i < proc->threadtablesize; ++i) { if (proc->threads[i] == NULL || (proc->threads[i]->flags & SCHED_THREAD_FLAGS_DEAD)) @@ -212,7 +214,7 @@ void signal_signalproc(struct proc_t *proc, int signal) { // tell the parent that a child stopped // TODO when stopping make sure that a thread was actually stopped - if ((notignorable || notignored) && defaultactions[signal] == ACTION_STOP) { + if ((notignorable || notignored) && signal_defaultactions[signal] == ACTION_STOP) { proc->status = 0x7f; proc->status |= signal << 8; proc->signals.stopunwaited = true; @@ -302,7 +304,7 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin goto leave; } else if ((action->address == SIG_DFL && (action->flags & SA_SIGINFO) == 0) || (action->address == SIG_IGN && sigset == &thread->signals.urgent)) { // default action - int defaction = defaultactions[signal]; + int defaction = signal_defaultactions[signal]; switch (defaction) { case ACTION_IGN: case ACTION_CONT: