]> Zhao Yanbai Git Server - minix.git/commitdiff
System processes can be signaled; signals are transformed in SYS_EVENT message
authorJorrit Herder <jnherder@minix3.org>
Tue, 19 Jul 2005 12:21:36 +0000 (12:21 +0000)
committerJorrit Herder <jnherder@minix3.org>
Tue, 19 Jul 2005 12:21:36 +0000 (12:21 +0000)
that passes signal map along. This mechanisms is also used for nonuser signals
like SIGKMESS, SIGKSTOP, SIGKSIG.

Revised comments of many system call handlers. Renamed setpriority to nice.

33 files changed:
kernel/clock.c
kernel/config.h
kernel/const.h
kernel/glo.h
kernel/i8259.c
kernel/ipc.h
kernel/klibc.c
kernel/main.c
kernel/priv.h
kernel/proc.c
kernel/proc.h
kernel/proto.h
kernel/sendmask.h [deleted file]
kernel/system.c
kernel/system.h
kernel/system/Makefile
kernel/system/do_abort.c
kernel/system/do_alarm.c
kernel/system/do_copy.c
kernel/system/do_endksig.c
kernel/system/do_exec.c
kernel/system/do_fork.c
kernel/system/do_getinfo.c
kernel/system/do_getksig.c
kernel/system/do_irqctl.c
kernel/system/do_kill.c
kernel/system/do_newmap.c
kernel/system/do_sdevio.c
kernel/system/do_segctl.c
kernel/system/do_sigreturn.c
kernel/system/do_sigsend.c
kernel/system/do_vdevio.c
kernel/utility.c

index e744e6742db4fa08f78fc58ef7a46dd76ebf16ef..d6039e4ac6048bb9c3dca2546f7b0ce87b85ba06 100755 (executable)
@@ -7,10 +7,8 @@
  *
  * Changes:
  *   Mar 18, 2004   clock interface moved to SYSTEM task (Jorrit N. Herder) 
- *   Oct 10, 2004   call vector + return values allowed  (Jorrit N. Herder) 
  *   Sep 30, 2004   source code documentation updated  (Jorrit N. Herder)
  *   Sep 24, 2004   redesigned timers and alarms  (Jorrit N. Herder)
- *   Jun 04, 2004   new timeout flag alarm functionality  (Jorrit N. Herder)
  *
  * The function do_clocktick() is not triggered from the clock library, but 
  * by the clock's interrupt handler when a watchdog timer has expired or 
@@ -60,25 +58,18 @@ FORWARD _PROTOTYPE( int do_clocktick, (message *m_ptr) );
 #endif
 
 /* The CLOCK's timers queue. The functions in <timers.h> operate on this. 
- * The process structure contains one timer per type of alarm (SIGNALRM,
- * SYNCALRM, and FLAGALRM), which means that a process can have a single
- * outstanding timer for each alarm type.
- * If other kernel parts want to use additional timers, they must declare 
- * their own persistent timer structure, which can be passed to the clock
+ * All system processes possess a single synchronous alarm timer. If other 
+ * kernel parts want to use additional timers, they must declare their own 
+ * persistent (static) timer structure, which can be passed to the clock
  * via (re)set_timer().
  * When a timer expires its watchdog function is run by the CLOCK task. 
  */
 PRIVATE timer_t *clock_timers;         /* queue of CLOCK timers */
 PRIVATE clock_t next_timeout;          /* realtime that next timer expires */
 
-/* The boot time and the current real time. The real time is incremented by
- * the clock on each clock tick. The boot time is set by a utility program
- * after system startup to prevent troubles reading the CMOS.  
- */
+/* The time is incremented by the interrupt handler on each clock tick. */
 PRIVATE clock_t realtime;              /* real time clock */
-
-/* Variables for and changed by the CLOCK's interrupt handler. */
-PRIVATE irq_hook_t clock_hook;
+PRIVATE irq_hook_t clock_hook;         /* interrupt handler hook */
 
 
 /*===========================================================================*
@@ -86,12 +77,12 @@ PRIVATE irq_hook_t clock_hook;
  *===========================================================================*/
 PUBLIC void clock_task()
 {
-/* Main program of clock task. It corrects realtime by adding pending ticks
- * seen only by the interrupt service, then it determines which call this is 
- * by looking at the message type and dispatches.
+/* Main program of clock task. It determines which call this is by looking at
+ * the message type and dispatches.
  */
   message m;                   /* message buffer for both input and output */
-  int result;
+  int result;                  /* result returned by the handler */
+
   init_clock();                        /* initialize clock task */
 
   /* Main loop of the clock task.  Get work, process it, sometimes reply. */
@@ -297,11 +288,9 @@ PUBLIC unsigned long read_clock()
  */
   unsigned count;
 
-  /* lock(10, "read_clock"); */
   outb(TIMER_MODE, LATCH_COUNT);
   count = inb(TIMER0);
   count |= (inb(TIMER0) << 8);
-  /* unlock(10); */
   
   return count;
 }
index a15ed0313dc20cf986b855f757970028a94b40b3..31e7e6bc6080bec5717ed5cf7b5b52447f038a4e 100644 (file)
@@ -34,7 +34,7 @@
 #define USE_IRQCTL             1       /* set an interrupt policy */
 #define USE_SEGCTL             1       /* set up a remote segment */
 #define USE_SVRCTL             1       /* system server control */
-#define USE_SCHEDCTL   1       /* change scheduling priority (nice) */
+#define USE_NICE       1       /* change scheduling priority */
 #define USE_UMAP               1       /* map virtual to physical address */
 #define USE_VIRCOPY    1       /* copy using virtual addressing */ 
 #define USE_VIRVCOPY   1       /* vector with virtual copy requests */
 #define VDEVIO_BUF_SIZE   64           /* max elements per VDEVIO request */
 #define VCOPY_VEC_SIZE    16           /* max elements per VCOPY request */
 
+#if TEMP_CODE
 /* How many buffers for notification messages should there be? */
 #define NR_NOTIFY_BUFS   32
+#endif
+
+/* How many bytes for the kernel stack. Space allocated in mpx.s. */
+#define K_STACK_BYTES   1024   
 
 
 /* This section allows to enable kernel debugging and timing functionality.
index b5be5cc8347c153faf4de270267564f585783e56..477491fcaf445d46142202836b13efd599f2ee3b 100755 (executable)
@@ -20,9 +20,6 @@
 #define structof(type, field, ptr) \
        ((type *) (((char *) (ptr)) - offsetof(type, field)))
 
-/* How many bytes for the kernel stack. Space allocated in mpx.s. */
-#define K_STACK_BYTES   1024   
-
 /* Constants used in virtual_copy(). Values must be 0 and 1, respectively. */
 #define _SRC_  0
 #define _DST_  1
index a8711d0f5716c6187e7677444d0a06d5542a446d..94fb594322adc7d3cbf78fcd2016439e5af06d4f 100755 (executable)
@@ -33,9 +33,11 @@ EXTERN char k_reenter;               /* kernel reentry count (entry count less 1) */
 EXTERN int sched_ticks;                /* keep track of quantum usage */
 EXTERN unsigned lost_ticks;    /* clock ticks counted outside clock task */
 
+#if TEMP_CODE
 /* Declare buffer space and a bit map for notification messages. */
 EXTERN struct notification notify_buffer[NR_NOTIFY_BUFS];
 EXTERN bitchunk_t notify_bitmap[BITMAP_CHUNKS(NR_NOTIFY_BUFS)];     
+#endif
 
 
 #if (CHIP == INTEL)
index 04f96f74df6e4c15eb9d2f3e24bc649e44b811f4..71d0f3bbb03e7157627acbb2d953ac190ff96997 100755 (executable)
@@ -51,39 +51,39 @@ int mine;
   intr_disable();
 
   if (machine.protected) {
-       /* The AT and newer PS/2 have two interrupt controllers, one master,
-        * one slaved at IRQ 2.  (We don't have to deal with the PC that
-        * has just one controller, because it must run in real mode.)
-        */
-       outb(INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
-       outb(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
+      /* The AT and newer PS/2 have two interrupt controllers, one master,
+       * one slaved at IRQ 2.  (We don't have to deal with the PC that
+       * has just one controller, because it must run in real mode.)
+       */
+      outb(INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
+      outb(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
                                                        /* ICW2 for master */
-       outb(INT_CTLMASK, (1 << CASCADE_IRQ));          /* ICW3 tells slaves */
-       outb(INT_CTLMASK, ICW4_AT_MASTER);
-       outb(INT_CTLMASK, ~(1 << CASCADE_IRQ));         /* IRQ 0-7 mask */
-       outb(INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
-       outb(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
+      outb(INT_CTLMASK, (1 << CASCADE_IRQ));           /* ICW3 tells slaves */
+      outb(INT_CTLMASK, ICW4_AT_MASTER);
+      outb(INT_CTLMASK, ~(1 << CASCADE_IRQ));          /* IRQ 0-7 mask */
+      outb(INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
+      outb(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
                                                        /* ICW2 for slave */
-       outb(INT2_CTLMASK, CASCADE_IRQ);                /* ICW3 is slave nr */
-       outb(INT2_CTLMASK, ICW4_AT_SLAVE);
-       outb(INT2_CTLMASK, ~0);                         /* IRQ 8-15 mask */
+      outb(INT2_CTLMASK, CASCADE_IRQ);         /* ICW3 is slave nr */
+      outb(INT2_CTLMASK, ICW4_AT_SLAVE);
+      outb(INT2_CTLMASK, ~0);                          /* IRQ 8-15 mask */
 
-       /* Copy the BIOS vectors from the BIOS to the Minix location, so we
-        * can still make BIOS calls without reprogramming the i8259s.
-        */
+      /* Copy the BIOS vectors from the BIOS to the Minix location, so we
+       * can still make BIOS calls without reprogramming the i8259s.
+       */
 #if IRQ0_VECTOR != BIOS_IRQ0_VEC
-       phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
+      phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
 #endif
 #if IRQ8_VECTOR != BIOS_IRQ8_VEC
-       phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
+      phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
 #endif
   } else {
-       /* Use the BIOS interrupt vectors in real mode.  We only reprogram the
-        * exceptions here, the interrupt vectors are reprogrammed on demand.
-        * SYS_VECTOR is the Minix system call for message passing.
-        */
-       for (i = 0; i < 8; i++) set_vec(i, int_vec[i]);
-       set_vec(SYS_VECTOR, s_call);
+      /* Use the BIOS interrupt vectors in real mode.  We only reprogram the
+       * exceptions here, the interrupt vectors are reprogrammed on demand.
+       * SYS_VECTOR is the Minix system call for message passing.
+       */
+      for (i = 0; i < 8; i++) set_vec(i, int_vec[i]);
+      set_vec(SYS_VECTOR, s_call);
   }
 }
 
@@ -100,14 +100,14 @@ irq_handler_t handler;
   irq_hook_t **line;
 
   if (irq < 0 || irq >= NR_IRQ_VECTORS)
-       panic("invalid call to put_irq_handler", irq);
+      panic("invalid call to put_irq_handler", irq);
 
   line = &irq_handlers[irq];
   id = 1;
   while (*line != NULL) {
-       if (hook == *line) return;      /* extra initialization */
-       line = &(*line)->next;
-       id <<= 1;
+      if (hook == *line) return;       /* extra initialization */
+      line = &(*line)->next;
+      id <<= 1;
   }
   if (id == 0) panic("Too many handlers for irq", irq);
 
@@ -130,22 +130,20 @@ int id;
 /* Unregister an interrupt handler. */
   irq_hook_t **line;
 
-  if (irq < 0 || irq >= NR_IRQ_VECTORS) {
-       return EINVAL;
-  }
+  if (irq < 0 || irq >= NR_IRQ_VECTORS) return(EINVAL);
 
   line = &irq_handlers[irq];
   while (*line != NULL) {
-       if((*line)->id == id) {
-               (*line) = (*line)->next;
-               if(!irq_handlers[irq])
-                       irq_use &= ~(1 << irq);
-               return OK;
-       }
-       line = &(*line)->next;
+      if((*line)->id == id) {
+          (*line) = (*line)->next;
+          if(! irq_handlers[irq])
+              irq_use &= ~(1 << irq);
+          return(OK);
+      }
+      line = &(*line)->next;
   }
 
-  return ENOENT;
+  return(ENOENT);
 }
 
 /*==========================================================================*
@@ -161,12 +159,12 @@ irq_hook_t *hook;
 
   /* Call list of handlers for an IRQ. */
   while (hook != NULL) {
-       /* For each handler in the list, mark it active by setting its ID bit,
-        * call the function, and unmark it if the function returns true.
-        */
-       irq_actids[hook->irq] |= hook->id;
-       if ((*hook->handler)(hook)) irq_actids[hook->irq] &= ~hook->id;
-       hook = hook->next;
+      /* For each handler in the list, mark it active by setting its ID bit,
+       * call the function, and unmark it if the function returns true.
+       */
+      irq_actids[hook->irq] |= hook->id;
+      if ((*hook->handler)(hook)) irq_actids[hook->irq] &= ~hook->id;
+      hook = hook->next;
   }
 
   /* The assembly code will now disable interrupts, unmask the IRQ if and only
index cb9d8f7b3feed0770a6c4a3358b5e3ddd1ed23cb..1540e8c9bd1b5548ec199e2ba7808027e2bab902 100644 (file)
@@ -18,9 +18,8 @@
 
 /* Call masks indicating which system calls a process can make. */
 #define EMPTY_CALL_MASK        (0)
-#define _USER_CALL_MASK                ((1 << SENDREC) | (1 << ALERT))
+#define USER_CALL_MASK         (1 << SENDREC) 
 #define SYSTEM_CALL_MASK       (~0)
-#define USER_CALL_MASK         (~0)
 
 
 #endif /* IPC_H */
index 1c3cbd2d7f8ca5b441d6abd93f7a7d026e3170e6..113ae5856f4b276f40201756e7cb7ee1d13ba0fd 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "kernel.h"
 
+#include <signal.h>
 #include <minix/com.h>
 
 #define isdigit(c)     ((unsigned) ((c) - '0') <  (unsigned) 10)
@@ -159,7 +160,7 @@ int c;                                      /* character to append */
           kmess.km_size += 1;          
       kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
   } else {
-      lock_alert(SYSTEM, PRINTF_PROC);
+      send_sig(PRINTF_PROC, SIGKMESS);
   }
 }
 
index 13c3602f69419a6e18884a79feccc5accf548c65..27cedbe3d437f97a6771f0f65b4217b4503320da 100755 (executable)
@@ -201,6 +201,9 @@ int how;                            /* reason to shut down */
           return;                      /* await sys_abort() from TTY */
   }
 
+  /* Send signal to TTY so that it can switch to the primary console. */
+  send_sig(TTY, SIGKSTOP);
+
   /* Allow processes to be scheduled to clean up, unless a CPU exception 
    * occurred. This is done by setting a timer. The timer argument passes
    * the shutdown status.
index 2d0281719a1430ea42d05478389168aa58910b17..37dc8925440a83fc7349bbcff8c0a27431bf9d6f 100755 (executable)
@@ -26,6 +26,7 @@ struct priv {
 
   sys_map_t s_notify_pending;          /* bit map with pending notifications */
   short s_int_pending;         /* pending hardware interrupts */
+  sigset_t s_sig_pending;      /* pending signals */
 
   timer_t s_alarm_timer;       /* synchronous alarm timer */ 
   struct far_mem s_farmem[NR_REMOTE_SEGS];  /* remote memory map */
@@ -60,6 +61,9 @@ struct priv {
 EXTERN struct priv priv[NR_SYS_PROCS];         /* system properties table */
 EXTERN struct priv *ppriv_addr[NR_SYS_PROCS];  /* direct slot pointers */
 
+/* Unprivileged user processes all share the same privilege structure. */
+#define USER_PRIV_ID   0
+
 /* Make sure the system can boot. The following sanity check verifies that
  * the system privileges table is large enough for the number of processes
  * in the boot image. 
index 4f3c53418bf61051b3b2632552777efaf837d906..70cf8a7d03dd1a669441bffbfe62dd6c1fa7d3a7 100755 (executable)
@@ -62,19 +62,27 @@ FORWARD _PROTOTYPE( void sched, (struct proc *rp) );
 FORWARD _PROTOTYPE( void pick_proc, (void) );
 
 
+#if TEMP_CODE
 #define BuildOldMess(m,n) \
        (m).NOTIFY_SOURCE = (n)->n_source, \
        (m).NOTIFY_TYPE = (n)->n_type, \
        (m).NOTIFY_FLAGS = (n)->n_flags, \
        (m).NOTIFY_ARG = (n)->n_arg;
+#endif
 
 #define BuildMess(m_ptr, src, dst_ptr) \
        (m_ptr)->m_source = (src);                                      \
        (m_ptr)->m_type = NOTIFY_FROM(src);                             \
        (m_ptr)->NOTIFY_TIMESTAMP = get_uptime();                       \
-       if ((src) == HARDWARE) {                                        \
+       switch (src) {                                                  \
+       case HARDWARE:                                                  \
                (m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_int_pending;     \
                priv(dst_ptr)->s_int_pending = 0;                       \
+               break;                                                  \
+       case SYSTEM:                                                    \
+               (m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_sig_pending;     \
+               priv(dst_ptr)->s_sig_pending = 0;                       \
+               break;                                                  \
        }
 
 #if (CHIP == INTEL)
@@ -123,24 +131,16 @@ message *m_ptr;                   /* pointer to message in the caller's space */
       return(EBADSRCDST);
 
 #if DEAD_CODE          /* temporarily disabled for testing ALERT */
-  /* Check validity of message pointer. */
-  vb = (vir_bytes) m_ptr;
-  vlo = vb >> CLICK_SHIFT;     /* vir click for bottom of message */
-  vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT;   /* vir click for top of msg */
-#if ALLOW_GAP_MESSAGES
   /* This check allows a message to be anywhere in data or stack or gap. 
    * It will have to be made more elaborate later for machines which
    * don't have the gap mapped.
    */
+  vb = (vir_bytes) m_ptr;
+  vlo = vb >> CLICK_SHIFT;     /* vir click for bottom of message */
+  vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT;   /* vir click for top of msg */
   if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
       vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len) 
         return(EFAULT); 
-#else
-  /* Check for messages wrapping around top of memory or outside data seg. */
-  if (vhi < vlo ||
-      vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len) 
-        return(EFAULT); 
-#endif
 #endif
 
   /* Now check if the call is known and try to perform the request. The only
@@ -183,9 +183,11 @@ message *m_ptr;                    /* pointer to message in the caller's space */
       break;
   case NOTIFY:
       result = mini_notify(caller_ptr, src_dst, m_ptr);
+#if TEMP_CODE
       break;
   case ECHO:
       kprintf("Echo message from process %s\n", proc_nr(caller_ptr));
+#endif
       CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, caller_ptr, m_ptr);
       result = OK;
       break;
@@ -197,7 +199,7 @@ message *m_ptr;                     /* pointer to message in the caller's space */
    * be raised. The priority may have been lowered if a process consumed too 
    * many full quantums in a row to prevent damage from infinite loops 
    */
-#if DEAD_CODE          /* temporarily disabled for testing ALERT */
+#if DEAD_CODE          /* buggy ... do unready() first! */
   if ((caller_ptr->p_priority > caller_ptr->p_max_priority) && 
          ! (flags & NON_BLOCKING) && (result == OK)) {
       caller_ptr->p_priority = caller_ptr->p_max_priority;
index dc5c7f096577cb736f75a8cf774ec956a5780091..e1050e159033fbbfee4e2ebf14a175331cad06e1 100755 (executable)
@@ -87,7 +87,7 @@ struct proc {
 #define BEG_USER_ADDR (&proc[NR_TASKS])
 #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
 
-#define NIL_PROC          ((struct proc *) 0)
+#define NIL_PROC          ((struct proc *) 0)          
 #define cproc_addr(n)     (&(proc + NR_TASKS)[(n)])
 #define proc_addr(n)      (pproc_addr + NR_TASKS)[(n)]
 #define proc_nr(p)       ((p)->p_nr)
index 9605aa18ab18f21d5450e6535d246f7ccf345be2..cef1817e76adab100c32352477c7c6c43728aa6b 100755 (executable)
@@ -50,6 +50,7 @@ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
                                U16_t parmoff, U16_t parmsize)          );
 
 /* system.c */
+_PROTOTYPE( void send_sig, (int proc_nr, int sig_nr)                   );
 _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr)                  );
 _PROTOTYPE( int init_proc, (int proc_nr, int proto_nr)                 );
 _PROTOTYPE( void clear_proc, (int proc_nr)                             );
diff --git a/kernel/sendmask.h b/kernel/sendmask.h
deleted file mode 100644 (file)
index 729b522..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Definition of the 'p_sendmask' bit mask used in the process table. The bit
- * mask of process is checked in mini_send() to see if the caller is allowed
- * to send to the destination. 
- *
- * PLEASE NOTE: the send masks definitions are a mess and must be updated!!!
- *             this will be done when dynamic driver loading is implemented
- *
- * Changes:
- *   May 01, 2004      created and sendmask definitions  (Jorrit N. Herder)
- */
-
-#ifndef SENDMASK_H
-#define SENDMASK_H
-
-/* Define type for sendmask, if not already done. */
-#include "type.h"
-
-/* Constants to support the bitmask operations. */
-#define BIT_0          (send_mask_t) 1
-#define MASK_ENTRIES   NR_TASKS + (INIT_PROC_NR+1) + 1
-#define USER_PROC_NR   INIT_PROC_NR+1  /* used to set bit for user procs */
-#define ALLOW_ALL_MASK (send_mask_t) -1
-#define DENY_ALL_MASK  (send_mask_t) 0
-
-/* Check if given process number is in range. */
-#define isvalid(n) ((unsigned) ((n)+NR_TASKS) <= MASK_ENTRIES -1)
-
-/* Default masks and bit operations that easily allow to construct bit masks.
- * Note the one always must start with a default mask like allow_all_mask.
- * From that point, one can, for example, deny several processes.
- */
-#define allow(enabled,n)       | (enabled << ((n) + NR_TASKS))
-#define deny(enabled,n)                & ~(enabled << ((n) + NR_TASKS))
-#define send_mask_allow(mask,n)        ((mask) |= (1 << ((n) + NR_TASKS)))
-#define send_mask_deny(mask,n) ((mask) &= ~(1 << ((n) + NR_TASKS)))
-
-/* Check if the bit for the given process number is set. */
-#define isallowed(mask,n) ((mask) & (BIT_0 << ((n) + NR_TASKS)))
-
-#define USER_PROC_SENDMASK \
-    DENY_ALL_MASK allow(1, PM_PROC_NR) allow(1, FS_PROC_NR)
-
-#endif  /* SENDMASK_H */
-
index ab4fd6b869520273b445527a2371e27f9e09154a..1f965e3822b5dc58ada33855730f595edf07351e 100755 (executable)
@@ -11,7 +11,8 @@
  *
  * In addition to the main sys_task() entry point, which starts the main loop,
  * there are several other minor entry points:
- *   cause_sig:                take action to cause a signal to occur
+ *   send_sig:         send signal directly to a system process
+ *   cause_sig:                take action to cause a signal to occur via PM
  *   clear_proc:       clean up a process in the process table, e.g. on exit
  *   umap_local:       map virtual address in LOCAL_SEG to physical 
  *   umap_remote:      map virtual address in REMOTE_SEG to physical 
@@ -78,9 +79,6 @@ PUBLIC void sys_task()
       /* Handle the request. */
       if ((unsigned) m.m_type < NR_SYS_CALLS) {
           result = (*call_vec[m.m_type])(&m);  /* handle the kernel call */
-      } else if (m.m_type == NEW_KSIG) {       
-          lock_alert(SYSTEM, PM_PROC_NR);      /* tell PM about signal */
-          continue;
       } else {
          kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source);
          result = EBADREQUEST;                 /* illegal message type */
@@ -133,6 +131,7 @@ PRIVATE void initialize(void)
   map(SYS_NEWMAP, do_newmap);          /* set up a process memory map */
   map(SYS_EXEC, do_exec);              /* update process after execute */
   map(SYS_EXIT, do_exit);              /* clean up after process exit */
+  map(SYS_NICE, do_nice);              /* set scheduling priority */
   map(SYS_TRACE, do_trace);            /* request a trace operation */
 
   /* Signal handling. */
@@ -153,7 +152,8 @@ PRIVATE void initialize(void)
   map(SYS_VDEVIO, do_vdevio);                  /* vector with devio requests */ 
 
   /* System control. */
-  map(SYS_SETPRIORITY, do_schedctl);   /* set scheduling priority */
+  map(SYS_ABORT, do_abort);            /* abort MINIX */
+  map(SYS_GETINFO, do_getinfo);        /* request system information */ 
   map(SYS_SEGCTL, do_segctl);          /* add segment and get selector */
   map(SYS_SVRCTL, do_svrctl);          /* kernel control functions */
 
@@ -164,10 +164,6 @@ PRIVATE void initialize(void)
   map(SYS_VIRVCOPY, do_virvcopy);      /* vector with copy requests */
   map(SYS_PHYSVCOPY, do_physvcopy);    /* vector with copy requests */
   map(SYS_MEMSET, do_memset);          /* write char to memory area */
-
-  /* Miscellaneous. */
-  map(SYS_ABORT, do_abort);            /* abort MINIX */
-  map(SYS_GETINFO, do_getinfo);        /* request system information */ 
 }
 
 
@@ -256,17 +252,18 @@ int proc_nr;                              /* slot of process to clean up */
   while (rc->p_ntf_q != NULL) {
       i = (int) (rc->p_ntf_q - &notify_buffer[0]);
       free_bit(i, notify_bitmap, NR_NOTIFY_BUFS); 
+#if TEMP_CODE
       rc->p_ntf_q = rc->p_ntf_q->n_next;
   }
-
-  /* Now clean up the process table entry. Reset to defaults. */
-  kstrncpy(rc->p_name, "<none>", P_NAME_LEN);  /* unset name */
-  sigemptyset(&rc->p_pending);         /* remove pending signals */
-  rc->p_rts_flags = SLOT_FREE;         /* announce slot empty */
-
-#if (CHIP == M68000)
-  pmmu_delete(rc);                     /* we're done, remove tables */
 #endif
+
+  /* Now it is safe to release the process table slot. If this is a system 
+   * process, also release its privilege structure.  Further cleanup is not
+   * needed at this point. All important fields are reinitialized when the 
+   * slots are assigned to another, new process. 
+   */
+  rc->p_rts_flags = SLOT_FREE;         
+  if (priv(rp)->s_flags & SYS_PROC) priv(rp)->s_proc_nr = NONE;
 }
 
 
@@ -331,6 +328,25 @@ irq_hook_t *hook;
 }
 
 
+/*===========================================================================*
+ *                             send_sig                                     *
+ *===========================================================================*/
+PUBLIC void send_sig(proc_nr, sig_nr)
+int proc_nr;                   /* system process to be signalled */
+int sig_nr;                    /* signal to be sent, 1 to _NSIG */
+{
+/* Notify a system process about a signal. This is straightforward. Simply
+ * set the signal that is to be delivered in the pending signals map and 
+ * send a notification with source SYSTEM.
+ */ 
+  register struct proc *rp;
+
+  rp = proc_addr(proc_nr);
+  sigaddset(&priv(rp)->s_sig_pending, sig_nr);
+  lock_alert(SYSTEM, proc_nr); 
+}
+
+
 /*===========================================================================*
  *                             cause_sig                                    *
  *===========================================================================*/
@@ -346,8 +362,10 @@ int sig_nr;                        /* signal to be sent, 1 to _NSIG */
  * signals and makes sure the PM gets them by sending a notification. The 
  * process being signaled is blocked while PM has not finished all signals 
  * for it. 
- * It is not sufficient to ready the process when PM is informed, because 
- * PM can block waiting for FS to do a core dump.
+ * Race conditions between calls to this function and the system calls that
+ * process pending kernel signals cannot exist. Signal related functions are
+ * only called when a user process causes a CPU exception and from the kernel 
+ * process level, which runs to completion.
  */
   register struct proc *rp;
 
@@ -358,7 +376,7 @@ int sig_nr;                 /* signal to be sent, 1 to _NSIG */
       if (! (rp->p_rts_flags & SIGNALED)) {            /* other pending */
           if (rp->p_rts_flags == 0) lock_unready(rp);  /* make not ready */
           rp->p_rts_flags |= SIGNALED | SIG_PENDING;   /* update flags */
-          lock_alert(HARDWARE, SYSTEM);
+          send_sig(PM_PROC_NR, SIGKSIG);
       }
   }
 }
@@ -509,10 +527,7 @@ vir_bytes bytes;           /* # of bytes to copy  */
   int i;
 
   /* Check copy count. */
-  if (bytes <= 0) {
-      kprintf("v_cp: copy count problem <= 0\n", NO_NUM);
-      return(EDOM);
-  }
+  if (bytes <= 0) return(EDOM);
 
   /* Do some more checks and map virtual addresses to physical addresses. */
   vir_addr[_SRC_] = src_addr;
@@ -539,16 +554,12 @@ vir_bytes bytes;          /* # of bytes to copy  */
           phys_addr[i] = vir_addr[i]->offset;
           break;
       default:
-          kprintf("v_cp: Unknown segment type: %d\n", 
-              vir_addr[i]->segment & SEGMENT_TYPE);
           return(EINVAL);
       }
 
       /* Check if mapping succeeded. */
-      if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG) {
-          kprintf("v_cp: Mapping failed ... phys <= 0\n", NO_NUM);
+      if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG) 
           return(EFAULT);
-      }
   }
 
   /* Now copy bytes between physical addresseses. */
index c787f5683d5f9ff36683fb4722111083e89e55ea..099e81dfd006e13fae458e8ccbf2386ad0a364c5 100644 (file)
@@ -43,9 +43,9 @@ _PROTOTYPE( int do_trace, (message *m_ptr) );
 #define do_trace do_unused
 #endif
 
-_PROTOTYPE( int do_schedctl, (message *m_ptr) );
-#if ! USE_SCHEDCTL
-#define do_schedctl do_unused
+_PROTOTYPE( int do_nice, (message *m_ptr) );
+#if ! USE_NICE
+#define do_nice do_unused
 #endif
 
 _PROTOTYPE( int do_copy, (message *m_ptr) );   
index d81ad887af0ebaa9a3da73cb0cd351bee8ff624c..a9d3d72c9e99993d4c56cf07888dfa40287438be 100644 (file)
@@ -23,7 +23,7 @@ OBJECTS       = \
        $(SYSTEM)(do_newmap.o) \
        $(SYSTEM)(do_exit.o) \
        $(SYSTEM)(do_trace.o) \
-       $(SYSTEM)(do_schedctl.o) \
+       $(SYSTEM)(do_nice.o) \
        $(SYSTEM)(do_times.o) \
        $(SYSTEM)(do_alarm.o) \
        $(SYSTEM)(do_irqctl.o) \
@@ -75,8 +75,8 @@ $(SYSTEM)(do_exit.o): do_exit.c
 $(SYSTEM)(do_trace.o): do_trace.c
        $(CC) do_trace.c
 
-$(SYSTEM)(do_schedctl.o):      do_schedctl.c
-       $(CC) do_schedctl.c
+$(SYSTEM)(do_nice.o):  do_nice.c
+       $(CC) do_nice.c
 
 $(SYSTEM)(do_times.o): do_times.c
        $(CC) do_times.c
index 3a68bc8d78f4eb831cccb53effdaefa4df41f1d0..e34c2efca3e60769b9e1304abf46fa22299b09ea 100644 (file)
@@ -1,7 +1,3 @@
-#include "../system.h"
-#include <unistd.h>
-
-
 /* The system call implemented in this file:
  *   m_type:   SYS_ABORT
  *
@@ -11,6 +7,10 @@
  *    m1_i3:   ABRT_MON_LEN    (length of monitor params)
  *    m1_p1:   ABRT_MON_ADDR   (virtual address of params)     
  */
+
+#include "../system.h"
+#include <unistd.h>
+
 #if USE_ABORT
 
 /*===========================================================================*
@@ -24,7 +24,7 @@ message *m_ptr;                       /* pointer to request message */
  * or ESC after debugging dumps).
  */
   int how = m_ptr->ABRT_HOW;
-  
+
   if (how == RBT_MONITOR) {
       /* The monitor is to run the specified instructions. */
       int proc_nr = m_ptr->ABRT_MON_PROC;
@@ -33,8 +33,8 @@ message *m_ptr;                       /* pointer to request message */
       phys_bytes src_phys = numap_local(proc_nr, src_vir, length);
 
       /* Validate length and address of shutdown code before copying. */
-      if (length > kinfo.params_size || src_phys == 0) 
-         phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
+      if (length > kinfo.params_size || src_phys == 0)
+          phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
       else
           phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
   }
index a1d6c4ef8c14bacc6c6569d1e2e45604ac036220..3f52e2e97b66f7151ff9944ace9f923004f0dff8 100644 (file)
@@ -5,10 +5,10 @@
  *    m2_i1:   ALRM_PROC_NR            (set alarm for this process)    
  *    m2_l1:   ALRM_EXP_TIME           (alarm's expiration time)
  *    m2_i2:   ALRM_ABS_TIME           (expiration time is absolute?)
- *    m2_l1:   ALRM_SEC_LEFT           (return seconds left of previous)
+ *    m2_l1:   ALRM_TIME_LEFT          (return seconds left of previous)
  *
  * Changes:
- *    Aug 25, 2004   fully rewritten to clean up code  (Jorrit N. Herder)  
+ *    Aug 25, 2004   fully rewritten to clean up code  (Jorrit N. Herder)
  */
 
 #include "../system.h"
@@ -40,10 +40,10 @@ message *m_ptr;                     /* pointer to request message */
   /* Get the timer structure and set the parameters for this alarm. */
   tp = &(proc_addr(proc_nr)->p_priv->s_alarm_timer);   
   tmr_arg(tp)->ta_int = proc_nr;       
-  tp->tmr_func = cause_alarm;  
+  tp->tmr_func = cause_alarm; 
 
   /* Return the ticks left on the previous alarm. */
-  uptime = get_uptime();  
+  uptime = get_uptime(); 
   if ((tp->tmr_exp_time == TMR_NEVER) || (tp->tmr_exp_time < uptime) ) {
       m_ptr->ALRM_TIME_LEFT = 0;
   } else {
@@ -69,7 +69,7 @@ timer_t *tp;
 {
 /* Routine called if a timer goes off and the process requested a synchronous
  * alarm. The process number is stored in timer argument 'ta_int'. Notify that
- * process given with a SYN_ALARM message.
+ * process with a notification message from CLOCK.
  */
   lock_alert(CLOCK, tmr_arg(tp)->ta_int);
 }
index d6975012ca3622fa2ac760bbefc9edc905e8c9c1..b2bce2c686a0801244c6f3a3ae7e0d590c52c06f 100644 (file)
@@ -45,10 +45,8 @@ register message *m_ptr;     /* pointer to request message */
 
       /* Check if process number was given implictly with SELF and is valid. */
       if (vir_addr[i].proc_nr == SELF) vir_addr[i].proc_nr = m_ptr->m_source;
-      if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) {
-          kprintf("do_vircopy: illegal proc nr, while not phys addr\n",NO_NUM);
+      if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) 
           return(EINVAL); 
-      }
 
       /* Check if physical addressing is used without SYS_PHYSCOPY. */
       if ((vir_addr[i].segment & PHYS_SEG) &&
@@ -58,10 +56,7 @@ register message *m_ptr;     /* pointer to request message */
   /* Check for overflow. This would happen for 64K segments and 16-bit 
    * vir_bytes. Especially copying by the PM on do_fork() is affected. 
    */
-  if (bytes != (vir_bytes) bytes) {
-       kprintf("do_vircopy: overflow\n", NO_NUM);
-       return(E2BIG);
-  }
+  if (bytes != (vir_bytes) bytes) return(E2BIG);
 
   /* Now try to make the actual virtual copy. */
   return( virtual_copy(&vir_addr[_SRC_], &vir_addr[_DST_], bytes) );
index e2babbfad340f1fb79364983ff8f859a9def1990..6f046364d461ae820338f0e14bd603e636e1feb0 100644 (file)
@@ -1,20 +1,8 @@
 /* The system call that is implemented in this file:
- *     SYS_SIGCTL      # signal handling functionality 
+ *   m_type:   SYS_ENDKSIG
  *
- * The parameters and types for this system call are:
- *     SIG_REQUEST     # request to perform                    (long)
- *     SIG_PROC        # process to signal/ pending            (int)
- *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
- *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
- *     SIG_MAP         # bit map with pending signals          (long)  
- *     SIG_NUMBER      # signal number to send to process      (int)   
- *
- * Supported request types are in the parameter SIG_REQUEST:
- *     S_GETSIG                # get a pending kernel signal
- *     S_ENDSIG                # signal has been processed 
- *     S_SENDSIG       # deliver a POSIX-style signal 
- *     S_SIGRETURN     # return from a POSIX-style signal 
- *     S_KILL          # send a signal to a process 
+ * The parameters for this system call are:
+ *     m2_i1:  SIG_PROC        # process for which PM is done
  */
 
 #include "../system.h"
index d5e0635ce5533e6a305e081a52bb89ad1dc7c033..c8db74a28609b279ac09a519ce53cfd948829136 100644 (file)
@@ -3,7 +3,9 @@
  *
  * The parameters for this system call are:
  *    m1_i1:   PR_PROC_NR              (process that did exec call)
+#if DEAD_CODE
  *    m1_i3:   PR_TRACING              (flag to indicate tracing is on/ off)
+#endif
  *    m1_p1:   PR_STACK_PTR            (new stack pointer)
  *    m1_p2:   PR_NAME_PTR             (pointer to program name)
  *    m1_p3:   PR_IP_PTR               (new instruction pointer)
@@ -20,14 +22,15 @@ PUBLIC int do_exec(m_ptr)
 register message *m_ptr;       /* pointer to request message */
 {
 /* Handle sys_exec().  A process has done a successful EXEC. Patch it up. */
-
   register struct proc *rp;
   reg_t sp;                    /* new sp */
   phys_bytes phys_name;
   char *np;
 
   rp = proc_addr(m_ptr->PR_PROC_NR);
+#if DEAD_CODE
   if (m_ptr->PR_TRACING) cause_sig(m_ptr->PR_PROC_NR, SIGTRAP);
+#endif
   sp = (reg_t) m_ptr->PR_STACK_PTR;
   rp->p_reg.sp = sp;           /* set the stack pointer */
 #if (CHIP == M68000)
index 8afdcd4eb4f710803e81819bfcc23cf06c94a25b..baf722ba119f05b1691faad0f5a0d3a1e97348cd 100644 (file)
@@ -26,25 +26,26 @@ register message *m_ptr;    /* pointer to request message */
 #if (CHIP == INTEL)
   reg_t old_ldt_sel;
 #endif
-  register struct proc *rpc;
-  struct proc *rpp;
+  register struct proc *rpc;           /* child process pointer */
+  struct proc *rpp;                    /* parent process pointer */
 
   rpp = proc_addr(m_ptr->PR_PPROC_NR);
   rpc = proc_addr(m_ptr->PR_PROC_NR);
-  if (! isemptyp(rpc)) return(EINVAL);
+  if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL);
 
-  /* Copy parent 'proc' struct to child. */
+  /* Copy parent 'proc' struct to child. And reinitialize some fields. */
 #if (CHIP == INTEL)
-  old_ldt_sel = rpc->p_ldt_sel;        /* stop this being obliterated by copy */
-#endif
-
-  *rpc = *rpp;                                 /* copy 'proc' struct */
-
-#if (CHIP == INTEL)
-  rpc->p_ldt_sel = old_ldt_sel;
+  old_ldt_sel = rpc->p_ldt_sel;                /* backup local descriptors */
+  *rpc = *rpp;                         /* copy 'proc' struct */
+  rpc->p_ldt_sel = old_ldt_sel;                /* restore descriptors */
+#else
+  *rpc = *rpp;                         /* copy 'proc' struct */
 #endif
   rpc->p_nr = m_ptr->PR_PROC_NR;       /* this was obliterated by copy */
+
+#if TEMP_CODE
   rpc->p_ntf_q = NULL;                 /* remove pending notifications */
+#endif
 
   /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
   rpc->p_rts_flags |= NO_MAP;          /* inhibit process from running */
index ee0cc9f635d7a5188a1aa27bda1fcc6194abc2c5..936ec2f0685d0774ce07a9488d8a35b6557fde83 100644 (file)
@@ -6,8 +6,8 @@
  *    m1_i4:   I_PROC_NR       (process to store value at)     
  *    m1_p1:   I_VAL_PTR       (where to put it)       
  *    m1_i1:   I_VAL_LEN       (maximum length expected, optional)     
- *    m1_p2:   I_KEY_PTR       (environment variable key)      
- *    m1_i2:   I_KEY_LEN       (lenght of environment variable key)    
+ *    m1_p2:   I_VAL_PTR2      (second, optional pointer)      
+ *    m1_i2:   I_VAL_LEN2      (second length or process nr)   
  * 
  * Author:
  *    Jorrit N. Herder <jnherder@cs.vu.nl>
@@ -29,26 +29,26 @@ register message *m_ptr;    /* pointer to request message */
   phys_bytes dst_phys; 
   int proc_nr, nr;
 
-  /* Set source address and length based on request type. */      
+  /* Set source address and length based on request type. */
   switch (m_ptr->I_REQUEST) {  
     case GET_MACHINE: {
-       length = sizeof(struct machine);
-       src_phys = vir2phys(&machine);
-       break;
+        length = sizeof(struct machine);
+        src_phys = vir2phys(&machine);
+        break;
     }
     case GET_KINFO: {
-       length = sizeof(struct kinfo);
-       src_phys = vir2phys(&kinfo);
-       break;
+        length = sizeof(struct kinfo);
+        src_phys = vir2phys(&kinfo);
+        break;
     }
     case GET_IMAGE: {
-       length = sizeof(struct system_image) * NR_BOOT_PROCS;
-       src_phys = vir2phys(image);
+        length = sizeof(struct system_image) * NR_BOOT_PROCS;
+        src_phys = vir2phys(image);
         break;
     }
     case GET_IRQHOOKS: {
-       length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
-       src_phys = vir2phys(irq_hooks);
+        length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
+        src_phys = vir2phys(irq_hooks);
         break;
     }
     case GET_SCHEDINFO: {
@@ -58,37 +58,36 @@ register message *m_ptr;    /* pointer to request message */
          */
         length = sizeof(struct proc *) * NR_SCHED_QUEUES;
         src_phys = vir2phys(rdy_head);
-        dst_phys = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->I_KEY_PTR,
-                length); 
+        dst_phys = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->I_VAL_PTR2,
+                length); 
         if (src_phys == 0 || dst_phys == 0) return(EFAULT);
         phys_copy(src_phys, dst_phys, length);
         /* fall through */
     }
     case GET_PROCTAB: {
-       length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
-       src_phys = vir2phys(proc);
+        length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
+        src_phys = vir2phys(proc);
         break;
     }
     case GET_PRIVTAB: {
-       length = sizeof(struct priv) * (NR_SYS_PROCS);
-       src_phys = vir2phys(priv);
+        length = sizeof(struct priv) * (NR_SYS_PROCS);
+        src_phys = vir2phys(priv);
         break;
     }
     case GET_PROC: {
-       nr = (m_ptr->I_KEY_LEN == SELF) ? m_ptr->m_source : m_ptr->I_KEY_LEN;
-       if (! isokprocn(nr)) return(EINVAL);    /* validate request */
-       length = sizeof(struct proc);
-       src_phys = vir2phys(proc_addr(nr));
+        nr = (m_ptr->I_VAL_LEN2 == SELF) ? m_ptr->m_source : m_ptr->I_VAL_LEN2;
+        if (! isokprocn(nr)) return(EINVAL);   /* validate request */
+        length = sizeof(struct proc);
+        src_phys = vir2phys(proc_addr(nr));
         break;
     }
     case GET_MONPARAMS: {
-       src_phys = kinfo.params_base;           /* already is a physical */
-       length = kinfo.params_size;
-       break;
+        src_phys = kinfo.params_base;          /* already is a physical */
+        length = kinfo.params_size;
+        break;
     }
     case GET_RANDOMNESS: {             
-        static struct randomness copy; /* copy to keep counters */
-
+        static struct randomness copy;         /* copy to keep counters */
        int i;
 
         copy = krandom;
@@ -107,9 +106,9 @@ register message *m_ptr;    /* pointer to request message */
     }
 #if DEBUG_TIME_LOCKS
     case GET_LOCKTIMING: {
-       length = sizeof(timingdata);
-       src_phys = vir2phys(timingdata);
-       break;
+    length = sizeof(timingdata);
+    src_phys = vir2phys(timingdata);
+    break;
     }
 #endif
     default:
index 51e5bfcfbdae60e5fe12a028b74d876e328f9486..8e3d0fe643d82cf8ddd502ec9531259e6adbe093 100644 (file)
@@ -1,20 +1,10 @@
 /* The system call that is implemented in this file:
- *     SYS_SIGCTL      # signal handling functionality 
+ *   m_type:   SYS_GETKSIG
  *
- * The parameters and types for this system call are:
- *     SIG_REQUEST     # request to perform                    (long)
- *     SIG_PROC        # process to signal/ pending            (int)
- *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
- *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
- *     SIG_MAP         # bit map with pending signals          (long)  
- *     SIG_NUMBER      # signal number to send to process      (int)   
+ * The parameters for this system call are:
+ *     m2_i1:  SIG_PROC        # process with pending signals
+ *     m2_l1:  SIG_MAP         # bit map with pending signals
  *
- * Supported request types are in the parameter SIG_REQUEST:
- *     S_GETSIG                # get a pending kernel signal
- *     S_ENDSIG                # signal has been processed 
- *     S_SENDSIG       # deliver a POSIX-style signal 
- *     S_SIGRETURN     # return from a POSIX-style signal 
- *     S_KILL          # send a signal to a process 
  */
 
 #include "../system.h"
@@ -32,16 +22,18 @@ message *m_ptr;                     /* pointer to request message */
 /* PM is ready to accept signals and repeatedly does a system call to get 
  * one. Find a process with pending signals. If no signals are available, 
  * return NONE in the process number field.
+ * It is not sufficient to ready the process when PM is informed, because 
+ * PM can block waiting for FS to do a core dump.
  */
   register struct proc *rp;
 
   /* Find the next process with pending signals. */
   for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
       if (rp->p_rts_flags & SIGNALED) {
-          m_ptr->SIG_PROC = rp->p_nr;
-          m_ptr->SIG_MAP = rp->p_pending;
-          sigemptyset(&rp->p_pending);         /* ball is in PM's court */
-          rp->p_rts_flags &= ~SIGNALED;        /* blocked by SIG_PENDING */
+          m_ptr->SIG_PROC = rp->p_nr;          /* store signaled process */
+          m_ptr->SIG_MAP = rp->p_pending;      /* pending signals map */
+          sigemptyset(&rp->p_pending);                 /* ball is in PM's court */
+          rp->p_rts_flags &= ~SIGNALED;                /* blocked by SIG_PENDING */
           return(OK);
       }
   }
index 618c07f8373313db383d2e68da6aa233cda97133..a30a06895762e51f2e4788b6124c69efdefe27c9 100644 (file)
@@ -37,15 +37,15 @@ register message *m_ptr;    /* pointer to request message */
   /* Enable or disable IRQs. This is straightforward. */
   case IRQ_ENABLE:           
   case IRQ_DISABLE: 
-      if (irq_hook_id >= NR_IRQ_HOOKS || 
-          irq_hooks[irq_hook_id].proc_nr == NONE) return(EINVAL);
+      if (irq_hook_id >= NR_IRQ_HOOKS ||
+          irq_hooks[irq_hook_id].proc_nr == NONE) return(EINVAL);
       if (irq_hooks[irq_hook_id].proc_nr != m_ptr->m_source) return(EPERM);
       if (m_ptr->IRQ_REQUEST == IRQ_ENABLE)
           enable_irq(&irq_hooks[irq_hook_id]); 
       else 
           disable_irq(&irq_hooks[irq_hook_id]);        
       break;
-  
+
 
   /* Control IRQ policies. Set a policy and needed details in the IRQ table.
    * This policy is used by a generic function to handle hardware interrupts. 
@@ -53,10 +53,7 @@ register message *m_ptr;     /* pointer to request message */
   case IRQ_SETPOLICY:  
 
       /* Check if IRQ line is acceptable. */
-      if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) {
-         kprintf("ST: irq line %d is not acceptable!\n", irq_vec);
-          return(EINVAL);
-      }
+      if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) return(EINVAL);
 
       /* Find a free IRQ hook for this mapping. */
       hook_ptr = NULL;
@@ -77,18 +74,16 @@ register message *m_ptr;    /* pointer to request message */
       m_ptr->IRQ_HOOK_ID = irq_hook_id + 1;
       break;
 
-  case IRQ_RMPOLICY:  
-       if (irq_hook_id >= NR_IRQ_HOOKS ||
-          irq_hooks[irq_hook_id].proc_nr == NONE) {
-               r = EINVAL;
-       } else {
-               if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
-                       r = EPERM;
-               } else {
-                       r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
-               }
-        }
-       break;
+  case IRQ_RMPOLICY:
+      if (irq_hook_id >= NR_IRQ_HOOKS ||
+               irq_hooks[irq_hook_id].proc_nr == NONE) {
+           return(EINVAL);
+      } else if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
+           return(EPERM);
+      } else {
+           r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
+      }
+      break;
 
   default:
       r = EINVAL;                              /* invalid IRQ_REQUEST */
index 0b33cc90fb2bb7b85b18b77167f25e6d249aa4fe..9f8a248f47e362b3ab60e2f16159fed395f73665 100644 (file)
@@ -1,20 +1,9 @@
 /* The system call that is implemented in this file:
- *     SYS_SIGCTL      # signal handling functionality 
+ *   m_type:   SYS_KILL
  *
- * The parameters and types for this system call are:
- *     SIG_REQUEST     # request to perform                    (long)
- *     SIG_PROC        # process to signal/ pending            (int)
- *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
- *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
- *     SIG_MAP         # bit map with pending signals          (long)  
- *     SIG_NUMBER      # signal number to send to process      (int)   
- *
- * Supported request types are in the parameter SIG_REQUEST:
- *     S_GETSIG                # get a pending kernel signal
- *     S_ENDSIG                # signal has been processed 
- *     S_SENDSIG       # deliver a POSIX-style signal 
- *     S_SIGRETURN     # return from a POSIX-style signal 
- *     S_KILL          # send a signal to a process 
+ * The parameters for this system call are:
+ *     m2_i1:  SIG_PROC        # process to signal/ pending            
+ *     m2_i2:  SIG_NUMBER      # signal number to send to process
  */
 
 #include "../system.h"
 PUBLIC int do_kill(m_ptr)
 message *m_ptr;                        /* pointer to request message */
 {
-/* Handle sys_kill(). Cause a signal to be sent to a process via PM.
- * Note that this has nothing to do with the kill (2) system call, this
- * is how the FS (and possibly other servers) get access to cause_sig. 
+/* Handle sys_kill(). Cause a signal to be sent to a process. The PM is the
+ * central server where all signals are processed and handler policies can
+ * be registered. Any request, except for PM requests, is added to the map
+ * of pending signals and the PM is informed about the new signal.
+ * Since system servers cannot use normal POSIX signal handlers (because they
+ * are usually blocked on a RECEIVE), they can request the PM to transform 
+ * signals into messages. This is done by the PM with a call to sys_kill(). 
  */
-  cause_sig(m_ptr->SIG_PROC, m_ptr->SIG_NUMBER);
+  proc_nr_t proc_nr = m_ptr->SIG_PROC;
+  int sig_nr = m_ptr->SIG_NUMBER;
+
+  if (! isokprocn(proc_nr) || sig_nr > _NSIG) return(EINVAL);
+
+  if (m_ptr->m_source == PM_PROC_NR) {
+      /* Directly send signal notification to a system process. */
+      if (! (priv(proc_addr(proc_nr))->s_flags & SYS_PROC)) return(EPERM);
+      send_sig(proc_nr, sig_nr);
+  } else {
+      /* Set pending signal to be processed by the PM. */
+      cause_sig(proc_nr, sig_nr);
+  }
   return(OK);
 }
 
index 60d712bfbb29932fb3c899f5806a44db1afb70f7..74048d9d610a060d3800ef6073b7a852ca24c36f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * The parameters for this system call are:
  *    m1_i1:   PR_PROC_NR              (install new map for this process)
- *    m1_p1:   PR_MEM_PTR              (pointer to memory map)
+ *    m1_p1:   PR_MEM_PTR              (pointer to the new memory map)
  */
 #include "../system.h"
 
@@ -16,24 +16,21 @@ PUBLIC int do_newmap(m_ptr)
 message *m_ptr;                        /* pointer to request message */
 {
 /* Handle sys_newmap().  Fetch the memory map from PM. */
-
-  register struct proc *rp;
-  phys_bytes src_phys;
+  register struct proc *rp;    /* process whose map is to be loaded */
   int caller;                  /* whose space has the new map (usually PM) */
-  int k;                       /* process whose map is to be loaded */
-  int old_flags;               /* value of flags before modification */
   struct mem_map *map_ptr;     /* virtual address of map inside caller (PM) */
+  phys_bytes src_phys;         /* physical address of map at the PM */
+  int old_flags;               /* value of flags before modification */
 
   /* Extract message parameters and copy new memory map from PM. */
   caller = m_ptr->m_source;
-  k = m_ptr->PR_PROC_NR;
   map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
-  if (!isokprocn(k)) return(EINVAL);
-  rp = proc_addr(k);           /* ptr to entry of user getting new map */
+  if (! isokprocn(m_ptr->PR_PROC_NR)) return(EINVAL);
+  rp = proc_addr(m_ptr->PR_PROC_NR);
 
   /* Copy the map from PM. */
   src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, 
-       sizeof(rp->p_memmap));
+      sizeof(rp->p_memmap));
   if (src_phys == 0) return(EFAULT);
   phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));
 
index cc723bcf64b73dfac8544cd158d8912acd7cf0af..58ea4fd570f6883f0a600a63d74d9148064bfbea 100644 (file)
@@ -44,8 +44,8 @@ register message *m_ptr;      /* pointer to request message */
       } 
   } else if (m_ptr->DIO_REQUEST == DIO_OUTPUT) { 
       switch (m_ptr->DIO_TYPE) {
-      case DIO_BYTE: phys_outsb(port, phys_buf, count); break;  
-      case DIO_WORD: phys_outsw(port, phys_buf, count); break;  
+      case DIO_BYTE: phys_outsb(port, phys_buf, count); break; 
+      case DIO_WORD: phys_outsw(port, phys_buf, count); break; 
       default: return(EINVAL);
       } 
   }
index 0b39813e472b00f8db2cef9ddac0a2c9c7ed75f1..5d106009753b9d840393c375e9eccf9017d86d32 100644 (file)
@@ -37,13 +37,13 @@ register message *m_ptr;    /* pointer to request message */
   rp = proc_addr(m_ptr->m_source);
   index = -1;
   for (i=0; i < NR_REMOTE_SEGS; i++) {
-       if (! rp->p_priv->s_farmem[i].in_use) {
-               index = i; 
-               rp->p_priv->s_farmem[i].in_use = TRUE;
-               rp->p_priv->s_farmem[i].mem_phys = phys;
-               rp->p_priv->s_farmem[i].mem_len = size;
-               break;
-       }
+      if (! rp->p_priv->s_farmem[i].in_use) {
+          index = i; 
+          rp->p_priv->s_farmem[i].in_use = TRUE;
+          rp->p_priv->s_farmem[i].mem_phys = phys;
+          rp->p_priv->s_farmem[i].mem_len = size;
+          break;
+      }
   }
   if (index < 0) return(ENOSPC);
 
@@ -63,7 +63,7 @@ register message *m_ptr;      /* pointer to request message */
                USER_PRIVILEGE);
           selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
           offset = 0;
-          result = OK;                 
+          result = OK;
       } else {
           init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0, 
                USER_PRIVILEGE);
index d7abab43340bec64dfa4c4d60978c75d17bad3da..e3d131ed9c89a6effce64b3f00f298244e90ad4e 100644 (file)
@@ -1,20 +1,10 @@
 /* The system call that is implemented in this file:
- *     SYS_SIGCTL      # signal handling functionality 
+ *   m_type:   SYS_SIGRETURN
  *
- * The parameters and types for this system call are:
- *     SIG_REQUEST     # request to perform                    (long)
- *     SIG_PROC        # process to signal/ pending            (int)
- *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
- *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
- *     SIG_MAP         # bit map with pending signals          (long)  
- *     SIG_NUMBER      # signal number to send to process      (int)   
+ * The parameters for this system call are:
+ *     m2_i1:  SIG_PROC        # process returning from handler
+ *     m2_p1:  SIG_CTXT_PTR    # pointer to sigcontext structure
  *
- * Supported request types are in the parameter SIG_REQUEST:
- *     S_GETSIG                # get a pending kernel signal
- *     S_ENDSIG                # signal has been processed 
- *     S_SENDSIG       # deliver a POSIX-style signal 
- *     S_SIGRETURN     # return from a POSIX-style signal 
- *     S_KILL          # send a signal to a process 
  */
 
 #include "../system.h"
index 88c35469cfbdf0dd074bab7be35e6d6c2c3082c6..0656a4cacfa06c76aa39be79dae8bba393c60347 100644 (file)
@@ -1,20 +1,11 @@
 /* The system call that is implemented in this file:
- *     SYS_SIGCTL      # signal handling functionality 
+ *   m_type:   SYS_SIGSEND
  *
- * The parameters and types for this system call are:
- *     SIG_REQUEST     # request to perform                    (long)
- *     SIG_PROC        # process to signal/ pending            (int)
- *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
- *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
- *     SIG_MAP         # bit map with pending signals          (long)  
- *     SIG_NUMBER      # signal number to send to process      (int)   
+ * The parameters for this system call are:
+ *     m2_i1:  SIG_PROC        # process to call signal handler
+ *     m2_p1:  SIG_CTXT_PTR    # pointer to sigcontext structure
+ *     m2_i3:  SIG_FLAGS       # flags for S_SIGRETURN call    
  *
- * Supported request types are in the parameter SIG_REQUEST:
- *     S_GETSIG                # get a pending kernel signal
- *     S_ENDSIG                # signal has been processed 
- *     S_SENDSIG       # deliver a POSIX-style signal 
- *     S_SIGRETURN     # return from a POSIX-style signal 
- *     S_KILL          # send a signal to a process 
  */
 
 #include "../system.h"
index 5b94870d1bfedec2f519a0b3a4b9ad88c0d78161..e7ecb2549ea082cd8671e8d367dfa180d38f0ff0 100644 (file)
@@ -48,24 +48,24 @@ register message *m_ptr;    /* pointer to request message */
     phys_bytes caller_phys;     /* physical address at caller */
     phys_bytes kernel_phys;     /* physical address in kernel */
 
-    
+
     /* Check if nr of ports is ok and get size of (port,value) data. */
     if (m_ptr->DIO_VEC_SIZE <= 0) return(EINVAL);
     switch(m_ptr->DIO_TYPE) {
-       case DIO_BYTE:
-           if (m_ptr->DIO_VEC_SIZE > MAX_PVB_PAIRS)  return(EINVAL);
-           bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvb_pair_t));
-           break;
-       case DIO_WORD:
-           if (m_ptr->DIO_VEC_SIZE > MAX_PVW_PAIRS)  return(EINVAL);
-           bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvw_pair_t));
-           break;
-       case DIO_LONG:
-           if (m_ptr->DIO_VEC_SIZE > MAX_PVL_PAIRS)  return(EINVAL);
-           bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvl_pair_t));
-           break;
-       default:        /* this once and for all checks for a correct type */
-           return(EINVAL);
+    case DIO_BYTE:
+        if (m_ptr->DIO_VEC_SIZE > MAX_PVB_PAIRS)  return(EINVAL);
+        bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvb_pair_t));
+        break;
+    case DIO_WORD:
+        if (m_ptr->DIO_VEC_SIZE > MAX_PVW_PAIRS)  return(EINVAL);
+        bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvw_pair_t));
+        break;
+    case DIO_LONG:
+        if (m_ptr->DIO_VEC_SIZE > MAX_PVL_PAIRS)  return(EINVAL);
+        bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvl_pair_t));
+        break;
+    default:   /* this once and for all checks for a correct type */
+        return(EINVAL);
     }
 
     /* Calculate physical addresses and copy (port,value)-pairs from user. */
index 5835f8cc5ec078a1b94e19eb98e0eaca5fb15b9d..7d8753fa41b46e44db0353271108891e8d3ebf91 100755 (executable)
@@ -1,9 +1,5 @@
 /* This file contains a collection of miscellaneous procedures:
  *   panic         abort MINIX due to a fatal error
- *   safe_lock     lock the kernel, use in combination with safe_unlock
- *   safe_unlock    unlock the kernel, but prevent breaking nested locks
- *   alloc_bit      bit map manipulation
- *   free_bit       bit map manipulation
  */
 
 #include "kernel.h"
@@ -12,33 +8,6 @@
 #include <minix/com.h>
 
 
-PRIVATE int relock_count = 0;
-
-/*===========================================================================*
- *                                   safe_lock                               *
- *===========================================================================*/
-PUBLIC void safe_lock(c,v)
-int c;
-char *v;
-{
-  if(!(read_cpu_flags() & X86_FLAG_I)) {
-       relock_count++;
-  } else {
-       intr_disable();
-  }
-}
-
-/*===========================================================================*
- *                                   safe_unlock                             *
- *===========================================================================*/
-PUBLIC void safe_unlock(void)
-{
-  if(! relock_count) {
-       intr_enable();
-  } else {
-       relock_count--;
-  }
-}
 
 /*===========================================================================*
  *                                   panic                                   *
@@ -49,8 +18,7 @@ int n;
 {
 /* The system has run aground of a fatal kernel error. Terminate execution. */
   static int panicking = 0;
-  if (panicking ++)            /* prevent recursive panics */
-       return;
+  if (panicking ++) return;            /* prevent recursive panics */
 
   if (s != NULL) {
        kprintf("\nKernel panic: %s", karg(s));
@@ -62,6 +30,7 @@ int n;
 
 
 
+#if TEMP_CODE
 
 /*===========================================================================*
  *                             free_bit                                     * 
@@ -113,3 +82,4 @@ bit_t nr_bits;
     return(-1);    
 }
 
+#endif