]> Zhao Yanbai Git Server - minix.git/commitdiff
New P_BLOCKEDON for kernel - a macro that encodes the "who is this
authorBen Gras <ben@minix3.org>
Wed, 3 Mar 2010 15:32:26 +0000 (15:32 +0000)
committerBen Gras <ben@minix3.org>
Wed, 3 Mar 2010 15:32:26 +0000 (15:32 +0000)
process waiting for" logic, which is duplicated a few times in the
kernel. (For a new feature for top.)

Introducing it and throwing out ESRCDIED and EDSTDIED (replaced by
EDEADSRCDST - so we don't have to care which part of the blocking is
failing in system.c) simplifies some code in the kernel and callers that
check for E{DEADSRCDST,ESRCDIED,EDSTDIED}, but don't care about the
difference, a fair bit, and more significantly doesn't duplicate the
'blocked-on' logic.

kernel/arch/i386/system.c
kernel/proc.c
kernel/proc.h
kernel/system.c

index d54dc63a43cdd3f1288644d3ae76cd89c3248543..af7f4bcaec95b51259317ea743c92f7ba164352a 100644 (file)
@@ -315,7 +315,7 @@ PRIVATE void ser_debug(int c)
 PRIVATE void printslot(struct proc *pp, int level)
 {
        struct proc *depproc = NULL;
-       int dep = NONE;
+       endpoint_t dep;
 #define COL { int i; for(i = 0; i < level; i++) printf("> "); }
 
        if(level >= NR_PROCS) {
@@ -331,15 +331,8 @@ PRIVATE void printslot(struct proc *pp, int level)
                pp->p_sys_time, pp->p_cycles.hi, pp->p_cycles.lo, pp->p_seg.p_cr3,
                rtsflagstr(pp->p_rts_flags), miscflagstr(pp->p_misc_flags));
 
-       if(pp->p_rts_flags & RTS_SENDING) {
-               dep = pp->p_sendto_e;
-               kprintf(" to: ");
-       } else if(pp->p_rts_flags & RTS_RECEIVING) {
-               dep = pp->p_getfrom_e;
-               kprintf(" from: ");
-       }
-
-       if(dep != NONE) {
+       if((dep = P_BLOCKEDON(pp)) != NONE) {
+               kprintf(" blocked on: ");
                if(dep == ANY) {
                        kprintf(" ANY\n");
                } else {
index 612736b7b37ac348157c1ffc1edee8ed06c74324..92d39d2b5f4e67877bea43b567ae2922502c97ae 100644 (file)
@@ -511,6 +511,7 @@ proc_nr_t src_dst;                          /* src or dst process */
 #endif
 
   while (src_dst != ANY) {                     /* check while process nr */
+      endpoint_t dep;
       xp = proc_addr(src_dst);                 /* follow chain of processes */
 #if DEBUG_ENABLE_IPC_WARNINGS
       processes[group_size] = xp;
@@ -520,14 +521,13 @@ proc_nr_t src_dst;                                /* src or dst process */
       /* Check whether the last process in the chain has a dependency. If it 
        * has not, the cycle cannot be closed and we are done.
        */
-      if (RTS_ISSET(xp, RTS_RECEIVING)) {      /* xp has dependency */
-         if(xp->p_getfrom_e == ANY) src_dst = ANY;
-         else okendpt(xp->p_getfrom_e, &src_dst);
-      } else if (RTS_ISSET(xp, RTS_SENDING)) { /* xp has dependency */
-         okendpt(xp->p_sendto_e, &src_dst);
-      } else {
-         return(0);                            /* not a deadlock */
-      }
+      if((dep = P_BLOCKEDON(xp)) == NONE)
+       return 0;
+
+      if(dep == ANY)
+       src_dst = ANY;
+      else
+       okendpt(dep, &src_dst);
 
       /* Now check if there is a cyclic dependency. For group sizes of two,  
        * a combination of SEND(REC) and RECEIVE is not fatal. Larger groups
@@ -585,7 +585,7 @@ int flags;
 
   if (RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT))
   {
-       return EDSTDIED;
+       return EDEADSRCDST;
   }
 
   /* Check if 'dst' is blocked waiting for this message. The destination's 
@@ -661,7 +661,7 @@ int flags;
        okendpt(src_e, &src_p);
        if (RTS_ISSET(proc_addr(src_p), RTS_NO_ENDPOINT))
        {
-               return ESRCDIED;
+               return EDEADSRCDST;
        }
   }
 
@@ -958,7 +958,7 @@ PRIVATE int mini_senda(struct proc *caller_ptr, asynmsg_t *table, size_t size)
                /* RTS_NO_ENDPOINT should be removed */
                if (dst_ptr->p_rts_flags & RTS_NO_ENDPOINT)
                {
-                       tabent.result= EDSTDIED;
+                       tabent.result= EDEADSRCDST;
                        A_INSERT(i, result);
                        tabent.flags= flags | AMF_DONE;
                        A_INSERT(i, flags);
index a144a4cb088dbe3ab429fa866a786f378f1b26f1..c2f05ea209b30699a80a974d2efd61a3d56f5c05 100644 (file)
@@ -157,6 +157,25 @@ struct proc {
 #define proc_is_preempted(p)   ((p)->p_rts_flags & RTS_PREEMPTED)
 #define proc_no_quantum(p)     ((p)->p_rts_flags & RTS_NO_QUANTUM)
 
+/* Macro to return: on which process is a certain process blocked?
+ * return endpoint number (can be ANY) or NONE. It's important to
+ * check RTS_SENDING first, and then RTS_RECEIVING, as they could
+ * both be on (if a sendrec() blocks on sending), and p_getfrom_e
+ * could be nonsense even though RTS_RECEIVING is on.
+ */
+#define P_BLOCKEDON(p)                                                 \
+       (                                                               \
+               ((p)->p_rts_flags & RTS_SENDING) ?                      \
+               (p)->p_sendto_e :                                       \
+               (                                                       \
+                       (                                               \
+                               ((p)->p_rts_flags & RTS_RECEIVING) ?    \
+                               (p)->p_getfrom_e :                      \
+                               NONE                                    \
+                       )                                               \
+               )                                                       \
+       )
+
 /* These runtime flags can be tested and manipulated by these macros. */
 
 #define RTS_ISSET(rp, f) (((rp)->p_rts_flags & (f)) == (f))
index 04a57d7b19570831d7b556bb978406fad031cf86..6539066621e4e47a7253872edc9915f3d0ecdbf3 100644 (file)
@@ -519,21 +519,12 @@ register struct proc *rc;         /* slot of process to clean up */
       /* Unset pending notification bits. */
       unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
 
-      /* Check if process is receiving from exiting process. */
-      if (RTS_ISSET(rp, RTS_RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) {
-          rp->p_reg.retreg = ESRCDIED;         /* report source died */
-         RTS_UNSET(rp, RTS_RECEIVING); /* no longer receiving */
+      /* Check if process is depends on exiting process. */
+      if (P_BLOCKEDON(rp) == rc->p_endpoint) {
+          rp->p_reg.retreg = EDEADSRCDST;              /* report source died */
+         RTS_UNSET(rp, (RTS_RECEIVING|RTS_SENDING)); /* no longer blocking */
 #if DEBUG_ENABLE_IPC_WARNINGS
-         kprintf("endpoint %d / %s receiving from dead src ep %d / %s\n",
-               rp->p_endpoint, rp->p_name, rc->p_endpoint, rc->p_name);
-#endif
-      } 
-      if (RTS_ISSET(rp, RTS_SENDING) &&
-         rp->p_sendto_e == rc->p_endpoint) {
-          rp->p_reg.retreg = EDSTDIED;         /* report destination died */
-         RTS_UNSET(rp, RTS_SENDING);
-#if DEBUG_ENABLE_IPC_WARNINGS
-         kprintf("endpoint %d / %s send to dying dst ep %d (%s)\n",
+         kprintf("endpoint %d / %s blocked on dead src ep %d / %s\n",
                rp->p_endpoint, rp->p_name, rc->p_endpoint, rc->p_name);
 #endif
       }