From owner-freebsd-threads@FreeBSD.ORG Wed Mar 2 14:56:24 2005 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 87EF416A4CE for ; Wed, 2 Mar 2005 14:56:24 +0000 (GMT) Received: from mail.emict.com (brig.emict.com [212.90.172.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9900143D39 for ; Wed, 2 Mar 2005 14:56:20 +0000 (GMT) (envelope-from andrit@ukr.net) Received: from BORJA (unknown [203.199.120.221]) by mail.emict.com (Postfix) with ESMTP id EBCD733390 for ; Wed, 2 Mar 2005 16:56:09 +0200 (EET) Message-ID: <000e01c51f37$fb3dc980$090210ac@BORJA> From: "Andriy Tkachuk" To: Date: Wed, 2 Mar 2005 20:26:02 +0530 MIME-Version: 1.0 X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 Content-Type: text/plain; charset="koi8-r" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.1 Subject: patch for threads/76690 - critical - fork hang in child for -lc_r X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Mar 2005 14:56:24 -0000 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.