VFLUSHO -> VDISCARD
[unix-history] / usr / src / sys / kern / kern_malloc.c
index 084d07a..91d6b6e 100644 (file)
@@ -3,13 +3,18 @@
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  *
- *     @(#)kern_malloc.c       7.8 (Berkeley) %G%
+ *     @(#)kern_malloc.c       7.17 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
 #include "kernel.h"
 #include "malloc.h"
 
 #include "kernel.h"
 #include "malloc.h"
 
-#include "../machine/pte.h"
+#include "machine/pte.h"
 
 struct kmembuckets bucket[MINBUCKET + 16];
 struct kmemstats kmemstats[M_LAST];
 struct kmemusage *kmemusage;
 long wantkmemmap;
 
 struct kmembuckets bucket[MINBUCKET + 16];
 struct kmemstats kmemstats[M_LAST];
 struct kmemusage *kmemusage;
 long wantkmemmap;
+long malloc_reentered;
+#define IN { if (malloc_reentered) panic("malloc reentered");\
+                       else malloc_reentered = 1;}
+#define OUT (malloc_reentered = 0)
 
 /*
  * Allocate a block of memory
 
 /*
  * Allocate a block of memory
@@ -34,29 +43,37 @@ long wantkmemmap;
 qaddr_t
 malloc(size, type, flags)
        unsigned long size;
 qaddr_t
 malloc(size, type, flags)
        unsigned long size;
-       long type, flags;
+       int type, flags;
 {
        register struct kmembuckets *kbp;
        register struct kmemusage *kup;
 {
        register struct kmembuckets *kbp;
        register struct kmemusage *kup;
-       long indx, npg, alloc, allocsize, s;
+       long indx, npg, alloc, allocsize;
+       int s;
        caddr_t va, cp;
 #ifdef KMEMSTATS
        register struct kmemstats *ksp = &kmemstats[type];
        caddr_t va, cp;
 #ifdef KMEMSTATS
        register struct kmemstats *ksp = &kmemstats[type];
+
+       if (((unsigned long)type) > M_LAST)
+               panic("malloc - bogus type");
 #endif
 
        indx = BUCKETINDX(size);
        kbp = &bucket[indx];
        s = splimp();
 #endif
 
        indx = BUCKETINDX(size);
        kbp = &bucket[indx];
        s = splimp();
+       IN;
 again:
 #ifdef KMEMSTATS
        while (ksp->ks_memuse >= ksp->ks_limit) {
                if (flags & M_NOWAIT) {
 again:
 #ifdef KMEMSTATS
        while (ksp->ks_memuse >= ksp->ks_limit) {
                if (flags & M_NOWAIT) {
+                       OUT;
                        splx(s);
                        return (0);
                }
                if (ksp->ks_limblocks < 65535)
                        ksp->ks_limblocks++;
                        splx(s);
                        return (0);
                }
                if (ksp->ks_limblocks < 65535)
                        ksp->ks_limblocks++;
+               OUT;
                sleep((caddr_t)ksp, PSWP+2);
                sleep((caddr_t)ksp, PSWP+2);
+               IN;
        }
 #endif
        if (kbp->kb_next == NULL) {
        }
 #endif
        if (kbp->kb_next == NULL) {
@@ -66,12 +83,14 @@ again:
                        allocsize = 1 << indx;
                npg = clrnd(btoc(allocsize));
                if ((flags & M_NOWAIT) && freemem < npg) {
                        allocsize = 1 << indx;
                npg = clrnd(btoc(allocsize));
                if ((flags & M_NOWAIT) && freemem < npg) {
+                       OUT;
                        splx(s);
                        return (0);
                }
                alloc = rmalloc(kmemmap, npg);
                if (alloc == 0) {
                        if (flags & M_NOWAIT) {
                        splx(s);
                        return (0);
                }
                alloc = rmalloc(kmemmap, npg);
                if (alloc == 0) {
                        if (flags & M_NOWAIT) {
+                               OUT;
                                splx(s);
                                return (0);
                        }
                                splx(s);
                                return (0);
                        }
@@ -80,13 +99,15 @@ again:
                                ksp->ks_mapblocks++;
 #endif
                        wantkmemmap++;
                                ksp->ks_mapblocks++;
 #endif
                        wantkmemmap++;
+                       OUT;
                        sleep((caddr_t)&wantkmemmap, PSWP+2);
                        sleep((caddr_t)&wantkmemmap, PSWP+2);
+                       IN;
                        goto again;
                }
                alloc -= CLSIZE;                /* convert to base 0 */
                        goto again;
                }
                alloc -= CLSIZE;                /* convert to base 0 */
-               (void) vmemall(&kmempt[alloc], npg, &proc[0], CSYS);
+               (void) vmemall(&kmempt[alloc], (int)npg, &proc[0], CSYS);
                va = (caddr_t) kmemxtob(alloc);
                va = (caddr_t) kmemxtob(alloc);
-               vmaccess(&kmempt[alloc], va, npg);
+               vmaccess(&kmempt[alloc], va, (int)npg);
 #ifdef KMEMSTATS
                kbp->kb_total += kbp->kb_elmpercl;
 #endif
 #ifdef KMEMSTATS
                kbp->kb_total += kbp->kb_elmpercl;
 #endif
@@ -106,12 +127,21 @@ again:
                kbp->kb_totalfree += kbp->kb_elmpercl;
 #endif
                kbp->kb_next = va + (npg * NBPG) - allocsize;
                kbp->kb_totalfree += kbp->kb_elmpercl;
 #endif
                kbp->kb_next = va + (npg * NBPG) - allocsize;
-               for (cp = kbp->kb_next; cp > va; cp -= allocsize)
-                       *(caddr_t *)cp = cp - allocsize;
-               *(caddr_t *)cp = NULL;
+               for (cp = kbp->kb_next; cp >= va; cp -= allocsize) {
+                       ((caddr_t *)cp)[2] = (cp > va ? cp - allocsize : NULL);
+                       if (indx == 7) {
+                               long *lp = (long *)cp;
+                               lp[0] = lp[1] = lp[3] = lp[4] = -1;
+                       }
+               }
        }
        va = kbp->kb_next;
        }
        va = kbp->kb_next;
-       kbp->kb_next = *(caddr_t *)va;
+       kbp->kb_next = ((caddr_t *)va)[2];
+       if (indx == 7) {
+               long *lp = (long *)va;
+               if (lp[0] != -1 || lp[1] != -1 || lp[3] != -1 || lp[4] != -1)
+                       panic("malloc meddled");
+       }
 #ifdef KMEMSTATS
        kup = btokup(va);
        if (kup->ku_indx != indx)
 #ifdef KMEMSTATS
        kup = btokup(va);
        if (kup->ku_indx != indx)
@@ -130,6 +160,7 @@ out:
 #else
 out:
 #endif
 #else
 out:
 #endif
+       OUT;
        splx(s);
        return ((qaddr_t)va);
 }
        splx(s);
        return ((qaddr_t)va);
 }
@@ -140,11 +171,12 @@ out:
 void
 free(addr, type)
        caddr_t addr;
 void
 free(addr, type)
        caddr_t addr;
-       long type;
+       int type;
 {
        register struct kmembuckets *kbp;
        register struct kmemusage *kup;
 {
        register struct kmembuckets *kbp;
        register struct kmemusage *kup;
-       long alloc, size, s;
+       long alloc, size;
+       int s;
 #ifdef KMEMSTATS
        register struct kmemstats *ksp = &kmemstats[type];
 #endif
 #ifdef KMEMSTATS
        register struct kmemstats *ksp = &kmemstats[type];
 #endif
@@ -152,11 +184,13 @@ free(addr, type)
        kup = btokup(addr);
        kbp = &bucket[kup->ku_indx];
        s = splimp();
        kup = btokup(addr);
        kbp = &bucket[kup->ku_indx];
        s = splimp();
+       IN;
        size = 1 << kup->ku_indx;
        if (size > MAXALLOCSAVE) {
                alloc = btokmemx(addr);
        size = 1 << kup->ku_indx;
        if (size > MAXALLOCSAVE) {
                alloc = btokmemx(addr);
-               (void) memfree(&kmempt[alloc], kup->ku_pagecnt, 0);
+               (void) memfree(&kmempt[alloc], (int)kup->ku_pagecnt, 1);
                rmfree(kmemmap, (long)kup->ku_pagecnt, alloc + CLSIZE);
                rmfree(kmemmap, (long)kup->ku_pagecnt, alloc + CLSIZE);
+               OUT;
                if (wantkmemmap) {
                        wakeup((caddr_t)&wantkmemmap);
                        wantkmemmap = 0;
                if (wantkmemmap) {
                        wakeup((caddr_t)&wantkmemmap);
                        wantkmemmap = 0;
@@ -175,6 +209,10 @@ free(addr, type)
                splx(s);
                return;
        }
                splx(s);
                return;
        }
+       if (size == 128) {
+               long *lp = (long *)addr;
+               lp[0] = lp[1] = lp[3] = lp[4] = -1;
+       }
 #ifdef KMEMSTATS
        kup->ku_freecnt++;
        if (kup->ku_freecnt >= kbp->kb_elmpercl)
 #ifdef KMEMSTATS
        kup->ku_freecnt++;
        if (kup->ku_freecnt >= kbp->kb_elmpercl)
@@ -189,8 +227,9 @@ free(addr, type)
                wakeup((caddr_t)ksp);
        ksp->ks_inuse--;
 #endif
                wakeup((caddr_t)ksp);
        ksp->ks_inuse--;
 #endif
-       *(caddr_t *)addr = kbp->kb_next;
+       ((caddr_t *)addr)[2] = kbp->kb_next;
        kbp->kb_next = addr;
        kbp->kb_next = addr;
+       OUT;
        splx(s);
 }
 
        splx(s);
 }
 
@@ -202,14 +241,17 @@ kmeminit()
        register long indx;
        int npg;
 
        register long indx;
        int npg;
 
-       if (!powerof2(MAXALLOCSAVE))
-               panic("kmeminit: MAXALLOCSAVE not power of 2");
-       if (MAXALLOCSAVE > MINALLOCSIZE * 32768)
-               panic("kmeminit: MAXALLOCSAVE too big");
-       if (MAXALLOCSAVE < CLBYTES)
-               panic("kmeminit: MAXALLOCSAVE too small");
+#if    ((MAXALLOCSAVE & (MAXALLOCSAVE - 1)) != 0)
+               ERROR!_kmeminit:_MAXALLOCSAVE_not_power_of_2
+#endif
+#if    (MAXALLOCSAVE > MINALLOCSIZE * 32768)
+               ERROR!_kmeminit:_MAXALLOCSAVE_too_big
+#endif
+#if    (MAXALLOCSAVE < CLBYTES)
+               ERROR!_kmeminit:_MAXALLOCSAVE_too_small
+#endif
        npg = ekmempt - kmempt;
        npg = ekmempt - kmempt;
-       rminit(kmemmap, npg, (long)CLSIZE, "malloc map", npg);
+       rminit(kmemmap, (long)npg, (long)CLSIZE, "malloc map", npg);
 #ifdef KMEMSTATS
        for (indx = 0; indx < MINBUCKET + 16; indx++) {
                if (1 << indx >= CLBYTES)
 #ifdef KMEMSTATS
        for (indx = 0; indx < MINBUCKET + 16; indx++) {
                if (1 << indx >= CLBYTES)
@@ -219,6 +261,6 @@ kmeminit()
                bucket[indx].kb_highwat = 5 * bucket[indx].kb_elmpercl;
        }
        for (indx = 0; indx < M_LAST; indx++)
                bucket[indx].kb_highwat = 5 * bucket[indx].kb_elmpercl;
        }
        for (indx = 0; indx < M_LAST; indx++)
-               kmemstats[indx].ks_limit = npg * CLBYTES * 8 / 10;
+               kmemstats[indx].ks_limit = npg * NBPG * 6 / 10;
 #endif
 }
 #endif
 }