Make the memory allocation code MP-safe.

This commit is contained in:
pk 2003-02-14 21:51:36 +00:00
parent 9a853301e6
commit 9ca040e74e
2 changed files with 22 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_malloc.c,v 1.77 2003/02/01 06:23:43 thorpej Exp $ */
/* $NetBSD: kern_malloc.c,v 1.78 2003/02/14 21:51:36 pk Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.77 2003/02/01 06:23:43 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.78 2003/02/14 21:51:36 pk Exp $");
#include "opt_lockdebug.h"
@ -214,6 +214,8 @@ MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address");
MALLOC_DEFINE(M_MRTABLE, "mrt", "multicast routing tables");
MALLOC_DEFINE(M_1394DATA, "1394data", "IEEE 1394 data buffers");
struct simplelock malloc_slock = SIMPLELOCK_INITIALIZER;
/*
* Allocate a block of memory
*/
@ -249,15 +251,18 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
indx = BUCKETINDX(size);
kbp = &bucket[indx];
s = splvm();
simple_lock(&malloc_slock);
#ifdef KMEMSTATS
while (ksp->ks_memuse >= ksp->ks_limit) {
if (flags & M_NOWAIT) {
simple_unlock(&malloc_slock);
splx(s);
return ((void *) NULL);
}
if (ksp->ks_limblocks < 65535)
ksp->ks_limblocks++;
tsleep((caddr_t)ksp, PSWP+2, ksp->ks_shortdesc, 0);
ltsleep((caddr_t)ksp, PSWP+2, ksp->ks_shortdesc, 0,
&malloc_slock);
}
ksp->ks_size |= 1 << indx;
#endif
@ -271,6 +276,7 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
else
allocsize = 1 << indx;
npg = btoc(allocsize);
simple_unlock(&malloc_slock);
va = (caddr_t) uvm_km_kmemalloc(kmem_map, NULL,
(vsize_t)ctob(npg),
((flags & M_NOWAIT) ? UVM_KMF_NOWAIT : 0) |
@ -289,6 +295,7 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
splx(s);
return (NULL);
}
simple_lock(&malloc_slock);
#ifdef KMEMSTATS
kbp->kb_total += kbp->kb_elmpercl;
#endif
@ -414,6 +421,7 @@ out:
#ifdef MALLOCLOG
domlog(va, size, type, 1, file, line);
#endif
simple_unlock(&malloc_slock);
splx(s);
if ((flags & M_ZERO) != 0)
memset(va, 0, size);
@ -462,6 +470,7 @@ free(void *addr, struct malloc_type *ksp)
size = 1 << kup->ku_indx;
kbp = &bucket[kup->ku_indx];
s = splvm();
simple_lock(&malloc_slock);
#ifdef MALLOCLOG
domlog(addr, 0, type, 2, file, line);
#endif
@ -491,6 +500,7 @@ free(void *addr, struct malloc_type *ksp)
ksp->ks_inuse--;
kbp->kb_total -= 1;
#endif
simple_unlock(&malloc_slock);
splx(s);
return;
}
@ -551,6 +561,7 @@ free(void *addr, struct malloc_type *ksp)
((struct freelist *)kbp->kb_last)->next = addr;
freep->next = NULL;
kbp->kb_last = addr;
simple_unlock(&malloc_slock);
splx(s);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: malloc.h,v 1.85 2003/02/02 02:22:14 christos Exp $ */
/* $NetBSD: malloc.h,v 1.86 2003/02/14 21:51:36 pk Exp $ */
/*
* Copyright (c) 1987, 1993
@ -148,6 +148,8 @@ struct kmembuckets {
#define btokmemx(addr) (((caddr_t)(addr) - kmembase) / NBPG)
#define btokup(addr) (&kmemusage[((caddr_t)(addr) - kmembase) >> PGSHIFT])
extern struct simplelock malloc_slock;
/*
* Macro versions for the usual cases of malloc/free
*/
@ -162,12 +164,15 @@ struct kmembuckets {
do { \
register struct kmembuckets *__kbp = &bucket[BUCKETINDX((size))]; \
long __s = splvm(); \
simple_lock(&malloc_slock); \
if (__kbp->kb_next == NULL) { \
simple_unlock(&malloc_slock); \
(space) = (cast)malloc((u_long)(size), (type), (flags)); \
splx(__s); \
} else { \
(space) = (cast)__kbp->kb_next; \
__kbp->kb_next = *(caddr_t *)(space); \
simple_unlock(&malloc_slock); \
splx(__s); \
if ((flags) & M_ZERO) \
memset((space), 0, (size)); \
@ -182,6 +187,7 @@ do { \
if (1 << __kup->ku_indx > MAXALLOCSAVE) { \
free((caddr_t)(addr), (type)); \
} else { \
simple_lock(&malloc_slock); \
__kbp = &bucket[__kup->ku_indx]; \
if (__kbp->kb_next == NULL) \
__kbp->kb_next = (caddr_t)(addr); \
@ -189,6 +195,7 @@ do { \
*(caddr_t *)(__kbp->kb_last) = (caddr_t)(addr); \
*(caddr_t *)(addr) = NULL; \
__kbp->kb_last = (caddr_t)(addr); \
simple_unlock(&malloc_slock); \
} \
splx(__s); \
} while(/* CONSTCOND */ 0)