diff options
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r-- | sys/kern/kern_malloc.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index a9776a5..be9f9d3 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94 - * $Id: kern_malloc.c,v 1.50 1999/01/08 17:31:09 eivind Exp $ + * $Id: kern_malloc.c,v 1.51 1999/01/10 01:58:24 eivind Exp $ */ #include "opt_vm.h" @@ -101,7 +101,16 @@ struct freelist { #endif /* INVARIANTS */ /* - * Allocate a block of memory + * malloc: + * + * Allocate a block of memory. + * + * If M_NOWAIT is set, this routine will not block and return NULL if + * the allocation fails. + * + * If M_ASLEEP is set (M_NOWAIT must also be set), this routine + * will have the side effect of calling asleep() if it returns NULL, + * allowing the parent to await() at some future time. */ void * malloc(size, type, flags) @@ -122,13 +131,26 @@ malloc(size, type, flags) #endif register struct malloc_type *ksp = type; - if (!type->ks_next) + /* + * Must be at splmem() prior to initializing segment to handle + * potential initialization race. + */ + + s = splmem(); + + if (!type->ks_next) { malloc_init(type); + } indx = BUCKETINDX(size); kbp = &bucket[indx]; - s = splmem(); + while (ksp->ks_memuse >= ksp->ks_limit) { + if (flags & M_ASLEEP) { + if (ksp->ks_limblocks < 65535) + ksp->ks_limblocks++; + asleep((caddr_t)ksp, PSWP+2, type->ks_shortdesc, 0); + } if (flags & M_NOWAIT) { splx(s); return ((void *) NULL); @@ -239,7 +261,11 @@ out: } /* - * Free a block of memory allocated by malloc. + * free: + * + * Free a block of memory allocated by malloc. + * + * This routine may not block. */ void free(addr, type) |