mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-31 22:48:21 +00:00
signal: check for pending signals before yield
This commit is contained in:
@@ -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
|
- SMP capable preemptible kernel
|
||||||
- Networking (UDP, DHCP)
|
- Networking (UDP, DHCP)
|
||||||
- POSIX compatibility
|
- 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
|
- Filesystems: tmpfs, devfs, ext2
|
||||||
- Block devices: NVMe, virtio-block
|
- Block devices: NVMe, virtio-block
|
||||||
- Network devices: virtio-net
|
- 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
|
## Current Goals
|
||||||
|
|
||||||
- TCP
|
- TCP
|
||||||
|
- Fat32
|
||||||
|
- Disk Caching
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,12 @@ typedef struct {
|
|||||||
#define SIG_UNBLOCK 1
|
#define SIG_UNBLOCK 1
|
||||||
#define SIG_SETMASK 2
|
#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 proc_t;
|
||||||
struct thread_t;
|
struct thread_t;
|
||||||
void signal_action(struct proc_t *proc, int signal, sigaction_t *new, sigaction_t *old);
|
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_signalthread(struct thread_t *thread, int signal, bool urgent);
|
||||||
void signal_pending(struct thread_t *, sigset_t *sigset);
|
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);
|
bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno);
|
||||||
|
extern int signal_defaultactions[NSIG];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -429,7 +429,23 @@ static void yield(context_t *context) {
|
|||||||
|
|
||||||
thread_t *next = runqueuenext(sleeping ? 0x0fffffff : thread->priority);
|
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;
|
sleeping = false;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
thread->flags &= ~(SCHED_THREAD_FLAGS_SLEEP | SCHED_THREAD_FLAGS_INTERRUPTIBLE);
|
thread->flags &= ~(SCHED_THREAD_FLAGS_SLEEP | SCHED_THREAD_FLAGS_INTERRUPTIBLE);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#define ACTION_STOP 3
|
#define ACTION_STOP 3
|
||||||
#define ACTION_CONT 4
|
#define ACTION_CONT 4
|
||||||
|
|
||||||
static int defaultactions[NSIG] = {
|
int signal_defaultactions[NSIG] = {
|
||||||
[SIGABRT] = ACTION_CORE,
|
[SIGABRT] = ACTION_CORE,
|
||||||
[SIGALRM] = ACTION_TERM,
|
[SIGALRM] = ACTION_TERM,
|
||||||
[SIGBUS] = ACTION_CORE,
|
[SIGBUS] = ACTION_CORE,
|
||||||
@@ -149,7 +149,7 @@ void signal_signalthread(struct thread_t *thread, int signal, bool urgent) {
|
|||||||
SIGNAL_SETON(sigset, signal);
|
SIGNAL_SETON(sigset, signal);
|
||||||
|
|
||||||
void *address = thread->proc->signals.actions[signal].address;
|
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)) {
|
if (signal == SIGKILL || signal == SIGSTOP || urgent || (SIGNAL_GET(&thread->signals.mask, signal) == 0 && notignored)) {
|
||||||
sched_wakeup(thread, SCHED_WAKEUP_REASON_INTERRUPTED);
|
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);
|
MUTEX_ACQUIRE(&proc->mutex, false);
|
||||||
PROCESS_ENTER(proc);
|
PROCESS_ENTER(proc);
|
||||||
void *address = proc->signals.actions[signal].address;
|
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 notignorable = signal == SIGKILL || signal == SIGSTOP || signal == SIGCONT;
|
||||||
bool threadcontinued = false;
|
bool threadcontinued = false;
|
||||||
bool isdefaultaction = address == SIG_DFL;
|
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) {
|
for (int i = 0; i < proc->threadtablesize; ++i) {
|
||||||
if (proc->threads[i] == NULL || (proc->threads[i]->flags & SCHED_THREAD_FLAGS_DEAD))
|
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
|
// tell the parent that a child stopped
|
||||||
// TODO when stopping make sure that a thread was actually 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 = 0x7f;
|
||||||
proc->status |= signal << 8;
|
proc->status |= signal << 8;
|
||||||
proc->signals.stopunwaited = true;
|
proc->signals.stopunwaited = true;
|
||||||
@@ -302,7 +304,7 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin
|
|||||||
goto leave;
|
goto leave;
|
||||||
} else if ((action->address == SIG_DFL && (action->flags & SA_SIGINFO) == 0) || (action->address == SIG_IGN && sigset == &thread->signals.urgent)) {
|
} else if ((action->address == SIG_DFL && (action->flags & SA_SIGINFO) == 0) || (action->address == SIG_IGN && sigset == &thread->signals.urgent)) {
|
||||||
// default action
|
// default action
|
||||||
int defaction = defaultactions[signal];
|
int defaction = signal_defaultactions[signal];
|
||||||
switch (defaction) {
|
switch (defaction) {
|
||||||
case ACTION_IGN:
|
case ACTION_IGN:
|
||||||
case ACTION_CONT:
|
case ACTION_CONT:
|
||||||
|
|||||||
Reference in New Issue
Block a user