From Lite2: proc LIST changes.

Reviewed by:	david & bde
This commit is contained in:
hsu 1996-03-11 06:05:03 +00:00
parent 633fd1e2eb
commit 3efcd29606
6 changed files with 111 additions and 214 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
* $Id: kern_exit.c,v 1.29 1996/02/25 09:49:57 hsu Exp $
* $Id: kern_exit.c,v 1.29 1996/03/11 02:24:21 hsu Exp $
*/
#include "opt_ktrace.h"
@ -208,34 +208,19 @@ exit1(p, rv)
* Remove proc from allproc queue and pidhash chain.
* Place onto zombproc. Unlink from parent's child list.
*/
if ((*p->p_prev = p->p_next))
p->p_next->p_prev = p->p_prev;
if ((p->p_next = zombproc))
p->p_next->p_prev = &p->p_next;
p->p_prev = &zombproc;
zombproc = p;
LIST_REMOVE(p, p_list);
LIST_INSERT_HEAD(&zombproc, p, p_list);
p->p_stat = SZOMB;
for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash)
if (*pp == p) {
*pp = p->p_hash;
goto done;
}
panic("exit");
done:
LIST_REMOVE(p, p_hash);
if (p->p_cptr) /* only need this if any child is S_ZOMB */
q = p->p_children.lh_first;
if (q) /* only need this if any child is S_ZOMB */
wakeup((caddr_t) initproc);
for (q = p->p_cptr; q != NULL; q = nq) {
nq = q->p_osptr;
if (nq != NULL)
nq->p_ysptr = NULL;
if (initproc->p_cptr)
initproc->p_cptr->p_ysptr = q;
q->p_osptr = initproc->p_cptr;
q->p_ysptr = NULL;
initproc->p_cptr = q;
for (; q != 0; q = nq) {
nq = q->p_sibling.le_next;
LIST_REMOVE(q, p_sibling);
LIST_INSERT_HEAD(&initproc->p_children, q, p_sibling);
q->p_pptr = initproc;
/*
* Traced processes are killed
@ -246,7 +231,6 @@ exit1(p, rv)
psignal(q, SIGKILL);
}
}
p->p_cptr = NULL;
/*
* Save exit status and final rusage info, adding in child rusage
@ -364,7 +348,7 @@ wait1(q, uap, retval, compat)
#endif
loop:
nfound = 0;
for (p = q->p_cptr; p; p = p->p_osptr) {
for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
if (uap->pid != WAIT_ANY &&
p->p_pid != uap->pid && p->p_pgid != -uap->pid)
continue;
@ -432,14 +416,8 @@ wait1(q, uap, retval, compat)
* Unlink it from its process group and free it.
*/
leavepgrp(p);
if ((*p->p_prev = p->p_next)) /* off zombproc */
p->p_next->p_prev = p->p_prev;
if ((q = p->p_ysptr))
q->p_osptr = p->p_osptr;
if ((q = p->p_osptr))
q->p_ysptr = p->p_ysptr;
if ((q = p->p_pptr)->p_cptr == p)
q->p_cptr = p->p_osptr;
LIST_REMOVE(p, p_list); /* off zombproc */
LIST_REMOVE(p, p_sibling);
/*
* Give machine-dependent layer a chance
@ -489,28 +467,11 @@ proc_reparent(child, parent)
register struct proc *child;
register struct proc *parent;
{
register struct proc *o;
register struct proc *y;
if (child->p_pptr == parent)
return;
/* fix up the child linkage for the old parent */
o = child->p_osptr;
y = child->p_ysptr;
if (y)
y->p_osptr = o;
if (o)
o->p_ysptr = y;
if (child->p_pptr->p_cptr == child)
child->p_pptr->p_cptr = o;
/* fix up child linkage for new parent */
o = parent->p_cptr;
if (o)
o->p_ysptr = child;
child->p_osptr = o;
child->p_ysptr = NULL;
parent->p_cptr = child;
LIST_REMOVE(child, p_sibling);
LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
child->p_pptr = parent;
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $Id: kern_fork.c,v 1.17 1996/02/23 18:49:17 peter Exp $
* $Id: kern_fork.c,v 1.18 1996/03/03 19:48:45 dyson Exp $
*/
#include "opt_ktrace.h"
@ -195,9 +195,9 @@ fork1(p1, forktype, rforkflags, retval)
* is in use. Remember the lowest pid that's greater
* than nextpid, so we can avoid checking for a while.
*/
p2 = (struct proc *)allproc;
p2 = allproc.lh_first;
again:
for (; p2 != NULL; p2 = p2->p_next) {
for (; p2 != 0; p2 = p2->p_list.le_next) {
while (p2->p_pid == nextpid ||
p2->p_pgrp->pg_id == nextpid) {
nextpid++;
@ -212,42 +212,17 @@ fork1(p1, forktype, rforkflags, retval)
}
if (!doingzomb) {
doingzomb = 1;
p2 = zombproc;
p2 = zombproc.lh_first;
goto again;
}
}
/*
* Link onto allproc (this should probably be delayed).
* Heavy use of volatile here to prevent the compiler from
* rearranging code. Yes, it *is* terribly ugly, but at least
* it works.
*/
p2 = newproc;
#define Vp2 ((volatile struct proc *)p2)
Vp2->p_stat = SIDL; /* protect against others */
Vp2->p_pid = nextpid;
/*
* This is really:
* p2->p_next = allproc;
* allproc->p_prev = &p2->p_next;
* p2->p_prev = &allproc;
* allproc = p2;
* The assignment via allproc is legal since it is never NULL.
*/
*(volatile struct proc **)&Vp2->p_next = allproc;
*(volatile struct proc ***)&allproc->p_prev =
(volatile struct proc **)&Vp2->p_next;
*(volatile struct proc ***)&Vp2->p_prev = &allproc;
allproc = Vp2;
#undef Vp2
p2->p_stat = SIDL; /* protect against others */
p2->p_pid = nextpid;
LIST_INSERT_HEAD(&allproc, p2, p_list);
p2->p_forw = p2->p_back = NULL; /* shouldn't be necessary */
/* Insert on the hash chain. */
hash = &pidhash[PIDHASH(p2->p_pid)];
p2->p_hash = *hash;
*hash = p2;
LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
/*
* Make a proc table entry for the new process.
@ -302,13 +277,11 @@ fork1(p1, forktype, rforkflags, retval)
p2->p_flag |= P_CONTROLT;
if (forktype == ISVFORK)
p2->p_flag |= P_PPWAIT;
p2->p_pgrpnxt = p1->p_pgrpnxt;
p1->p_pgrpnxt = p2;
LIST_INSERT_AFTER(p1, p2, p_pglist);
p2->p_pptr = p1;
p2->p_osptr = p1->p_cptr;
if (p1->p_cptr)
p1->p_cptr->p_ysptr = p2;
p1->p_cptr = p2;
LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
LIST_INIT(&p2->p_children);
#ifdef KTRACE
/*
* Copy traceflag and tracefile if enabled.

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_ktrace.c 8.2 (Berkeley) 9/23/93
* $Id: kern_ktrace.c,v 1.9 1995/12/14 08:31:23 phk Exp $
* $Id: kern_ktrace.c,v 1.10 1996/01/03 21:42:04 wollman Exp $
*/
#include "opt_ktrace.h"
@ -282,7 +282,7 @@ ktrace(curp, uap, retval)
* Clear all uses of the tracefile
*/
if (ops == KTROP_CLEARFILE) {
for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_tracep == vp) {
if (ktrcanset(curp, p)) {
p->p_tracep = NULL;
@ -314,7 +314,7 @@ ktrace(curp, uap, retval)
error = ESRCH;
goto done;
}
for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt)
for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next)
if (descend)
ret |= ktrsetchildren(curp, p, ops, facs, vp);
else
@ -401,20 +401,16 @@ ktrsetchildren(curp, top, ops, facs, vp)
* otherwise do any siblings, and if done with this level,
* follow back up the tree (but not past top).
*/
if (p->p_cptr)
p = p->p_cptr;
else if (p == top)
return (ret);
else if (p->p_osptr)
p = p->p_osptr;
if (p->p_children.lh_first)
p = p->p_children.lh_first;
else for (;;) {
p = p->p_pptr;
if (p == top)
return (ret);
if (p->p_osptr) {
p = p->p_osptr;
if (p->p_sibling.le_next) {
p = p->p_sibling.le_next;
break;
}
p = p->p_pptr;
}
}
/*NOTREACHED*/
@ -457,7 +453,7 @@ ktrwrite(vp, kth)
*/
log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
error);
for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_tracep == vp) {
p->p_tracep = NULL;
p->p_traceflag = 0;

View File

@ -30,8 +30,8 @@
* 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
* $Id: kern_proc.c,v 1.14 1995/12/14 08:31:30 phk Exp $
* @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
* $Id: kern_proc.c,v 1.15 1996/01/01 17:01:03 peter Exp $
*/
#include <sys/param.h>
@ -62,32 +62,43 @@ struct prochd qs[NQS]; /* as good a place as any... */
struct prochd rtqs[NQS]; /* Space for REALTIME queues too */
struct prochd idqs[NQS]; /* Space for IDLE queues too */
volatile struct proc *allproc; /* all processes */
struct proc *zombproc; /* just zombies */
static void pgdelete __P((struct pgrp *));
/*
* Structure associated with user cacheing.
*/
static struct uidinfo {
struct uidinfo *ui_next;
struct uidinfo **ui_prev;
struct uidinfo {
LIST_ENTRY(uidinfo) ui_hash;
uid_t ui_uid;
long ui_proccnt;
} **uihashtbl;
static u_long uihash; /* size of hash table - 1 */
#define UIHASH(uid) ((uid) & uihash)
};
#define UIHASH(uid) (&uihashtbl[(uid) & uihash])
LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
static u_long uihash; /* size of hash table - 1 */
static void orphanpg __P((struct pgrp *pg));
/*
* Allocate a hash table.
* Other process lists
*/
struct pidhashhead *pidhashtbl;
u_long pidhash;
struct pgrphashhead *pgrphashtbl;
u_long pgrphash;
struct proclist allproc;
struct proclist zombproc;
/*
* Initialize global process hashing structures.
*/
void
usrinfoinit()
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);
}
@ -100,10 +111,11 @@ chgproccnt(uid, 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) {
@ -112,9 +124,7 @@ chgproccnt(uid, diff)
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);
}
@ -124,11 +134,7 @@ chgproccnt(uid, diff)
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);
@ -157,7 +163,7 @@ pfind(pid)
{
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);
@ -172,8 +178,8 @@ pgfind(pgid)
{
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);
@ -189,8 +195,6 @@ enterpgrp(p, pgid, mksess)
int mksess;
{
register struct pgrp *pgrp = pgfind(pgid);
register struct proc **pp;
int n;
#ifdef DIAGNOSTIC
if (pgrp != NULL && mksess) /* firewalls */
@ -209,7 +213,7 @@ enterpgrp(p, pgid, mksess)
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) {
@ -219,7 +223,7 @@ enterpgrp(p, pgid, mksess)
* 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;
@ -237,10 +241,9 @@ enterpgrp(p, pgid, mksess)
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_mem = NULL;
} else if (pgrp == p->p_pgrp)
return (0);
@ -252,30 +255,11 @@ enterpgrp(p, pgid, mksess)
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);
/*
* link into new one
*/
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);
}
@ -286,19 +270,9 @@ int
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);
@ -311,21 +285,11 @@ static void
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;
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);
@ -366,7 +330,7 @@ fixjobc(p, pgrp, entering)
* 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)
@ -387,9 +351,10 @@ orphanpg(pg)
{
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) {
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);
}
@ -398,31 +363,31 @@ orphanpg(pg)
}
}
#ifdef debug
/* DEBUG */
#ifdef DEBUG
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 */
/*
* Fill in an eproc structure for the specified process.
@ -504,10 +469,10 @@ sysctl_kern_proc SYSCTL_HANDLER_ARGS
if (error)
return (error);
}
p = (struct proc *)allproc;
p = allproc.lh_first;
doingzomb = 0;
again:
for (; p != NULL; p = p->p_next) {
for (; p != 0; p = p->p_list.le_next) {
/*
* Skip embryonic processes.
*/
@ -559,7 +524,7 @@ sysctl_kern_proc SYSCTL_HANDLER_ARGS
return (error);
}
if (doingzomb == 0) {
p = zombproc;
p = zombproc.lh_first;
doingzomb++;
goto again;
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
* $Id: kern_sig.c,v 1.19 1996/03/02 19:38:09 peter Exp $
* $Id: kern_sig.c,v 1.20 1996/03/11 02:22:02 hsu Exp $
*/
#include "opt_ktrace.h"
@ -540,7 +540,7 @@ killpg1(cp, signum, pgid, all)
/*
* broadcast
*/
for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !CANSIGNAL(cp, pc, p, signum))
continue;
@ -559,7 +559,8 @@ killpg1(cp, signum, pgid, all)
if (pgrp == NULL)
return (ESRCH);
}
for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
for (p = pgrp->pg_members.lh_first; p != 0;
p = p->p_pglist.le_next) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p->p_stat == SZOMB ||
!CANSIGNAL(cp, pc, p, signum))
@ -657,7 +658,8 @@ pgsignal(pgrp, signum, checkctty)
register struct proc *p;
if (pgrp)
for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
for (p = pgrp->pg_members.lh_first; p != 0;
p = p->p_pglist.le_next)
if (checkctty == 0 || p->p_flag & P_CONTROLT)
psignal(p, signum);
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)tty.c 8.8 (Berkeley) 1/21/94
* $Id: tty.c,v 1.78 1995/12/16 21:45:02 bde Exp $
* $Id: tty.c,v 1.79 1996/03/02 18:24:06 peter Exp $
*/
/*-
@ -2177,11 +2177,11 @@ ttyinfo(tp)
ttyprintf(tp, "not a controlling terminal\n");
else if (tp->t_pgrp == NULL)
ttyprintf(tp, "no foreground process group\n");
else if ((p = tp->t_pgrp->pg_mem) == NULL)
else if ((p = tp->t_pgrp->pg_members.lh_first) == 0)
ttyprintf(tp, "empty foreground process group\n");
else {
/* Pick interesting process. */
for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
for (pick = NULL; p != 0; p = p->p_pglist.le_next)
if (proc_compare(pick, p))
pick = p;