Mercurial > illumos > illumos-gate
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); +}