BSD 4_4_Lite2 release
[unix-history] / usr / src / sys / kern / kern_proc.c
index 91d9e21..6701793 100644 (file)
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)kern_proc.c 8.4 (Berkeley) 1/4/94
+ *     @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
  * Structure associated with user cacheing.
  */
 struct uidinfo {
  * Structure associated with user cacheing.
  */
 struct uidinfo {
-       struct  uidinfo *ui_next;
-       struct  uidinfo **ui_prev;
+       LIST_ENTRY(uidinfo) ui_hash;
        uid_t   ui_uid;
        long    ui_proccnt;
        uid_t   ui_uid;
        long    ui_proccnt;
-} **uihashtbl;
-u_long uihash;         /* size of hash table - 1 */
-#define        UIHASH(uid)     ((uid) & uihash)
+};
+#define        UIHASH(uid)     (&uihashtbl[(uid) & uihash])
+LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
+u_long uihash;         /* size of hash table - 1 */
 
 /*
 
 /*
- * Allocate a hash table.
+ * Other process lists
  */
  */
-usrinfoinit()
+struct pidhashhead *pidhashtbl;
+u_long pidhash;
+struct pgrphashhead *pgrphashtbl;
+u_long pgrphash;
+struct proclist allproc;
+struct proclist zombproc;
+
+/*
+ * Initialize global process hashing structures.
+ */
+void
+procinit()
 {
 
 {
 
+       LIST_INIT(&allproc);
+       LIST_INIT(&zombproc);
+       pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
+       pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
        uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
 }
 
        uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
 }
 
@@ -79,10 +94,11 @@ chgproccnt(uid, diff)
        uid_t   uid;
        int     diff;
 {
        uid_t   uid;
        int     diff;
 {
-       register struct uidinfo **uipp, *uip, *uiq;
+       register struct uidinfo *uip;
+       register struct uihashhead *uipp;
 
 
-       uipp = &uihashtbl[UIHASH(uid)];
-       for (uip = *uipp; uip; uip = uip->ui_next)
+       uipp = UIHASH(uid);
+       for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next)
                if (uip->ui_uid == uid)
                        break;
        if (uip) {
                if (uip->ui_uid == uid)
                        break;
        if (uip) {
@@ -91,9 +107,7 @@ chgproccnt(uid, diff)
                        return (uip->ui_proccnt);
                if (uip->ui_proccnt < 0)
                        panic("chgproccnt: procs < 0");
                        return (uip->ui_proccnt);
                if (uip->ui_proccnt < 0)
                        panic("chgproccnt: procs < 0");
-               if (uiq = uip->ui_next)
-                       uiq->ui_prev = uip->ui_prev;
-               *uip->ui_prev = uiq;
+               LIST_REMOVE(uip, ui_hash);
                FREE(uip, M_PROC);
                return (0);
        }
                FREE(uip, M_PROC);
                return (0);
        }
@@ -103,11 +117,7 @@ chgproccnt(uid, diff)
                panic("chgproccnt: lost user");
        }
        MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
                panic("chgproccnt: lost user");
        }
        MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
-       if (uiq = *uipp)
-               uiq->ui_prev = &uip->ui_next;
-       uip->ui_next = uiq;
-       uip->ui_prev = uipp;
-       *uipp = uip;
+       LIST_INSERT_HEAD(uipp, uip, ui_hash);
        uip->ui_uid = uid;
        uip->ui_proccnt = diff;
        return (diff);
        uip->ui_uid = uid;
        uip->ui_proccnt = diff;
        return (diff);
@@ -135,7 +145,7 @@ pfind(pid)
 {
        register struct proc *p;
 
 {
        register struct proc *p;
 
-       for (p = pidhash[PIDHASH(pid)]; p != NULL; p = p->p_hash)
+       for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next)
                if (p->p_pid == pid)
                        return (p);
        return (NULL);
                if (p->p_pid == pid)
                        return (p);
        return (NULL);
@@ -150,8 +160,8 @@ pgfind(pgid)
 {
        register struct pgrp *pgrp;
 
 {
        register struct pgrp *pgrp;
 
-       for (pgrp = pgrphash[PIDHASH(pgid)];
-           pgrp != NULL; pgrp = pgrp->pg_hforw)
+       for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0;
+            pgrp = pgrp->pg_hash.le_next)
                if (pgrp->pg_id == pgid)
                        return (pgrp);
        return (NULL);
                if (pgrp->pg_id == pgid)
                        return (pgrp);
        return (NULL);
@@ -160,14 +170,13 @@ pgfind(pgid)
 /*
  * Move p to a new or existing process group (and session)
  */
 /*
  * Move p to a new or existing process group (and session)
  */
+int
 enterpgrp(p, pgid, mksess)
        register struct proc *p;
        pid_t pgid;
        int mksess;
 {
        register struct pgrp *pgrp = pgfind(pgid);
 enterpgrp(p, pgid, mksess)
        register struct proc *p;
        pid_t pgid;
        int mksess;
 {
        register struct pgrp *pgrp = pgfind(pgid);
-       register struct proc **pp;
-       int n;
 
 #ifdef DIAGNOSTIC
        if (pgrp != NULL && mksess)     /* firewalls */
 
 #ifdef DIAGNOSTIC
        if (pgrp != NULL && mksess)     /* firewalls */
@@ -186,7 +195,7 @@ enterpgrp(p, pgid, mksess)
                        panic("enterpgrp: new pgrp and pid != pgid");
 #endif
                MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
                        panic("enterpgrp: new pgrp and pid != pgid");
 #endif
                MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
-                      M_WAITOK);
+                   M_WAITOK);
                if ((np = pfind(savepid)) == NULL || np != p)
                        return (ESRCH);
                if (mksess) {
                if ((np = pfind(savepid)) == NULL || np != p)
                        return (ESRCH);
                if (mksess) {
@@ -196,7 +205,7 @@ enterpgrp(p, pgid, mksess)
                         * new session
                         */
                        MALLOC(sess, struct session *, sizeof(struct session),
                         * new session
                         */
                        MALLOC(sess, struct session *, sizeof(struct session),
-                               M_SESSION, M_WAITOK);
+                           M_SESSION, M_WAITOK);
                        sess->s_leader = p;
                        sess->s_count = 1;
                        sess->s_ttyvp = NULL;
                        sess->s_leader = p;
                        sess->s_count = 1;
                        sess->s_ttyvp = NULL;
@@ -214,10 +223,9 @@ enterpgrp(p, pgid, mksess)
                        pgrp->pg_session->s_count++;
                }
                pgrp->pg_id = pgid;
                        pgrp->pg_session->s_count++;
                }
                pgrp->pg_id = pgid;
-               pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)];
-               pgrphash[n] = pgrp;
+               LIST_INIT(&pgrp->pg_members);
+               LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
                pgrp->pg_jobc = 0;
                pgrp->pg_jobc = 0;
-               pgrp->pg_mem = NULL;
        } else if (pgrp == p->p_pgrp)
                return (0);
 
        } else if (pgrp == p->p_pgrp)
                return (0);
 
@@ -229,52 +237,24 @@ enterpgrp(p, pgid, mksess)
        fixjobc(p, pgrp, 1);
        fixjobc(p, p->p_pgrp, 0);
 
        fixjobc(p, pgrp, 1);
        fixjobc(p, p->p_pgrp, 0);
 
-       /*
-        * unlink p from old process group
-        */
-       for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) {
-               if (*pp == p) {
-                       *pp = p->p_pgrpnxt;
-                       break;
-               }
-       }
-#ifdef DIAGNOSTIC
-       if (pp == NULL)
-               panic("enterpgrp: can't find p on old pgrp");
-#endif
-       /*
-        * delete old if empty
-        */
-       if (p->p_pgrp->pg_mem == 0)
+       LIST_REMOVE(p, p_pglist);
+       if (p->p_pgrp->pg_members.lh_first == 0)
                pgdelete(p->p_pgrp);
                pgdelete(p->p_pgrp);
-       /*
-        * link into new one
-        */
        p->p_pgrp = pgrp;
        p->p_pgrp = pgrp;
-       p->p_pgrpnxt = pgrp->pg_mem;
-       pgrp->pg_mem = p;
+       LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
        return (0);
 }
 
 /*
  * remove process from process group
  */
        return (0);
 }
 
 /*
  * remove process from process group
  */
+int
 leavepgrp(p)
        register struct proc *p;
 {
 leavepgrp(p)
        register struct proc *p;
 {
-       register struct proc **pp = &p->p_pgrp->pg_mem;
 
 
-       for (; *pp; pp = &(*pp)->p_pgrpnxt) {
-               if (*pp == p) {
-                       *pp = p->p_pgrpnxt;
-                       break;
-               }
-       }
-#ifdef DIAGNOSTIC
-       if (pp == NULL)
-               panic("leavepgrp: can't find p in pgrp");
-#endif
-       if (!p->p_pgrp->pg_mem)
+       LIST_REMOVE(p, p_pglist);
+       if (p->p_pgrp->pg_members.lh_first == 0)
                pgdelete(p->p_pgrp);
        p->p_pgrp = 0;
        return (0);
                pgdelete(p->p_pgrp);
        p->p_pgrp = 0;
        return (0);
@@ -283,24 +263,15 @@ leavepgrp(p)
 /*
  * delete a process group
  */
 /*
  * delete a process group
  */
+void
 pgdelete(pgrp)
        register struct pgrp *pgrp;
 {
 pgdelete(pgrp)
        register struct pgrp *pgrp;
 {
-       register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)];
 
        if (pgrp->pg_session->s_ttyp != NULL && 
            pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
                pgrp->pg_session->s_ttyp->t_pgrp = NULL;
 
        if (pgrp->pg_session->s_ttyp != NULL && 
            pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
                pgrp->pg_session->s_ttyp->t_pgrp = NULL;
-       for (; *pgp; pgp = &(*pgp)->pg_hforw) {
-               if (*pgp == pgrp) {
-                       *pgp = pgrp->pg_hforw;
-                       break;
-               }
-       }
-#ifdef DIAGNOSTIC
-       if (pgp == NULL)
-               panic("pgdelete: can't find pgrp on hash chain");
-#endif
+       LIST_REMOVE(pgrp, pg_hash);
        if (--pgrp->pg_session->s_count == 0)
                FREE(pgrp->pg_session, M_SESSION);
        FREE(pgrp, M_PGRP);
        if (--pgrp->pg_session->s_count == 0)
                FREE(pgrp->pg_session, M_SESSION);
        FREE(pgrp, M_PGRP);
@@ -318,6 +289,7 @@ static void orphanpg();
  * entering == 0 => p is leaving specified group.
  * entering == 1 => p is entering specified group.
  */
  * entering == 0 => p is leaving specified group.
  * entering == 1 => p is entering specified group.
  */
+void
 fixjobc(p, pgrp, entering)
        register struct proc *p;
        register struct pgrp *pgrp;
 fixjobc(p, pgrp, entering)
        register struct proc *p;
        register struct pgrp *pgrp;
@@ -342,7 +314,7 @@ fixjobc(p, pgrp, entering)
         * their process groups; if so, adjust counts for children's
         * process groups.
         */
         * their process groups; if so, adjust counts for children's
         * process groups.
         */
-       for (p = p->p_cptr; p; p = p->p_osptr)
+       for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next)
                if ((hispgrp = p->p_pgrp) != pgrp &&
                    hispgrp->pg_session == mysession &&
                    p->p_stat != SZOMB)
                if ((hispgrp = p->p_pgrp) != pgrp &&
                    hispgrp->pg_session == mysession &&
                    p->p_stat != SZOMB)
@@ -363,9 +335,10 @@ orphanpg(pg)
 {
        register struct proc *p;
 
 {
        register struct proc *p;
 
-       for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
+       for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) {
                if (p->p_stat == SSTOP) {
                if (p->p_stat == SSTOP) {
-                       for (p = pg->pg_mem; p; p = p->p_pgrpnxt) {
+                       for (p = pg->pg_members.lh_first; p != 0;
+                           p = p->p_pglist.le_next) {
                                psignal(p, SIGHUP);
                                psignal(p, SIGCONT);
                        }
                                psignal(p, SIGHUP);
                                psignal(p, SIGCONT);
                        }
@@ -374,28 +347,28 @@ orphanpg(pg)
        }
 }
 
        }
 }
 
-#ifdef debug
-/* DEBUG */
+#ifdef DEBUG
 pgrpdump()
 {
        register struct pgrp *pgrp;
        register struct proc *p;
        register i;
 
 pgrpdump()
 {
        register struct pgrp *pgrp;
        register struct proc *p;
        register i;
 
-       for (i=0; i<PIDHSZ; i++) {
-               if (pgrphash[i]) {
-                 printf("\tindx %d\n", i);
-                 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) {
-                   printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
-                       pgrp, pgrp->pg_id, pgrp->pg_session,
-                       pgrp->pg_session->s_count, pgrp->pg_mem);
-                   for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) {
-                       printf("\t\tpid %d addr %x pgrp %x\n", 
-                               p->p_pid, p, p->p_pgrp);
-                   }
-                 }
-
+       for (i = 0; i <= pgrphash; i++) {
+               if (pgrp = pgrphashtbl[i].lh_first) {
+                       printf("\tindx %d\n", i);
+                       for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) {
+                               printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
+                                   pgrp, pgrp->pg_id, pgrp->pg_session,
+                                   pgrp->pg_session->s_count,
+                                   pgrp->pg_members.lh_first);
+                               for (p = pgrp->pg_members.lh_first; p != 0;
+                                   p = p->p_pglist.le_next) {
+                                       printf("\t\tpid %d addr %x pgrp %x\n", 
+                                           p->p_pid, p, p->p_pgrp);
+                               }
+                       }
                }
        }
 }
                }
        }
 }
-#endif /* debug */
+#endif /* DEBUG */