DEPRECATED: use fork-malloc-uthread-4.11.patch.txt Index: /usr/src/lib/libc/gen/getlogin.c --- /usr/src/lib/libc/gen/getlogin.c Mon Oct 24 10:41:22 2005 +++ /usr/src/lib/libc/gen/getlogin.c Mon Oct 24 10:42:01 2005 @@ -54,7 +54,7 @@ #include #include "pthread_private.h" static struct pthread_mutex logname_lock = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t logname_mutex = &logname_lock; + pthread_mutex_t logname_mutex = &logname_lock; #define THREAD_LOCK() if (__isthreaded) pthread_mutex_lock(&logname_mutex) #define THREAD_UNLOCK() if (__isthreaded) pthread_mutex_unlock(&logname_mutex) #endif /* _THREAD_SAFE */ Index: /usr/src/lib/libc/gen/ttyname.c --- /usr/src/lib/libc/gen/ttyname.c Mon Oct 24 10:46:01 2005 +++ /usr/src/lib/libc/gen/ttyname.c Mon Oct 24 10:46:39 2005 @@ -52,7 +52,7 @@ #include #include "pthread_private.h" static struct pthread_mutex _ttyname_lockd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t ttyname_lock = &_ttyname_lockd; + pthread_mutex_t ttyname_lock = &_ttyname_lockd; static pthread_key_t ttyname_key; static int ttyname_init = 0; Index: /usr/src/lib/libc/stdio/findfp.c --- /usr/src/lib/libc/stdio/findfp.c Mon Oct 24 10:49:11 2005 +++ /usr/src/lib/libc/stdio/findfp.c Mon Oct 24 10:48:11 2005 @@ -87,9 +87,9 @@ static struct glue * moreglue __P((int)); -static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; -#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock) -#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock) + spinlock_t _findfp_thread_lock = _SPINLOCK_INITIALIZER; +#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&_findfp_thread_lock) +#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&_findfp_thread_lock) static struct glue * moreglue(n) Index: /usr/src/lib/libc/stdlib/atexit.c --- /usr/src/lib/libc/stdlib/atexit.c Mon Oct 24 10:49:32 2005 +++ /usr/src/lib/libc/stdlib/atexit.c Mon Oct 24 10:49:58 2005 @@ -48,10 +48,10 @@ #include "libc_private.h" #include "spinlock.h" -static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; + spinlock_t _atexit_thread_lock = _SPINLOCK_INITIALIZER; -#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock); -#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock); +#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&_atexit_thread_lock); +#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&_atexit_thread_lock); struct atexit *__atexit; /* points to head of LIFO stack */ Index: /usr/src/lib/libc/stdlib/malloc.c --- /usr/src/lib/libc/stdlib/malloc.c Mon Oct 24 10:50:31 2005 +++ /usr/src/lib/libc/stdlib/malloc.c Mon Oct 24 10:50:54 2005 @@ -60,9 +60,9 @@ */ # include "libc_private.h" # include "spinlock.h" - static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; -# define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock); -# define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock); + spinlock_t _malloc_thread_lock = _SPINLOCK_INITIALIZER; +# define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&_malloc_thread_lock); +# define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&_malloc_thread_lock); #endif /* __FreeBSD__ */ #if defined(__sparc__) && defined(sun) Index: /usr/src/lib/libc/stdtime/localtime.c --- /usr/src/lib/libc/stdtime/localtime.c Mon Oct 24 10:52:35 2005 +++ /usr/src/lib/libc/stdtime/localtime.c Mon Oct 24 10:53:13 2005 @@ -175,8 +175,8 @@ #ifdef _THREAD_SAFE static struct pthread_mutex _lcl_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; static struct pthread_mutex _gmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t lcl_mutex = &_lcl_mutexd; -static pthread_mutex_t gmt_mutex = &_gmt_mutexd; + pthread_mutex_t lcl_mutex = &_lcl_mutexd; + pthread_mutex_t gmt_mutex = &_gmt_mutexd; #endif char * tzname[2] = { Index: /usr/src/lib/libc/stdtime/strptime.c --- /usr/src/lib/libc/stdtime/strptime.c Mon Oct 24 10:53:49 2005 +++ /usr/src/lib/libc/stdtime/strptime.c Mon Oct 24 10:54:12 2005 @@ -79,7 +79,7 @@ #ifdef _THREAD_SAFE static struct pthread_mutex _gotgmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t gotgmt_mutex = &_gotgmt_mutexd; + pthread_mutex_t gotgmt_mutex = &_gotgmt_mutexd; #endif static int got_GMT; Index: /usr/src/lib/libc_r/uthread/uthread_fork.c --- /usr/src/lib/libc_r/uthread/uthread_fork.c Tue Aug 17 11:50:31 2004 +++ /usr/src/lib/libc_r/uthread/uthread_fork.c Mon Oct 24 11:08:47 2005 @@ -37,8 +37,56 @@ #include #include #include +#include #include "pthread_private.h" +/* Very ugly code to assure that none of the libc locks are locked when forking. + */ + +extern pthread_mutex_t logname_mutex; +extern pthread_mutex_t ttyname_lock; +extern pthread_mutex_t __getaddrinfo_thread_lock; +extern pthread_mutex_t lcl_mutex; +extern pthread_mutex_t gmt_mutex; +extern pthread_mutex_t gotgmt_mutex; +extern spinlock_t _findfp_thread_lock; +extern spinlock_t _atexit_thread_lock; +extern spinlock_t _malloc_thread_lock; + +static void +_fork_get_locks(void) +{ + if (__isthreaded) + { + (void)pthread_mutex_lock(&logname_mutex); + (void)pthread_mutex_lock(&ttyname_lock); + (void)pthread_mutex_lock(&__getaddrinfo_thread_lock); + (void)pthread_mutex_lock(&lcl_mutex); + (void)pthread_mutex_lock(&gmt_mutex); + (void)pthread_mutex_lock(&gotgmt_mutex); + _SPINLOCK(&_findfp_thread_lock); + _SPINLOCK(&_atexit_thread_lock); + _SPINLOCK(&_malloc_thread_lock); + } +} + +static void +_fork_release_locks(void) +{ + if (__isthreaded) + { + (void)pthread_mutex_unlock(&logname_mutex); + (void)pthread_mutex_unlock(&ttyname_lock); + (void)pthread_mutex_unlock(&__getaddrinfo_thread_lock); + (void)pthread_mutex_unlock(&lcl_mutex); + (void)pthread_mutex_unlock(&gmt_mutex); + (void)pthread_mutex_unlock(&gotgmt_mutex); + _SPINUNLOCK(&_findfp_thread_lock); + _SPINUNLOCK(&_atexit_thread_lock); + _SPINUNLOCK(&_malloc_thread_lock); + } +} + pid_t _fork(void) { @@ -48,6 +96,12 @@ pthread_t pthread; pthread_t pthread_save; + /* Get all the locks in libc so that the new process will start in a + * consistent state. + */ + + _fork_get_locks(); + /* * Defer signals to protect the scheduling queues from access * by the signal handler: @@ -109,6 +163,11 @@ /* Abort this application: */ PANIC("Cannot initialize priority ready queue."); } else { + /* Release all the libc locks so that we can do things. + */ + + _fork_release_locks(); + /* * Enter a loop to remove all threads other than * the running thread from the thread list: @@ -213,6 +272,11 @@ * Undefer and handle pending signals, yielding if necessary: */ _thread_kern_sig_undefer(); + + /* Release all the locks that we have in libc. + */ + + _fork_release_locks(); /* Return the process ID: */ return (ret);