Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Mar 2005 20:26:02 +0530
From:      "Andriy Tkachuk" <andrit@ukr.net>
To:        <threads@freebsd.org>
Subject:   patch for threads/76690 - critical - fork hang in child for -lc_r
Message-ID:  <000e01c51f37$fb3dc980$090210ac@BORJA>

next in thread | raw e-mail | index | archive | help
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      =3D _SPINLOCK_INITIALIZER;
+    spinlock_t thread_lock     =3D _SPINLOCK_INITIALIZER;
     spinlock_t *__malloc_lock          =3D &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 =3D __sys_fork()) !=3D 0) {
+               _SPINUNLOCK(&thread_lock);
+
                /* Run down atfork parent handlers. */
                TAILQ_FOREACH(af, &_atfork_list, qe) {
                        if (af->parent !=3D 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.






Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000e01c51f37$fb3dc980$090210ac>