From: Matthias Kruk Date: Sat, 18 Jan 2020 07:39:58 +0000 (+0900) Subject: Change return type of _process_hwint_deliver() so that the caller can find out whethe... X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=147fba670b7525c8fd004e5b57a0dbf09afa6dbc;p=corax Change return type of _process_hwint_deliver() so that the caller can find out whether or not the interrupt has been successfully delivered --- diff --git a/kernel/core/process.c b/kernel/core/process.c index 068c758..2fea2de 100644 --- a/kernel/core/process.c +++ b/kernel/core/process.c @@ -734,7 +734,7 @@ int process_signal_deliver(process_t *proc, int signal) ret_val = -EINVAL; - if(proc && signal > 0 && signal <= SIGUNUSED) { + if(proc && signal >= 0 && signal <= SIGUNUSED) { process_t *cproc; stack_frame_t *kstk; u32_t *vesp3; @@ -745,6 +745,7 @@ int process_signal_deliver(process_t *proc, int signal) cproc = process_get_current(); if(cproc != proc) { + dbg_printf("Signal %u to different process\n", signal); /* FIXME: Need to suspend the process in order to deliver the signal safely */ process_suspend(proc); @@ -1045,15 +1046,18 @@ void* process_get_sighandler(process_t *proc, int signal) return((void*)proc->p_sighandler[signal]); } -void _process_hwint_deliver(pid_t pid, int irq) +int _process_hwint_deliver(pid_t pid, int irq) { process_t *proc; + int ret_val; + ret_val = -EINVAL; proc = process_lookup(pid); if(proc) { process_signal_deliver(proc, SIGHWINT); + ret_val = 0; } - return; + return(ret_val); } diff --git a/kernel/core/signal.c b/kernel/core/signal.c index eae38f8..506dba0 100644 --- a/kernel/core/signal.c +++ b/kernel/core/signal.c @@ -1,24 +1,31 @@ #include #include #include -#include -#include #include #include +#include + +#include +#include struct intq { pid_t handlers[CONFIG_IRQ_QLEN]; }; -struct intq _int_q[32]; +struct intq _int_q[IRQ(INT_MAX)]; -void _process_hwint_deliver(pid_t, int); +int _process_hwint_deliver(pid_t, int); -void _sig_hwint_deliver(const int irq) +void _sig_hwint_deliver(const int intno) { struct intq *q; + int irq; int i; + irq = IRQ(intno); + + dbg_printf("Delivering interrupt %u\n", irq); + /* make sure we don't make invalid accesses to _int_q */ if(irq < 1 || irq >= (sizeof(_int_q) / sizeof(_int_q[0]))) { return; @@ -33,8 +40,26 @@ void _sig_hwint_deliver(const int irq) break; } + dbg_printf("irq %u -> pid %u\n", irq, q->handlers[i]); + /* deliver hardware interrupt to process */ - _process_hwint_deliver(q->handlers[i], irq); + if(_process_hwint_deliver(q->handlers[i], irq) < 0) { + /* remove the handler if an interrupt could not be delivered */ + pid_t npid; + int j; + + dbg_printf("irq %u could not be delivered\n", irq); + + for(npid = -1, j = (sizeof(q->handlers) / sizeof(q->handlers[0])) - 1; j > i; j++) { + if(q->handlers[j] > 0) { + npid = q->handlers[j]; + q->handlers[j] = -1; + break; + } + } + + q->handlers[i] = npid; + } } return; @@ -47,6 +72,7 @@ int sys_sigaction(stack_frame_t *stk) struct sigaction *old; process_t *cproc; int ret_val; + int irq; cproc = process_get_current(); @@ -59,6 +85,21 @@ int sys_sigaction(stack_frame_t *stk) case SIGHWINT: /* this is the Corax way to notify processes about hardware interrupts */ + for(irq = 0; irq < IRQ(INT_MAX); irq++) { + int intno; + pid_t cpid; + + intno = INT(irq); + cpid = process_get_id(cproc); + + if(sigismember(&(new.sa_mask), intno)) { + dbg_printf("Process %u would like to receive notifications for irq %u [%u]\n", + cpid, irq, intno); + + _int_q[irq].handlers[0] = cpid; + } + } + ret_val = 0; break;