| From | Sent On | Attachments |
|---|---|---|
| Andriy Tkachuk | Mar 2, 2005 2:56 pm | |
| Daniel Eischen | Mar 2, 2005 3:47 pm | |
| Andriy Tkachuk | Mar 3, 2005 6:35 am | |
| Daniel Eischen | Mar 3, 2005 6:46 am | |
| David Xu | Mar 3, 2005 6:48 am | |
| Andriy Tkachuk | Mar 3, 2005 6:58 am | .patch |
| Andriy Tkachuk | Mar 3, 2005 7:29 am | .cc |
| Andriy Tkachuk | Mar 3, 2005 8:07 am | |
| Andriy Tkachuk | Mar 3, 2005 8:10 am | |
| Andriy Tkachuk | Mar 3, 2005 8:15 am | |
| David Xu | Mar 3, 2005 8:15 am | |
| Andriy Tkachuk | Mar 3, 2005 8:44 am | |
| Andriy Tkachuk | Mar 3, 2005 9:26 am | .patch2 |
| David Xu | Mar 3, 2005 10:46 am | |
| Daniel Eischen | Mar 3, 2005 3:14 pm | |
| Julian Elischer | Mar 3, 2005 8:29 pm | |
| David Xu | Mar 4, 2005 3:24 am | |
| Andriy Tkachuk | Mar 4, 2005 5:57 am |
| Subject: | patch for threads/76690 - critical - fork hang in child for -lc_r | |
|---|---|---|
| From: | Andriy Tkachuk (and...@ukr.net) | |
| Date: | Mar 2, 2005 2:56:05 pm | |
| List: | org.freebsd.freebsd-threads | |
Hi folks.
I spent some time on the problem in $subj and found some solution that seems to be working but i'm not sure about it's architectural correctness because libc was changed little bit ;)
here it is:
# diff -u -r lib lib.patched
diff -u -r lib/libc/stdlib/malloc.c lib.patched/libc/stdlib/malloc.c
--- lib/libc/stdlib/malloc.c Sun Feb 27 22:46:16 2005
+++ lib.patched/libc/stdlib/malloc.c Wed Mar 2 19:55:24 2005
@@ -74,7 +74,7 @@
*/
# include "libc_private.h"
# include "spinlock.h"
- static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
+ spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
spinlock_t *__malloc_lock = &thread_lock;
# define _MALLOC_LOCK() if (__isthreaded)
_SPINLOCK(&thread_lock);
# define _MALLOC_UNLOCK() if (__isthreaded)
_SPINUNLOCK(&thread_lock);
diff -u -r lib/libc_r/uthread/uthread_fork.c
lib.patched/libc_r/uthread/uthread_fork.c
--- lib/libc_r/uthread/uthread_fork.c Fri Dec 10 09:06:45 2004
+++ lib.patched/libc_r/uthread/uthread_fork.c Wed Mar 2 20:10:49 2005
@@ -61,6 +61,8 @@
_thread_kern_sig_defer();
_pthread_mutex_lock(&_atfork_mutex); + extern spinlock_t thread_lock; + _SPINLOCK(&thread_lock);
/* Run down atfork prepare handlers. */ TAILQ_FOREACH_REVERSE(af, &_atfork_list, atfork_head, qe) { @@ -70,6 +72,8 @@
/* Fork a new process: */ if ((ret = __sys_fork()) != 0) { + _SPINUNLOCK(&thread_lock); + /* Run down atfork parent handlers. */ TAILQ_FOREACH(af, &_atfork_list, qe) { if (af->parent != NULL) @@ -78,6 +82,8 @@ _pthread_mutex_unlock(&_atfork_mutex);
} else { + _SPINUNLOCK(&thread_lock); + /* Close the pthread kernel pipe: */ __sys_close(_thread_kern_pipe[0]); __sys_close(_thread_kern_pipe[1]);
The main problem with it is that after fork child inherits from the parent inconsist heap. So the obvious solution is to synchronyze the fork and heap manipulations. I didn't find the easyest way how to get the lock variable from malloc lib as to open this variable deleting static spec.
So what do you think guys about this patch?
Thanks, Andriy Tkachuk.






.patch