]> git.corax.cc Git - corax/commitdiff
Change return type of _process_hwint_deliver() so that the caller can find out whethe...
authorMatthias Kruk <m@m10k.eu>
Sat, 18 Jan 2020 07:39:58 +0000 (16:39 +0900)
committerMatthias Kruk <m@m10k.eu>
Sat, 18 Jan 2020 07:39:58 +0000 (16:39 +0900)
kernel/core/process.c
kernel/core/signal.c

index 068c75868629ae0a1393e026a8ce86ec3a062309..2fea2de98eafce703206c1f3b62c610f7a2999f3 100644 (file)
@@ -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);
 }
index eae38f89f76b8a024c8d913b451f5fcb50a891d6..506dba06ada7f4814da5bf4b5444fbdb159e4022 100644 (file)
@@ -1,24 +1,31 @@
 #include <config.h>
 #include <corax/types.h>
 #include <corax/errno.h>
-#include <arch.h>
-#include <signal.h>
 #include <sys/types.h>
 #include <process.h>
+#include <signal.h>
+
+#include <arch.h>
+#include <debug.h>
 
 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;