From: Alan Cox Date: Wed, 17 Feb 2016 18:08:21 +0000 (+0000) Subject: process: clean up signal handling logic and finish off SIGSTOP/CONT X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=c1829adb6802cbd2ab6856d9e41448433cf2e549;p=FUZIX.git process: clean up signal handling logic and finish off SIGSTOP/CONT --- diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 22fa1ea8..b9239b39 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -285,11 +285,8 @@ struct mount { #define P_READY 2 /* Runnable */ #define P_SLEEP 3 /* Sleeping; can be awakened by signal */ #define P_STOPPED 4 /* Sleeping, don't wake up for signal */ -#define P_PAUSE 5 /* Sleeping for pause(); can wakeup for signal */ -#define P_WAIT 6 /* Executed a wait() */ -#define P_FORKING 7 /* In process of forking; do not mess with */ -#define P_ZOMBIE2 8 /* Exited but code pages still valid. */ -#define P_ZOMBIE 9 /* Exited. */ +#define P_FORKING 5 /* In process of forking; do not mess with */ +#define P_ZOMBIE 6 /* Exited. */ /* 0 is used to mean 'check we could signal this process' */ @@ -783,10 +780,10 @@ extern void pwake(ptptr p); extern ptptr getproc(void); extern void newproc(ptptr p); extern ptptr ptab_alloc(void); -extern void ssig(ptptr proc, uint16_t sig); +extern void ssig(ptptr proc, uint8_t sig); extern void chksigs(void); extern void program_vectors(uint16_t *pageptr); -extern void sgrpsig(uint16_t pgrp, uint16_t sig); +extern void sgrpsig(uint16_t pgrp, uint8_t sig); extern void unix_syscall(void); extern void timer_interrupt(void); extern void doexit (int16_t val, int16_t val2); diff --git a/Kernel/process.c b/Kernel/process.c index 11ae84ca..ee064afa 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -36,12 +36,7 @@ void psleep(void *event) panic(PANIC_VOODOO); } - if (!event) - udata.u_ptab->p_status = P_PAUSE; - else if (event == (char *) udata.u_ptab) - udata.u_ptab->p_status = P_WAIT; - else - udata.u_ptab->p_status = P_SLEEP; + udata.u_ptab->p_status = P_SLEEP; udata.u_ptab->p_wait = event; udata.u_ptab->p_waitno = ++waitno; nready--; @@ -428,7 +423,7 @@ void unix_syscall(void) ei(); } -void sgrpsig(uint16_t pgrp, uint16_t sig) +void sgrpsig(uint16_t pgrp, uint8_t sig) { ptptr p; if (pgrp) { @@ -457,15 +452,23 @@ void chksigs(void) m = sigmask(j); if (!(m & pending)) continue; + /* SIGSTOP can't be ignored and puts the process into + P_STOPPED state when it is ready to handle the signal. + Annoyingly right now we have to context switch to the task + in order to stop it in the right place. That would be nice + to fix */ + if (j == SIGSTOP || j == SIGTTIN || j == SIGTTOU) { + udata.u_ptab->p_status = P_STOPPED; + udata.u_ptab->p_event = j; + psleep(NULL); + } /* This is more complex than in V7 - we have multiple behaviours (plus the unimplemented as yet core dump) */ if (*svec == SIG_DFL) { /* SIGCONT is subtle - we woke the process to handle the signal so ignoring here works fine */ if (j == SIGCHLD || j == SIGURG || j == SIGSTOP || -#ifdef CONFIG_LEVEL_2 j == SIGTTIN || j == SIGTTOU || -#endif j == SIGIO || j == SIGCONT || udata.u_ptab->p_pid == 1) { udata.u_ptab->p_pending &= ~m; // unset the bit continue; @@ -490,7 +493,10 @@ void chksigs(void) /* * Send signal, avoid touching uarea */ -void ssig(ptptr proc, uint16_t sig) +/* SDCC bug #2472: SDCC generates hideous code for this function due to bad + code generation when masking longs. Not clear we can do much about it but + file a bug */ +void ssig(ptptr proc, uint8_t sig) { uint32_t sigm; irqflags_t irq; @@ -500,28 +506,26 @@ void ssig(ptptr proc, uint16_t sig) irq = di(); if (proc->p_status != P_EMPTY) { /* Presumably was killed just now */ - /* SIGSTOP can't be ignored and puts the process into P_STOPPED. - We need to sort out handling of SIGSTOP when waiting - we should - really interrupt the syscall and stop */ - if (sig == SIGSTOP || sig == SIGTTIN || sig == SIGTTOU) { - if (proc->p_status == P_RUNNING || - proc->p_status == P_READY) - nready--; - proc->p_status = P_STOPPED; - proc->p_event = sig; - /* SIGCONT likewise has an unblockable effect */ - } else if (sig == SIGCONT && proc->p_status == P_STOPPED) { - proc->p_status = P_READY; - proc->p_event = 0; - nready++; + /* SIGCONT has an unblockable effect */ + if (sig == SIGCONT) { + if (proc->p_status == P_STOPPED) { + proc->p_status = P_READY; + proc->p_event = 0; + nready++; + } + /* CONT discards pending stops */ + proc->p_pending &= ~((1L << SIGSTOP) | (1L << SIGTTIN) | + (1L << SIGTTOU) | (1L << SIGTSTP)); } + /* STOP discards pending conts */ + if (sig >= SIGSTOP && sig <= SIGTTOU) + proc->p_pending &= ~(1L << SIGCONT); + /* Routine signal behaviour */ if (!(proc->p_ignored & sigm)) { /* Don't wake for held signals */ if (!(proc->p_held & sigm)) { switch (proc->p_status) { - case P_PAUSE: - case P_WAIT: case P_SLEEP: proc->p_status = P_READY; nready++; diff --git a/Library/include/proc.h b/Library/include/proc.h index 2929a092..37ade670 100644 --- a/Library/include/proc.h +++ b/Library/include/proc.h @@ -11,11 +11,8 @@ #define P_READY 2 /* Runnable */ #define P_SLEEP 3 /* Sleeping; can be awakened by signal */ #define P_STOPPED 4 /* Stopped waiting for SIGCONT */ -#define P_PAUSE 5 /* Sleeping for pause(); can wakeup for signal */ -#define P_WAIT 6 /* Executed a wait() */ -#define P_FORKING 7 /* In process of forking; do not mess with */ -#define P_ZOMBIE2 8 /* Exited but code pages still valid. */ -#define P_ZOMBIE 9 /* Exited. */ +#define P_FORKING 5 /* In process of forking; do not mess with */ +#define P_ZOMBIE 6 /* Exited. */ /* Process table entry */