POSIX signal sending / reception (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 20 Oct 2012 00:23:24 +0000 (17:23 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 20 Oct 2012 00:28:19 +0000 (17:28 -0700)
Adds kernel support for basic POSIX inter-process signals.  We just
multiplex signals through a new Event type.  There's a kernel helper to
send signals, if you want.

Uthread code registers an ev_q for the signals, and right now just has a
dummy handler.  We'll need to hook this in to glibc for support of all
the usual signal-related functions.

Also, grab the new busybox config - it supports kill.

Rebuild your cross compiler/kernel headers and anything that linked
against parlib (like busybox).

kern/include/event.h
kern/include/ros/bits/posix_signum.h [new file with mode: 0644]
kern/include/ros/event.h
kern/src/event.c
kern/src/syscall.c
tests/hello.c
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/kill.c
tools/patches/busybox-1.17.3-config
user/parlib/uthread.c

index 471f279..8a6c22a 100644 (file)
@@ -9,6 +9,7 @@
 #define ROS_KERN_EVENT_H
 
 #include <ros/event.h>
+#include <ros/bits/posix_signum.h>
 #include <process.h>
 
 void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
@@ -16,5 +17,6 @@ void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
 void send_kernel_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid);
 void post_vcore_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid,
                       int ev_flags);
+void send_posix_signal(struct proc *p, int sig_nr);
 
 #endif /* ROS_KERN_EVENT_H */
diff --git a/kern/include/ros/bits/posix_signum.h b/kern/include/ros/bits/posix_signum.h
new file mode 100644 (file)
index 0000000..d2ae3b0
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef ROS_INC_BITS_POSIX_SIGNUM_H
+#define ROS_INC_BITS_POSIX_SIGNUM_H
+
+#ifdef ROS_KERNEL
+
+#define        SIGHUP          1
+#define        SIGINT          2
+#define        SIGQUIT         3
+#define        SIGILL          4
+#define        SIGTRAP         5
+#define        SIGABRT         6
+#define        SIGIOT          6
+#define        SIGBUS          7
+#define        SIGFPE          8
+#define        SIGKILL         9
+#define        SIGUSR1         10
+#define        SIGSEGV         11
+#define        SIGUSR2         12
+#define        SIGPIPE         13
+#define        SIGALRM         14
+#define        SIGTERM         15
+#define        SIGSTKFLT       16
+#define        SIGCLD          SIGCHLD
+#define        SIGCHLD         17
+#define        SIGCONT         18
+#define        SIGSTOP         19
+#define        SIGTSTP         20
+#define        SIGTTIN         21
+#define        SIGTTOU         22
+#define        SIGURG          23
+#define        SIGXCPU         24
+#define        SIGXFSZ         25
+#define        SIGVTALRM       26
+#define        SIGPROF         27
+#define        SIGWINCH        28
+#define        SIGPOLL         SIGIO
+#define        SIGIO           29
+#define        SIGPWR          30
+#define SIGSYS         31
+#define SIGUNUSED      31
+
+#define        _NSIG           65
+
+#define __SIGRTMIN     32
+#define __SIGRTMAX     (_NSIG - 1)
+#endif /* ROS_KERNEL */
+
+#endif /* ROS_INC_BITS_POSIX_SIGNUM_H */
index ecec750..02c42bb 100644 (file)
@@ -46,7 +46,8 @@
 #define EV_FREE_APPLE_PIE               9
 #define EV_SYSCALL                             10
 #define EV_CHECK_MSGS                  11
-#define NR_EVENT_TYPES                 12 /* keep me last */
+#define EV_POSIX_SIGNAL                        12
+#define NR_EVENT_TYPES                 25 /* keep me last (and 1 > the last one) */
 
 /* Will probably have dynamic notifications later */
 #define MAX_NR_DYN_EVENT               25
index fea5d8d..f835423 100644 (file)
@@ -473,3 +473,13 @@ void post_vcore_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid,
        post_vc_msg(p, vcoreid, get_vcpd_mbox(vcoreid, ev_flags), msg, ev_flags);
        switch_back(p, old_proc);
 }
+
+/* Attempts to send a posix signal to the process.  If they do not have an ev_q
+ * registered for EV_POSIX_SIGNAL, then nothing will happen. */
+void send_posix_signal(struct proc *p, int sig_nr)
+{
+       struct event_msg local_msg = {0};
+       local_msg.ev_type = EV_POSIX_SIGNAL;
+       local_msg.ev_arg1 = sig_nr;
+       send_kernel_event(p, &local_msg, 0);
+}
index 742a754..6ed8691 100644 (file)
@@ -675,6 +675,8 @@ static int sys_notify(struct proc *p, int target_pid, unsigned int ev_type,
                        set_errno(EINVAL);
                        return -1;
                }
+       } else {
+               local_msg.ev_type = ev_type;
        }
        send_kernel_event(target, &local_msg, 0);
        proc_decref(target);
index 4efc982..2555df7 100644 (file)
@@ -1,10 +1,13 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <parlib.h>
+#include <unistd.h>
+#include <signal.h>
 
 int main(int argc, char** argv)
 {
        printf("Hello world from program %s!!\n", argv[0]);
+       kill(getpid(), SIGTERM);
        sys_block(5000);
        printf("Done\n");
        return 0;
index d42b3c9..b2d22c1 100644 (file)
 #include <errno.h>
 #include <signal.h>
 #include <ros/syscall.h>
+#include <ros/event.h>
 
 /* Send signal SIG to process number PID.  If PID is zero,
    send SIG to all processes in the current process's process group.
-   If PID is < -1, send SIG to all processes in process group - PID.  */
-int
-__kill (int pid, int sig)
+   If PID is < -1, send SIG to all processes in process group - PID.
+   If SIG is SIGKILL, kill the process. */
+int __kill (int pid, int sig)
 {
-  if(pid <= 0)
-  {
-    errno = ENOSYS;
-    return -1;
-  }
-  return ros_syscall(SYS_proc_destroy, pid, 0, 0, 0, 0, 0);
+       struct event_msg local_msg = {0};
+       if (pid <= 0) {
+               errno = ENOSYS;
+               return -1;
+       }
+       if (sig == SIGKILL)
+               return ros_syscall(SYS_proc_destroy, pid, 0, 0, 0, 0, 0);
+       local_msg.ev_type = EV_POSIX_SIGNAL;
+       local_msg.ev_arg1 = sig;
+       return ros_syscall(SYS_notify, pid, EV_POSIX_SIGNAL, &local_msg, 0, 0, 0);
 }
 weak_alias (__kill, kill)
index 9ef85ce..abf9625 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Busybox version: 1.17.3
-# Mon Apr  9 19:14:46 2012
+# Thu Oct 18 13:11:01 2012
 #
 CONFIG_HAVE_DOT_CONFIG=y
 
@@ -833,9 +833,9 @@ CONFIG_FEATURE_MIME_CHARSET=""
 # CONFIG_SMEMCAP is not set
 # CONFIG_FREE is not set
 # CONFIG_FUSER is not set
-# CONFIG_KILL is not set
-# CONFIG_KILLALL is not set
-# CONFIG_KILLALL5 is not set
+CONFIG_KILL=y
+CONFIG_KILLALL=y
+CONFIG_KILLALL5=y
 # CONFIG_NMETER is not set
 # CONFIG_PGREP is not set
 # CONFIG_PIDOF is not set
index 73baf7b..6fecbf1 100644 (file)
@@ -110,16 +110,33 @@ static void scp_vcctx_ready(void)
                             old_flags & ~VC_SCP_NOVCCTX));
 }
 
+/* TODO: dumb helper, put it in glibc or something */
+static void handle_posix_signal(struct event_msg *ev_msg, unsigned int ev_type)
+{
+       int sig_nr;
+       assert(ev_msg);
+       sig_nr = ev_msg->ev_arg1;
+       printf("Received POSIX signal number %d\n", sig_nr);
+}
+
 /* Slim-init - sets up basic uthreading for when we are in _S mode and before
  * we set up the 2LS.  Some apps may not have a 2LS and thus never do the full
  * vcore/2LS/uthread init. */
 void uthread_slim_init(void)
 {
        struct uthread *uthread = malloc(sizeof(*uthread));
+       struct event_queue *posix_sig_ev_q;
        /* TODO: consider a vcore_init_vc0 call.  Init the vcore system */
        assert(!vcore_init());
        uthread_manage_thread0(uthread);
        scp_vcctx_ready();
+       /* Register an ev_q for posix signals */
+       /* TODO: probably put this handler in glibc */
+       ev_handlers[EV_POSIX_SIGNAL] = handle_posix_signal;
+       posix_sig_ev_q = get_big_event_q();
+       assert(posix_sig_ev_q);
+       posix_sig_ev_q->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_FALLBACK;
+       register_kevent_q(posix_sig_ev_q, EV_POSIX_SIGNAL);
        /* change our blockon from glibc's internal one to the mcp one (which can
         * handle SCPs too).  we must do this before switching to _M, or at least
         * before blocking while an _M.  it's harmless (and probably saner) to do it