summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r--sys/kern/kern_malloc.c36
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)
OpenPOWER on IntegriCloud