BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / kern / kern_malloc.c
index 0e3429c..5481865 100644 (file)
@@ -1,45 +1,56 @@
 /*
 /*
- * Copyright (c) 1987 Regents of the University of California.
+ * Copyright (c) 1987, 1991 The Regents of the University of California.
  * All rights reserved.
  *
  * All rights reserved.
  *
- * Redistribution is only permitted until one year after the first shipment
- * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
- * binary forms are permitted provided that: (1) source distributions retain
- * this entire copyright notice and comment, and (2) distributions including
- * binaries display the following acknowledgement:  This product includes
- * software developed by the University of California, Berkeley and its
- * contributors'' in the documentation or other materials provided with the
- * distribution and in all advertising materials mentioning features or use
- * of this software.  Neither the name of the University nor the names of
- * its contributors may 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
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)kern_malloc.c       7.19 (Berkeley) 7/27/90
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)kern_malloc.c       7.25 (Berkeley) 5/8/91
  */
 
 #include "param.h"
  */
 
 #include "param.h"
-#include "vm.h"
-#include "cmap.h"
-#include "time.h"
 #include "proc.h"
 #include "map.h"
 #include "kernel.h"
 #include "malloc.h"
 #include "proc.h"
 #include "map.h"
 #include "kernel.h"
 #include "malloc.h"
-
-#include "machine/pte.h"
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
 
 struct kmembuckets bucket[MINBUCKET + 16];
 struct kmemstats kmemstats[M_LAST];
 struct kmemusage *kmemusage;
 
 struct kmembuckets bucket[MINBUCKET + 16];
 struct kmemstats kmemstats[M_LAST];
 struct kmemusage *kmemusage;
-long wantkmemmap;
+char *kmembase, *kmemlimit;
+char *memname[] = INITKMEMNAMES;
 
 /*
  * Allocate a block of memory
  */
 
 /*
  * Allocate a block of memory
  */
-qaddr_t
+void *
 malloc(size, type, flags)
        unsigned long size;
        int type, flags;
 malloc(size, type, flags)
        unsigned long size;
        int type, flags;
@@ -48,7 +59,7 @@ malloc(size, type, flags)
        register struct kmemusage *kup;
        long indx, npg, alloc, allocsize;
        int s;
        register struct kmemusage *kup;
        long indx, npg, alloc, allocsize;
        int s;
-       caddr_t va, cp;
+       caddr_t va, cp, savedlist;
 #ifdef KMEMSTATS
        register struct kmemstats *ksp = &kmemstats[type];
 
 #ifdef KMEMSTATS
        register struct kmemstats *ksp = &kmemstats[type];
 
@@ -59,16 +70,15 @@ malloc(size, type, flags)
        indx = BUCKETINDX(size);
        kbp = &bucket[indx];
        s = splimp();
        indx = BUCKETINDX(size);
        kbp = &bucket[indx];
        s = splimp();
-again:
 #ifdef KMEMSTATS
        while (ksp->ks_memuse >= ksp->ks_limit) {
                if (flags & M_NOWAIT) {
                        splx(s);
 #ifdef KMEMSTATS
        while (ksp->ks_memuse >= ksp->ks_limit) {
                if (flags & M_NOWAIT) {
                        splx(s);
-                       return (0);
+                       return ((void *) NULL);
                }
                if (ksp->ks_limblocks < 65535)
                        ksp->ks_limblocks++;
                }
                if (ksp->ks_limblocks < 65535)
                        ksp->ks_limblocks++;
-               sleep((caddr_t)ksp, PSWP+2);
+               tsleep((caddr_t)ksp, PSWP+2, memname[type], 0);
        }
 #endif
        if (kbp->kb_next == NULL) {
        }
 #endif
        if (kbp->kb_next == NULL) {
@@ -77,28 +87,12 @@ again:
                else
                        allocsize = 1 << indx;
                npg = clrnd(btoc(allocsize));
                else
                        allocsize = 1 << indx;
                npg = clrnd(btoc(allocsize));
-               if ((flags & M_NOWAIT) && freemem < npg) {
+               va = (caddr_t) kmem_malloc(kmem_map, (vm_size_t)ctob(npg),
+                                          !(flags & M_NOWAIT));
+               if (va == NULL) {
                        splx(s);
                        splx(s);
-                       return (0);
-               }
-               alloc = rmalloc(kmemmap, npg);
-               if (alloc == 0) {
-                       if (flags & M_NOWAIT) {
-                               splx(s);
-                               return (0);
-                       }
-#ifdef KMEMSTATS
-                       if (ksp->ks_mapblocks < 65535)
-                               ksp->ks_mapblocks++;
-#endif
-                       wantkmemmap++;
-                       sleep((caddr_t)&wantkmemmap, PSWP+2);
-                       goto again;
+                       return ((void *) NULL);
                }
                }
-               alloc -= CLSIZE;                /* convert to base 0 */
-               (void) vmemall(&kmempt[alloc], (int)npg, &proc[0], CSYS);
-               va = (caddr_t) kmemxtob(alloc);
-               vmaccess(&kmempt[alloc], va, (int)npg);
 #ifdef KMEMSTATS
                kbp->kb_total += kbp->kb_elmpercl;
 #endif
 #ifdef KMEMSTATS
                kbp->kb_total += kbp->kb_elmpercl;
 #endif
@@ -117,10 +111,16 @@ again:
                kup->ku_freecnt = kbp->kb_elmpercl;
                kbp->kb_totalfree += kbp->kb_elmpercl;
 #endif
                kup->ku_freecnt = kbp->kb_elmpercl;
                kbp->kb_totalfree += kbp->kb_elmpercl;
 #endif
+               /*
+                * Just in case we blocked while allocating memory,
+                * and someone else also allocated memory for this
+                * bucket, don't assume the list is still empty.
+                */
+               savedlist = kbp->kb_next;
                kbp->kb_next = va + (npg * NBPG) - allocsize;
                for (cp = kbp->kb_next; cp > va; cp -= allocsize)
                        *(caddr_t *)cp = cp - allocsize;
                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;
+               *(caddr_t *)cp = savedlist;
        }
        va = kbp->kb_next;
        kbp->kb_next = *(caddr_t *)va;
        }
        va = kbp->kb_next;
        kbp->kb_next = *(caddr_t *)va;
@@ -143,7 +143,7 @@ out:
 out:
 #endif
        splx(s);
 out:
 #endif
        splx(s);
-       return ((qaddr_t)va);
+       return ((void *) va);
 }
 
 #ifdef DIAGNOSTIC
 }
 
 #ifdef DIAGNOSTIC
@@ -160,7 +160,7 @@ long addrmask[] = { 0x00000000,
  */
 void
 free(addr, type)
  */
 void
 free(addr, type)
-       caddr_t addr;
+       void *addr;
        int type;
 {
        register struct kmembuckets *kbp;
        int type;
 {
        register struct kmembuckets *kbp;
@@ -187,13 +187,7 @@ free(addr, type)
        kbp = &bucket[kup->ku_indx];
        s = splimp();
        if (size > MAXALLOCSAVE) {
        kbp = &bucket[kup->ku_indx];
        s = splimp();
        if (size > MAXALLOCSAVE) {
-               alloc = btokmemx(addr);
-               (void) memfree(&kmempt[alloc], (int)kup->ku_pagecnt, 1);
-               rmfree(kmemmap, (long)kup->ku_pagecnt, alloc + CLSIZE);
-               if (wantkmemmap) {
-                       wakeup((caddr_t)&wantkmemmap);
-                       wantkmemmap = 0;
-               }
+               kmem_free(kmem_map, (vm_offset_t)addr, ctob(kup->ku_pagecnt));
 #ifdef KMEMSTATS
                size = kup->ku_pagecnt << PGSHIFT;
                ksp->ks_memuse -= size;
 #ifdef KMEMSTATS
                size = kup->ku_pagecnt << PGSHIFT;
                ksp->ks_memuse -= size;
@@ -244,8 +238,11 @@ kmeminit()
 #if    (MAXALLOCSAVE < CLBYTES)
                ERROR!_kmeminit:_MAXALLOCSAVE_too_small
 #endif
 #if    (MAXALLOCSAVE < CLBYTES)
                ERROR!_kmeminit:_MAXALLOCSAVE_too_small
 #endif
-       npg = ekmempt - kmempt;
-       rminit(kmemmap, (long)npg, (long)CLSIZE, "malloc map", npg);
+       npg = VM_KMEM_SIZE/ NBPG;
+       kmemusage = (struct kmemusage *) kmem_alloc(kernel_map,
+               (vm_size_t)(npg * sizeof(struct kmemusage)));
+       kmem_map = kmem_suballoc(kernel_map, (vm_offset_t)&kmembase,
+               (vm_offset_t)&kmemlimit, (vm_size_t)(npg * NBPG), FALSE);
 #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)