BSD 4_3 release
[unix-history] / usr / src / sys / sys / kern_fork.c
index 08e47f4..1ef8e13 100644 (file)
@@ -1,23 +1,29 @@
-/*     kern_fork.c     6.1     83/07/29        */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)kern_fork.c 7.1 (Berkeley) 6/5/86
+ */
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 #include "../machine/psl.h"
 
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 #include "../machine/psl.h"
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/map.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/kernel.h"
-#include "../h/proc.h"
-#include "../h/inode.h"
-#include "../h/seg.h"
-#include "../h/vm.h"
-#include "../h/text.h"
-#include "../h/file.h"
-#include "../h/acct.h"
-#include "../h/quota.h"
+#include "param.h"
+#include "systm.h"
+#include "map.h"
+#include "dir.h"
+#include "user.h"
+#include "kernel.h"
+#include "proc.h"
+#include "inode.h"
+#include "seg.h"
+#include "vm.h"
+#include "text.h"
+#include "file.h"
+#include "acct.h"
+#include "quota.h"
 
 /*
  * fork system call.
 
 /*
  * fork system call.
@@ -47,14 +53,13 @@ fork1(isvfork)
        register a;
 
        a = 0;
        register a;
 
        a = 0;
-       p2 = NULL;
-       for (p1 = proc; p1 < procNPROC; p1++) {
-               if (p1->p_stat==NULL && p2==NULL)
-                       p2 = p1;
-               else {
-                       if (p1->p_uid==u.u_uid && p1->p_stat!=NULL)
+       if (u.u_uid != 0) {
+               for (p1 = allproc; p1; p1 = p1->p_nxt)
+                       if (p1->p_uid == u.u_uid)
+                               a++;
+               for (p1 = zombproc; p1; p1 = p1->p_nxt)
+                       if (p1->p_uid == u.u_uid)
                                a++;
                                a++;
-               }
        }
        /*
         * Disallow if
        }
        /*
         * Disallow if
@@ -62,13 +67,14 @@ fork1(isvfork)
         *  not su and too many procs owned; or
         *  not su and would take last slot.
         */
         *  not su and too many procs owned; or
         *  not su and would take last slot.
         */
+       p2 = freeproc;
        if (p2==NULL)
                tablefull("proc");
        if (p2==NULL)
                tablefull("proc");
-       if (p2==NULL || (u.u_uid!=0 && (p2==procNPROC-1 || a>MAXUPRC))) {
+       if (p2==NULL || (u.u_uid!=0 && (p2->p_nxt == NULL || a>MAXUPRC))) {
                u.u_error = EAGAIN;
                if (!isvfork) {
                u.u_error = EAGAIN;
                if (!isvfork) {
-                       (void) vsexpand(0, &u.u_cdmap, 1);
-                       (void) vsexpand(0, &u.u_csmap, 1);
+                       (void) vsexpand((size_t)0, &u.u_cdmap, 1);
+                       (void) vsexpand((size_t)0, &u.u_csmap, 1);
                }
                goto out;
        }
                }
                goto out;
        }
@@ -76,7 +82,7 @@ fork1(isvfork)
        if (newproc(isvfork)) {
                u.u_r.r_val1 = p1->p_pid;
                u.u_r.r_val2 = 1;  /* child */
        if (newproc(isvfork)) {
                u.u_r.r_val1 = p1->p_pid;
                u.u_r.r_val2 = 1;  /* child */
-               u.u_start = time.tv_sec;
+               u.u_start = time;
                u.u_acflag = AFORK;
                return;
        }
                u.u_acflag = AFORK;
                return;
        }
@@ -94,33 +100,60 @@ out:
 newproc(isvfork)
        int isvfork;
 {
 newproc(isvfork)
        int isvfork;
 {
-       register struct proc *p;
        register struct proc *rpp, *rip;
        register int n;
        register struct file *fp;
        register struct proc *rpp, *rip;
        register int n;
        register struct file *fp;
+       static int pidchecked = 0;
 
 
-       p = NULL;
        /*
         * First, just locate a slot for a process
         * and copy the useful info from this process into it.
         * The panic "cannot happen" because fork has already
         * checked for the existence of a slot.
         */
        /*
         * First, just locate a slot for a process
         * and copy the useful info from this process into it.
         * The panic "cannot happen" because fork has already
         * checked for the existence of a slot.
         */
-retry:
        mpid++;
        mpid++;
+retry:
        if (mpid >= 30000) {
        if (mpid >= 30000) {
-               mpid = 0;
-               goto retry;
+               mpid = 100;
+               pidchecked = 0;
        }
        }
-       for (rpp = proc; rpp < procNPROC; rpp++) {
-               if (rpp->p_stat == NULL && p==NULL)
-                       p = rpp;
-               if (rpp->p_pid==mpid || rpp->p_pgrp==mpid)
-                       goto retry;
+       if (mpid >= pidchecked) {
+               int doingzomb = 0;
+
+               pidchecked = 30000;
+               /*
+                * Scan the proc table to check whether this pid
+                * is in use.  Remember the lowest pid that's greater
+                * than mpid, so we can avoid checking for a while.
+                */
+               rpp = allproc;
+again:
+               for (; rpp != NULL; rpp = rpp->p_nxt) {
+                       if (rpp->p_pid == mpid || rpp->p_pgrp == mpid) {
+                               mpid++;
+                               if (mpid >= pidchecked)
+                                       goto retry;
+                       }
+                       if (rpp->p_pid > mpid && pidchecked > rpp->p_pid)
+                               pidchecked = rpp->p_pid;
+                       if (rpp->p_pgrp > mpid && pidchecked > rpp->p_pgrp)
+                               pidchecked = rpp->p_pgrp;
+               }
+               if (!doingzomb) {
+                       doingzomb = 1;
+                       rpp = zombproc;
+                       goto again;
+               }
        }
        }
-       if ((rpp = p) == NULL)
+       if ((rpp = freeproc) == NULL)
                panic("no procs");
 
                panic("no procs");
 
+       freeproc = rpp->p_nxt;                  /* off freeproc */
+       rpp->p_nxt = allproc;                   /* onto allproc */
+       rpp->p_nxt->p_prev = &rpp->p_nxt;       /*   (allproc is never NULL) */
+       rpp->p_prev = &allproc;
+       allproc = rpp;
+
        /*
         * Make a proc table entry for the new process.
         */
        /*
         * Make a proc table entry for the new process.
         */
@@ -176,14 +209,14 @@ retry:
        rpp->p_pctcpu = 0;
        rpp->p_cpticks = 0;
        n = PIDHASH(rpp->p_pid);
        rpp->p_pctcpu = 0;
        rpp->p_cpticks = 0;
        n = PIDHASH(rpp->p_pid);
-       p->p_idhash = pidhash[n];
+       rpp->p_idhash = pidhash[n];
        pidhash[n] = rpp - proc;
        multprog++;
 
        /*
         * Increase reference counts on shared objects.
         */
        pidhash[n] = rpp - proc;
        multprog++;
 
        /*
         * Increase reference counts on shared objects.
         */
-       for (n = 0; n < NOFILE; n++) {
+       for (n = 0; n <= u.u_lastfile; n++) {
                fp = u.u_ofile[n];
                if (fp == NULL)
                        continue;
                fp = u.u_ofile[n];
                if (fp == NULL)
                        continue;
@@ -194,9 +227,6 @@ retry:
                u.u_rdir->i_count++;
 
        /*
                u.u_rdir->i_count++;
 
        /*
-        * Partially simulate the environment
-        * of the new process so that when it is actually
-        * created (by copying) it will look right.
         * This begins the section where we must prevent the parent
         * from being swapped.
         */
         * This begins the section where we must prevent the parent
         * from being swapped.
         */
@@ -207,7 +237,7 @@ retry:
        /*
         * Make child runnable and add to run queue.
         */
        /*
         * Make child runnable and add to run queue.
         */
-       (void) spl6();
+       (void) splclock();
        rpp->p_stat = SRUN;
        setrq(rpp);
        (void) spl0();
        rpp->p_stat = SRUN;
        setrq(rpp);
        (void) spl0();