changeset 3866:a61ffaa37ee1

6533630 all malloc interposition libraries need to be made fork-safe
author raf
date Tue, 20 Mar 2007 19:30:49 -0700
parents 6dfee3b4c9ff
children 3bb8feda9874
files deleted_files/usr/src/lib/libmapmalloc/common/malloc_debug.c usr/src/lib/libmalloc/Makefile.com usr/src/lib/libmalloc/common/mallint.h usr/src/lib/libmalloc/common/malloc.c usr/src/lib/libmapmalloc/Makefile.com usr/src/lib/libmapmalloc/common/calloc.c usr/src/lib/libmapmalloc/common/malloc_debug.c usr/src/lib/libmapmalloc/common/textmem.c usr/src/lib/libmapmalloc/common/valloc.c usr/src/lib/libmtmalloc/Makefile.com usr/src/lib/libmtmalloc/common/mtmalloc.c usr/src/lib/libumem/Makefile.com usr/src/lib/watchmalloc/Makefile.com usr/src/lib/watchmalloc/common/mallint.h usr/src/lib/watchmalloc/common/malloc.c
diffstat 15 files changed, 284 insertions(+), 237 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deleted_files/usr/src/lib/libmapmalloc/common/malloc_debug.c	Tue Mar 20 19:30:49 2007 -0700
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1991, Sun Microsytems, Inc.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*LINTLIBRARY*/
+#include <sys/types.h>
+
+
+/*
+ * malloc_debug(level) - empty routine
+ */
+
+/*ARGSUSED*/
+int
+malloc_debug(int level)
+{
+	return (1);
+}
+
+
+/*
+ * malloc_verify() - empty routine
+ */
+
+int
+malloc_verify(void)
+{
+	return (1);
+}
+
+
+/*
+ * mallocmap() - empty routine
+ */
+
+void
+mallocmap(void)
+{
+	;
+}
--- a/usr/src/lib/libmalloc/Makefile.com	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmalloc/Makefile.com	Tue Mar 20 19:30:49 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -42,7 +42,7 @@
 LINTFLAGS64 +=	-erroff=E_BAD_PTR_CAST_ALIGN
 
 CFLAGS +=	$(CCVERBOSE)
-CPPFLAGS +=	-D_REENTRANT
+CPPFLAGS +=	-I../../common/inc -D_REENTRANT
 DYNFLAGS +=	$(ZINTERPOSE)
 LDLIBS +=	-lc
 
--- a/usr/src/lib/libmalloc/common/mallint.h	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmalloc/common/mallint.h	Tue Mar 20 19:30:49 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,15 +18,15 @@
  *
  * CDDL HEADER END
  */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 /*	Copyright (c) 1988 AT&T	*/
 /*	  All Rights Reserved  	*/
 
-
-/*
- * Copyright (c) 1997,2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
 #ifndef _MALLINT_H
 #define	_MALLINT_H
 
@@ -198,18 +197,6 @@
 #define	CHECKQ
 #endif
 
-#ifdef	_REENTRANT
-
-#define	mutex_lock(m)			_mutex_lock(m)
-#define	mutex_unlock(m)			_mutex_unlock(m)
-
-#else
-
-#define	mutex_lock(m)
-#define	mutex_unlock(m)
-
-#endif	/* _REENTRANT */
-
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/lib/libmalloc/common/malloc.c	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmalloc/common/malloc.c	Tue Mar 20 19:30:49 2007 -0700
@@ -19,16 +19,17 @@
  * CDDL HEADER END
  */
 
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 /*	Copyright (c) 1988 AT&T	*/
 /*	  All Rights Reserved  	*/
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-/*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
+#include <c_synonyms.h>
 #include <sys/types.h>
 
 #ifndef debug
@@ -41,6 +42,7 @@
 #include "malloc.h"
 #include "mallint.h"
 #include <thread.h>
+#include <pthread.h>
 #include <synch.h>
 #include <unistd.h>
 #include <limits.h>
@@ -1170,3 +1172,22 @@
 {
 	free(p);
 }
+
+static void
+malloc_prepare()
+{
+	(void) mutex_lock(&mlock);
+}
+
+static void
+malloc_release()
+{
+	(void) mutex_unlock(&mlock);
+}
+
+#pragma init(malloc_init)
+static void
+malloc_init(void)
+{
+	(void) pthread_atfork(malloc_prepare, malloc_release, malloc_release);
+}
--- a/usr/src/lib/libmapmalloc/Makefile.com	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmapmalloc/Makefile.com	Tue Mar 20 19:30:49 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -30,7 +30,6 @@
 
 OBJECTS=  \
 	calloc.o \
-	malloc_debug.o \
 	textmem.o \
 	valloc.o
 
@@ -44,7 +43,7 @@
 LINTSRC=	$(LINTLIB:%.ln=%)
 
 CFLAGS +=	$(CCVERBOSE)
-CPPFLAGS +=	-D_REENTRANT
+CPPFLAGS +=	-I../../common/inc -D_REENTRANT
 DYNFLAGS +=	$(ZINTERPOSE)
 LDLIBS +=	-lc
 
--- a/usr/src/lib/libmapmalloc/common/calloc.c	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmapmalloc/common/calloc.c	Tue Mar 20 19:30:49 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,14 +18,15 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
-#include <sys/types.h>
+#include <c_synonyms.h>
 #include <stdlib.h>
 #include <string.h>
 /*
--- a/usr/src/lib/libmapmalloc/common/malloc_debug.c	Tue Mar 20 18:39:28 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1991, Sun Microsytems, Inc.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*LINTLIBRARY*/
-#include <sys/types.h>
-
-
-/*
- * malloc_debug(level) - empty routine
- */
-
-/*ARGSUSED*/
-int
-malloc_debug(int level)
-{
-	return (1);
-}
-
-
-/*
- * malloc_verify() - empty routine
- */
-
-int
-malloc_verify(void)
-{
-	return (1);
-}
-
-
-/*
- * mallocmap() - empty routine
- */
-
-void
-mallocmap(void)
-{
-	;
-}
--- a/usr/src/lib/libmapmalloc/common/textmem.c	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmapmalloc/common/textmem.c	Tue Mar 20 19:30:49 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,15 +18,15 @@
  *
  * CDDL HEADER END
  */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
 /*	  All Rights Reserved  	*/
 
-
-/*
- * Copyright (c) 1991-1997,2000-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVR4/MNLS 1.1.2.1 */
 
 /*LINTLIBRARY*/
@@ -49,6 +48,7 @@
  * New memory chunks are allocated on a first-fit basis.
  * Freed blocks are joined in larger blocks. Free pages are unmapped.
  */
+#include <c_synonyms.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -56,13 +56,11 @@
 #include <errno.h>
 #include <unistd.h>
 #include <thread.h>
+#include <pthread.h>
 #include <synch.h>
 #include <string.h>
 
-
-#ifdef _REENTRANT
 static mutex_t lock = DEFAULTMUTEX;
-#endif /* _REENTRANT */
 
 struct block {
 	size_t size;		/* Space available for user */
@@ -280,3 +278,22 @@
 		(void) munmap((caddr_t)page, page->size);
 	}
 }
+
+static void
+malloc_prepare()
+{
+	(void) mutex_lock(&lock);
+}
+
+static void
+malloc_release()
+{
+	(void) mutex_unlock(&lock);
+}
+
+#pragma init(malloc_init)
+static void
+malloc_init(void)
+{
+	(void) pthread_atfork(malloc_prepare, malloc_release, malloc_release);
+}
--- a/usr/src/lib/libmapmalloc/common/valloc.c	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmapmalloc/common/valloc.c	Tue Mar 20 19:30:49 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,14 +18,16 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright (c) 1991-1997, Sun Microsytems, Inc.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*LINTLIBRARY*/
-#include <sys/types.h>
+#include <c_synonyms.h>
 #include <stdlib.h>
 #include <errno.h>
 
--- a/usr/src/lib/libmtmalloc/Makefile.com	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmtmalloc/Makefile.com	Tue Mar 20 19:30:49 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -40,7 +40,7 @@
 LIBS 		 = $(DYNLIB) $(LINTLIB)
 LDLIBS 		+= -lc
 CFLAGS 		+= $(CCVERBOSE) $(C_PICFLAGS)
-CPPFLAGS	+= -I../common -D_REENTRANT
+CPPFLAGS	+= -I../common -I../../common/inc -D_REENTRANT
 DYNFLAGS 	+= $(ZINTERPOSE)
 
 $(LINTLIB) lint :=	LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN
--- a/usr/src/lib/libmtmalloc/common/mtmalloc.c	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libmtmalloc/common/mtmalloc.c	Tue Mar 20 19:30:49 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,18 +18,21 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
+#include <c_synonyms.h>
 #include <mtmalloc.h>
 #include "mtmalloc_impl.h"
 #include <unistd.h>
 #include <synch.h>
 #include <thread.h>
+#include <pthread.h>
 #include <stdio.h>
 #include <limits.h>
 #include <errno.h>
@@ -116,7 +118,6 @@
 #endif
 
 static void * morecore(size_t);
-static int setup_caches(void);
 static void create_cache(cache_t *, size_t bufsize, uint_t hunks);
 static void * malloc_internal(size_t, percpu_t *);
 static void * oversize(size_t);
@@ -136,15 +137,6 @@
 #define	HASH_OVERSIZE(caddr)	((uintptr_t)(caddr) % NUM_BUCKETS)
 oversize_t *ovsz_hashtab[NUM_BUCKETS];
 
-/*
- * Gets a decent "current cpu identifier", to be used to reduce contention.
- * Eventually, this should be replaced by an interface to get the actual
- * CPU sequence number in libthread/liblwp.
- */
-extern uint_t _thr_self();
-#pragma weak _thr_self
-#define	get_curcpu_func() (curcpu_func)_thr_self
-
 #define	ALIGN(x, a)	((((uintptr_t)(x) + ((uintptr_t)(a) - 1)) \
 			& ~((uintptr_t)(a) - 1)))
 
@@ -195,9 +187,9 @@
 
 static percpu_t *cpu_list;
 static oversize_t oversize_list;
-static mutex_t oversize_lock;
+static mutex_t oversize_lock = DEFAULTMUTEX;
 
-static int ncpus;
+static int ncpus = 0;
 
 #define	MTMALLOC_OVERSIZE_MAGIC		((uintptr_t)&oversize_list)
 #define	MTMALLOC_MEMALIGN_MAGIC		((uintptr_t)&oversize_list + 1)
@@ -233,20 +225,6 @@
 	percpu_t *list_rotor;
 	uint_t	list_index;
 
-	/*
-	 * this test is due to linking with libthread.
-	 * There are malloc calls prior to this library
-	 * being initialized.
-	 *
-	 * If setup_caches fails, we set ENOMEM and return NULL
-	 */
-	if (cpu_list == (percpu_t *)NULL) {
-		if (setup_caches() == 0) {
-			errno = ENOMEM;
-			return (NULL);
-		}
-	}
-
 	if (bytes > MAX_CACHED)
 		return (oversize(bytes));
 
@@ -332,7 +310,7 @@
 	ptr = malloc(size);
 	if (ptr == NULL)
 		return (NULL);
-	bzero(ptr, size);
+	(void) memset(ptr, 0, size);
 
 	return (ptr);
 }
@@ -753,25 +731,13 @@
 }
 
 /*
- * if this function is changed, update the fallback code in setup_caches to
- * set ncpus to the number of possible return values. (currently 1)
+ * Initialization function, called from the init section of the library.
+ * No locking is required here because we are single-threaded during
+ * library initialization.
  */
-static uint_t
-fallback_curcpu(void)
-{
-	return (0);
-}
-
-/*
- * Returns non-zero on success, zero on failure.
- *
- * This carefully doesn't set cpu_list until initialization is finished.
- */
-static int
+static void
 setup_caches(void)
 {
-	static mutex_t init_lock = DEFAULTMUTEX;
-
 	uintptr_t oldbrk;
 	uintptr_t newbrk;
 
@@ -785,21 +751,14 @@
 	uint_t i, j;
 	uintptr_t list_addr;
 
-	(void) mutex_lock(&init_lock);
-	if (cpu_list != NULL) {
-		(void) mutex_unlock(&init_lock);
-		return (1); 		/* success -- already initialized */
-	}
-
-	new_curcpu = get_curcpu_func();
-	if (new_curcpu == NULL) {
-		new_curcpu = fallback_curcpu;
-		ncpus = 1;
-	} else {
-		if ((ncpus = 2 * sysconf(_SC_NPROCESSORS_CONF)) <= 0)
-			ncpus = 4; /* decent default value */
-	}
-	assert(ncpus > 0);
+	/*
+	 * Get a decent "current cpu identifier", to be used to reduce
+	 * contention.  Eventually, this should be replaced by an interface
+	 * to get the actual CPU sequence number in libthread/liblwp.
+	 */
+	new_curcpu = (curcpu_func)thr_self;
+	if ((ncpus = 2 * sysconf(_SC_NPROCESSORS_CONF)) <= 0)
+		ncpus = 4; /* decent default value */
 
 	/* round ncpus up to a power of 2 */
 	while (ncpus & (ncpus - 1))
@@ -817,10 +776,8 @@
 	 * First, make sure sbrk is sane, and store the current brk in oldbrk.
 	 */
 	oldbrk = (uintptr_t)sbrk(0);
-	if ((void *)oldbrk == (void *)-1) {
-		(void) mutex_unlock(&init_lock);
-		return (0);	/* sbrk is broken -- we're doomed. */
-	}
+	if ((void *)oldbrk == (void *)-1)
+		abort();	/* sbrk is broken -- we're doomed. */
 
 	/*
 	 * Now, align the brk to a multiple of CACHE_COHERENCY_UNIT, so that
@@ -830,10 +787,8 @@
 	 *	so they can be paged out individually.
 	 */
 	newbrk = ALIGN(oldbrk, CACHE_COHERENCY_UNIT);
-	if (newbrk != oldbrk && (uintptr_t)sbrk(newbrk - oldbrk) != oldbrk) {
-		(void) mutex_unlock(&init_lock);
-		return (0);	/* someone else sbrked */
-	}
+	if (newbrk != oldbrk && (uintptr_t)sbrk(newbrk - oldbrk) != oldbrk)
+		abort();	/* sbrk is broken -- we're doomed. */
 
 	/*
 	 * For each cpu, there is one percpu_t and a list of caches
@@ -843,10 +798,8 @@
 	new_cpu_list = (percpu_t *)sbrk(cache_space_needed);
 
 	if (new_cpu_list == (percpu_t *)-1 ||
-	    (uintptr_t)new_cpu_list != newbrk) {
-		(void) mutex_unlock(&init_lock);
-		return (0);	/* someone else sbrked */
-	}
+	    (uintptr_t)new_cpu_list != newbrk)
+		abort();	/* sbrk is broken -- we're doomed. */
 
 	/*
 	 * Finally, align the brk to HUNKSIZE so that all hunks are
@@ -857,10 +810,8 @@
 
 	padding = ALIGN(newbrk, HUNKSIZE) - newbrk;
 
-	if (padding > 0 && (uintptr_t)sbrk(padding) != newbrk) {
-		(void) mutex_unlock(&init_lock);
-		return (0);	/* someone else sbrked */
-	}
+	if (padding > 0 && (uintptr_t)sbrk(padding) != newbrk)
+		abort();	/* sbrk is broken -- we're doomed. */
 
 	list_addr = ((uintptr_t)new_cpu_list + (sizeof (percpu_t) * ncpus));
 
@@ -872,7 +823,8 @@
 			new_cpu_list[i].mt_caches[j].mt_hint = NULL;
 		}
 
-		bzero(&new_cpu_list[i].mt_parent_lock, sizeof (mutex_t));
+		(void) mutex_init(&new_cpu_list[i].mt_parent_lock,
+		    USYNC_THREAD, NULL);
 
 		/* get the correct cache list alignment */
 		list_addr += CACHELIST_SIZE;
@@ -889,16 +841,11 @@
 	oversize_list.size = 0;		/* sentinal */
 
 	/*
-	 * now install the global variables, leaving cpu_list for last, so that
-	 * there aren't any race conditions.
+	 * Now install the global variables.
 	 */
 	curcpu = new_curcpu;
 	cpu_mask = new_cpu_mask;
 	cpu_list = new_cpu_list;
-
-	(void) mutex_unlock(&init_lock);
-
-	return (1);
 }
 
 static void
@@ -906,7 +853,7 @@
 {
 	long nblocks;
 
-	bzero(&cp->mt_cache_lock, sizeof (mutex_t));
+	(void) mutex_init(&cp->mt_cache_lock, USYNC_THREAD, NULL);
 	cp->mt_size = size;
 	cp->mt_freelist = ((caddr_t)cp + sizeof (cache_t));
 	cp->mt_span = chunksize * HUNKSIZE - sizeof (cache_t);
@@ -958,11 +905,6 @@
 	cache_t *thiscache;
 	cache_head_t *cachehead;
 
-	if (wp == NULL || cpu_list == NULL) {
-		reinit = 0;
-		return;
-	}
-
 	/* Reinitialize free oversize blocks. */
 	(void) mutex_lock(&oversize_lock);
 	if (debugopt & MTDEBUGPATTERN)
@@ -1516,3 +1458,70 @@
 	ovsz_hdr->addr = (caddr_t)mem;
 	return (ovsz_hdr);
 }
+
+static void
+malloc_prepare()
+{
+	percpu_t *cpuptr;
+	cache_head_t *cachehead;
+	cache_t *thiscache;
+
+	(void) mutex_lock(&oversize_lock);
+	for (cpuptr = &cpu_list[0]; cpuptr < &cpu_list[ncpus]; cpuptr++) {
+		(void) mutex_lock(&cpuptr->mt_parent_lock);
+		for (cachehead = &cpuptr->mt_caches[0];
+		    cachehead < &cpuptr->mt_caches[NUM_CACHES];
+		    cachehead++) {
+			for (thiscache = cachehead->mt_cache;
+			    thiscache != NULL;
+			    thiscache = thiscache->mt_next) {
+				(void) mutex_lock(
+				    &thiscache->mt_cache_lock);
+			}
+		}
+	}
+}
+
+static void
+malloc_release()
+{
+	percpu_t *cpuptr;
+	cache_head_t *cachehead;
+	cache_t *thiscache;
+
+	for (cpuptr = &cpu_list[ncpus - 1]; cpuptr >= &cpu_list[0]; cpuptr--) {
+		for (cachehead = &cpuptr->mt_caches[NUM_CACHES - 1];
+		    cachehead >= &cpuptr->mt_caches[0];
+		    cachehead--) {
+			for (thiscache = cachehead->mt_cache;
+			    thiscache != NULL;
+			    thiscache = thiscache->mt_next) {
+				(void) mutex_unlock(
+				    &thiscache->mt_cache_lock);
+			}
+		}
+		(void) mutex_unlock(&cpuptr->mt_parent_lock);
+	}
+	(void) mutex_unlock(&oversize_lock);
+}
+
+#pragma init(malloc_init)
+static void
+malloc_init(void)
+{
+	/*
+	 * This works in the init section for this library
+	 * because setup_caches() doesn't call anything in libc
+	 * that calls malloc().  If it did, disaster would ensue.
+	 *
+	 * For this to work properly, this library must be the first
+	 * one to have its init section called (after libc) by the
+	 * dynamic linker.  If some other library's init section
+	 * ran first and called malloc(), disaster would ensue.
+	 * Because this is an interposer library for malloc(), the
+	 * dynamic linker arranges for its init section to run first.
+	 */
+	(void) setup_caches();
+
+	(void) pthread_atfork(malloc_prepare, malloc_release, malloc_release);
+}
--- a/usr/src/lib/libumem/Makefile.com	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/libumem/Makefile.com	Tue Mar 20 19:30:49 2007 -0700
@@ -161,6 +161,6 @@
 LINTFLAGS +=	-erroff=E_BAD_PTR_CAST_ALIGN
 LINTFLAGS64 +=	-erroff=E_BAD_PTR_CAST_ALIGN
 
-DYNFLAGS +=     $(ZINTERPOSE) $(ZINITFIRST)
+DYNFLAGS +=     $(ZINTERPOSE)
 
 .KEEP_STATE:
--- a/usr/src/lib/watchmalloc/Makefile.com	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/watchmalloc/Makefile.com	Tue Mar 20 19:30:49 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -39,7 +39,7 @@
 LDLIBS += -lc
 CFLAGS += $(CCVERBOSE)
 CFLAGS64 += $(CCVERBOSE)
-CPPFLAGS += -D_REENTRANT -I../common
+CPPFLAGS += -I../common -I../../common/inc -D_REENTRANT
 DYNFLAGS += $(ZINTERPOSE)
 
 .KEEP_STATE:
--- a/usr/src/lib/watchmalloc/common/mallint.h	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/watchmalloc/common/mallint.h	Tue Mar 20 19:30:49 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -29,10 +29,6 @@
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.2	*/
 
-#ifndef	_REENTRANT
-#define	_REENTRANT
-#endif
-
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -40,6 +36,7 @@
 #include <errno.h>
 #include <memory.h>
 #include <thread.h>
+#include <pthread.h>
 #include <synch.h>
 #include <procfs.h>
 #include <limits.h>
@@ -140,7 +137,3 @@
 #define	MAX_GETCORE (size_t)(SSIZE_MAX & ~(ALIGN - 1)) /* round down ALIGN */
 #define	MAX_MALLOC (size_t)(SIZE_MAX - CORESIZE - 3 * ALIGN) /* overflow chk */
 #define	MAX_ALIGN	(1 + (size_t)SSIZE_MAX)
-
-/* where are these *really* declared? */
-extern	int	_mutex_lock(mutex_t *mp);
-extern	int	_mutex_unlock(mutex_t *mp);
--- a/usr/src/lib/watchmalloc/common/malloc.c	Tue Mar 20 18:39:28 2007 -0700
+++ b/usr/src/lib/watchmalloc/common/malloc.c	Tue Mar 20 19:30:49 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -58,6 +58,7 @@
  *			Otherwise, it is always 0.
  */
 
+#include <c_synonyms.h>
 #include "mallint.h"
 
 static	mutex_t	__watch_malloc_lock = DEFAULTMUTEX;
@@ -164,9 +165,9 @@
 malloc(size_t size)
 {
 	void	*ret;
-	_mutex_lock(&__watch_malloc_lock);
+	(void) mutex_lock(&__watch_malloc_lock);
 	ret = malloc_unlocked(size);
-	_mutex_unlock(&__watch_malloc_lock);
+	(void) mutex_unlock(&__watch_malloc_lock);
 	return (ret);
 }
 
@@ -299,10 +300,10 @@
 	}
 
 	/* pointer to the block */
-	_mutex_lock(&__watch_malloc_lock);
+	(void) mutex_lock(&__watch_malloc_lock);
 	if (old == NULL) {
 		new = malloc_unlocked(size);
-		_mutex_unlock(&__watch_malloc_lock);
+		(void) mutex_unlock(&__watch_malloc_lock);
 		return (new);
 	}
 
@@ -318,7 +319,7 @@
 	if (!ISBIT0(ts)) {
 		/* XXX; complain here! */
 		protect(tp);
-		_mutex_unlock(&__watch_malloc_lock);
+		(void) mutex_unlock(&__watch_malloc_lock);
 		errno = EINVAL;
 		return (NULL);
 	}
@@ -327,7 +328,7 @@
 	if (size == SIZE(tp)) {	/* nothing to do */
 		SIZE(tp) = ts;
 		protect(tp);
-		_mutex_unlock(&__watch_malloc_lock);
+		(void) mutex_unlock(&__watch_malloc_lock);
 		return (old);
 	}
 
@@ -336,7 +337,7 @@
 		if (size == 0) {
 			SETOLD01(SIZE(tp), ts);
 			free_unlocked(old);
-			_mutex_unlock(&__watch_malloc_lock);
+			(void) mutex_unlock(&__watch_malloc_lock);
 			return (NULL);
 		}
 		goto call_malloc;
@@ -394,7 +395,7 @@
 		/* the previous block may be free */
 		SETOLD01(SIZE(tp), ts);
 		protect(tp);
-		_mutex_unlock(&__watch_malloc_lock);
+		(void) mutex_unlock(&__watch_malloc_lock);
 		return (old);
 	}
 
@@ -406,7 +407,7 @@
 			ts = size;
 		(void) memcpy(new, old, ts);
 		free_unlocked(old);
-		_mutex_unlock(&__watch_malloc_lock);
+		(void) mutex_unlock(&__watch_malloc_lock);
 		return (new);
 	}
 
@@ -432,7 +433,7 @@
 		if (size < SIZE(tp))		/* case 1. */ {
 			SETOLD01(SIZE(tp), ts);
 			protect(tp);
-			_mutex_unlock(&__watch_malloc_lock);
+			(void) mutex_unlock(&__watch_malloc_lock);
 			return (old);
 		} else if (size < MINSIZE)	/* case 2. */ {
 			size = MINSIZE;
@@ -461,7 +462,7 @@
 	}
 	SETOLD01(SIZE(tp), ts);
 	protect(tp);
-	_mutex_unlock(&__watch_malloc_lock);
+	(void) mutex_unlock(&__watch_malloc_lock);
 	/* malloc() sets errno */
 	return (NULL);
 }
@@ -1075,9 +1076,9 @@
 void
 free(void *old)
 {
-	_mutex_lock(&__watch_malloc_lock);
+	(void) mutex_lock(&__watch_malloc_lock);
 	free_unlocked(old);
-	_mutex_unlock(&__watch_malloc_lock);
+	(void) mutex_unlock(&__watch_malloc_lock);
 }
 
 
@@ -1168,7 +1169,7 @@
 		/* malloc sets errno */
 		return (NULL);
 	}
-	_mutex_lock(&__watch_malloc_lock);
+	(void) mutex_lock(&__watch_malloc_lock);
 
 	/*
 	 * get size of the entire block (overhead and all)
@@ -1242,7 +1243,7 @@
 	}
 	copy_pattern(LIVEPAT, aligned_blk);
 	protect(aligned_blk);
-	_mutex_unlock(&__watch_malloc_lock);
+	(void) mutex_unlock(&__watch_malloc_lock);
 	return (DATA(aligned_blk));
 }
 
@@ -1440,3 +1441,22 @@
 	ctl.prwatch.pr_wflags = 0;		/* clear the watched area */
 	(void) write(ctlfd, &ctl, sizeof (ctl));
 }
+
+static void
+malloc_prepare()
+{
+	(void) mutex_lock(&__watch_malloc_lock);
+}
+
+static void
+malloc_release()
+{
+	(void) mutex_unlock(&__watch_malloc_lock);
+}
+
+#pragma init(malloc_init)
+static void
+malloc_init(void)
+{
+	(void) pthread_atfork(malloc_prepare, malloc_release, malloc_release);
+}