ptab_end: redo the various process table scans
authorAlan Cox <alan@linux.intel.com>
Sat, 3 Jan 2015 15:41:36 +0000 (15:41 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 3 Jan 2015 15:41:36 +0000 (15:41 +0000)
Currently we do a compare with &ptab[maxproc], which generates a pile of
maths to scale maxproc each time around the loop. This is *silly* and its
repeated in various places where it takes space, time and registers.

Instead in start.c evaluate &ptab[maxproc] once after maxproc is computed
and save it as ptab_end. Our comparisons now now don't do the math. This
saves us 180 bytes, or nearly half the cost of adding flock support.

Kernel/include/kdata.h
Kernel/kdata.c
Kernel/process.c
Kernel/start.c
Kernel/swap.c
Kernel/syscall_proc.c

index c9d4232..366cc3c 100644 (file)
@@ -21,6 +21,7 @@ extern uint16_t root_dev;  /* Device number of root filesystem. */
 
 extern struct blkbuf bufpool[NBUFS];
 extern struct p_tab ptab[PTABSIZE];
+extern struct p_tab *ptab_end;
 extern struct oft of_tab[OFTSIZE];       /* Open File Table */
 extern struct cinode i_tab[ITABSIZE];    /* In-core inode table */
 extern struct mount fs_tab[NMOUNTS];    /* Mount table */
index 19ddd99..264a2d6 100644 (file)
@@ -26,6 +26,7 @@ struct runload loadavg[3] = {
 struct blkbuf bufpool[NBUFS];
 
 struct p_tab ptab[PTABSIZE];
+struct p_tab *ptab_end;                /* Points to first byte off end */
 struct oft of_tab[OFTSIZE];    /* Open File Table */
 struct cinode i_tab[ITABSIZE]; /* In-core inode table */
 struct mount fs_tab[NMOUNTS];  /* In-core mount table */
index f26b1d3..8d8dcd3 100644 (file)
@@ -61,7 +61,7 @@ void wakeup(void *event)
        kprintf("wakeup(0x%x)\n", event);
 #endif
        irq = di();
-       for (p = ptab; p < ptab + maxproc; ++p) {
+       for (p = ptab; p < ptab_end; ++p) {
                if (p->p_status > P_RUNNING && p->p_wait == event) {
 #ifdef DEBUG
                        kprintf("wakeup: found proc 0x%x pid %d\n",
@@ -102,7 +102,7 @@ ptptr getproc(void)
 #ifdef DEBUG
 #ifdef DEBUGREALLYHARD
        kputs("getproc start ... ");
-       for (pp = ptab; pp < ptab + maxproc; pp++)
+       for (pp = ptab; pp < ptab_end; pp++)
                kprintf("ptab[0x%x]: pid=%d uid=%d status=%d, page=0x%x\n",
                        pp, pp->p_pid, pp->p_uid, pp->p_status,
                        pp->p_page);
@@ -116,7 +116,7 @@ ptptr getproc(void)
 
        for (;;) {
                getproc_nextp++;
-               if (getproc_nextp >= ptab + maxproc) {
+               if (getproc_nextp >= ptab_end) {
                        getproc_nextp = ptab;
                }
 
@@ -247,7 +247,7 @@ ptptr ptab_alloc(void)
        udata.u_error = EAGAIN;
 
        irq = di();
-       for (p = ptab; p < ptab + maxproc; p++)
+       for (p = ptab; p < ptab_end; p++)
                if (p->p_status == P_EMPTY) {
                        newp = p;
                        break;
@@ -262,7 +262,7 @@ ptptr ptab_alloc(void)
                        if (nextpid++ > MAXPID)
                                nextpid = 20;
                        newp->p_pid = nextpid;
-                       for (p = ptab; p < ptab + maxproc; p++)
+                       for (p = ptab; p < ptab_end; p++)
                                if (p->p_status != P_EMPTY
                                    && p->p_pid == nextpid)
                                        newp->p_pid = 0;        /* try again */
@@ -338,7 +338,7 @@ void timer_interrupt(void)
                ticks.full++;
 
                /* Update process alarm clocks and timeouts */
-               for (p = ptab; p < ptab + maxproc; ++p) {
+               for (p = ptab; p < ptab_end; ++p) {
                        if (p->p_alarm) {
                                p->p_alarm--;
                                if (!p->p_alarm)
@@ -421,7 +421,7 @@ void unix_syscall(void)
 void sgrpsig(uint16_t pgrp, uint16_t sig)
 {
        ptptr p;
-       for (p = ptab; p < ptab + maxproc; ++p) {
+       for (p = ptab; p < ptab_end; ++p) {
                if (-p->p_pgrp == pgrp)
                        ssig(p, sig);
        }
@@ -577,7 +577,7 @@ void doexit(int16_t val, int16_t val2)
               2 * sizeof(clock_t));
 
        /* See if we have any children. Set child's parents to our parent */
-       for (p = ptab; p < ptab + maxproc; ++p) {
+       for (p = ptab; p < ptab_end; ++p) {
                if (p->p_status && p->p_pptr == udata.u_ptab
                    && p != udata.u_ptab)
                        p->p_pptr = udata.u_ptab->p_pptr;
index f2dff56..96ab019 100644 (file)
@@ -139,6 +139,10 @@ void fuzix_main(void)
 #else
        maxproc = PTABSIZE;
 #endif
+        /* Used as a stop marker to make compares fast on process
+           scheduling and the like */
+        ptab_end = &ptab[maxproc];
+
        /* Parameters message */
        kprintf("%dkB total RAM, %dkB available to processes (%d processes max)\n", ramsize, procmem, maxproc);
        bufinit();
index ad99282..f9b9476 100644 (file)
@@ -172,7 +172,7 @@ static ptptr swapvictim(ptptr p, int notself)
                        }
                }
                c++;
-               if (c > ptab + maxproc)
+               if (c > ptab_end)
                        c = ptab;
        }
        while (c != getproc_nextp);
index 2624e76..11894fd 100644 (file)
@@ -276,7 +276,7 @@ int16_t _waitpid(void)
        }
 
        /* See if we have any children. */
-       for (p = ptab; p < ptab + maxproc; ++p) {
+       for (p = ptab; p < ptab_end; ++p) {
                if (p->p_status && p->p_pptr == udata.u_ptab
                    && p != udata.u_ptab)
                        goto ok;
@@ -293,7 +293,7 @@ int16_t _waitpid(void)
                        udata.u_error = EINTR;
                        return (-1);
                }
-               for (p = ptab; p < ptab + maxproc; ++p) {
+               for (p = ptab; p < ptab_end; ++p) {
                        if (p->p_status == P_ZOMBIE
                            && p->p_pptr == udata.u_ptab) {
                                if (pid == -1 || p->p_pid == pid
@@ -499,7 +499,7 @@ int16_t _kill(void)
        if (pid == 0)
                udata.u_argn = -udata.u_ptab->p_pgrp;
 
-       for (p = ptab; p < ptab + maxproc; ++p) {
+       for (p = ptab; p < ptab_end; ++p) {
                /* No overlap here */
                if (-p->p_pgrp == pid || p->p_pid == pid) {
                        f = 1;  /* Found */