/*
- * Copyright (c) 1987 Regents of the University of California.
+ * Copyright (c) 1987, 1991 The Regents of the University of California.
* 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 "vm.h"
-#include "cmap.h"
-#include "time.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;
-long wantkmemmap;
+char *kmembase, *kmemlimit;
+char *memname[] = INITKMEMNAMES;
/*
* Allocate a block of memory
*/
-qaddr_t
+void *
malloc(size, type, flags)
unsigned long size;
int type, flags;
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];
indx = BUCKETINDX(size);
kbp = &bucket[indx];
s = splimp();
-again:
#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++;
- sleep((caddr_t)ksp, PSWP+2);
+ tsleep((caddr_t)ksp, PSWP+2, memname[type], 0);
}
#endif
if (kbp->kb_next == NULL) {
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);
- 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
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;
- *(caddr_t *)cp = NULL;
+ *(caddr_t *)cp = savedlist;
}
va = kbp->kb_next;
kbp->kb_next = *(caddr_t *)va;
out:
#endif
splx(s);
- return ((qaddr_t)va);
+ return ((void *) va);
}
#ifdef DIAGNOSTIC
*/
void
free(addr, type)
- caddr_t addr;
+ void *addr;
int type;
{
register struct kmembuckets *kbp;
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;
#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)