From owner-freebsd-ppc@FreeBSD.ORG Fri Sep 1 18:17:10 2006 Return-Path: X-Original-To: ppc@FreeBSD.org Delivered-To: freebsd-ppc@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B247A16A4E6 for ; Fri, 1 Sep 2006 18:17:10 +0000 (UTC) (envelope-from xcllnt@mac.com) Received: from smtpout.mac.com (smtpout.mac.com [17.250.248.182]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6750C43D55 for ; Fri, 1 Sep 2006 18:17:09 +0000 (GMT) (envelope-from xcllnt@mac.com) Received: from mac.com (smtpin07-en2 [10.13.10.152]) by smtpout.mac.com (Xserve/8.12.11/smtpout12/MantshX 4.0) with ESMTP id k81IH97u005362 for ; Fri, 1 Sep 2006 11:17:09 -0700 (PDT) Received: from [192.168.1.5] (c-67-164-11-148.hsd1.ca.comcast.net [67.164.11.148]) (authenticated bits=0) by mac.com (Xserve/smtpin07/MantshX 4.0) with ESMTP id k81IH7Ea003096 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 1 Sep 2006 11:17:08 -0700 (PDT) Mime-Version: 1.0 (Apple Message framework v752.2) Content-Transfer-Encoding: 7bit Message-Id: <933C0437-DDF8-4A61-83BA-F4920D9E6E96@mac.com> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed To: ppc@FreeBSD.org From: Marcel Moolenaar Date: Fri, 1 Sep 2006 11:16:30 -0700 X-Mailer: Apple Mail (2.752.2) Cc: Subject: Status of threading and TLS X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Sep 2006 18:17:10 -0000 All, I've been working on TLS for both ia64 and powerpc and all is well... except for one nasty bugger on powerpc. Here's the status on powerpc: TLS for non-threaded statically linked applications: working TLS for non-threaded dynamically linked applications: working TLS for statically linked 1:1 (libthr): working TLS for dynamically linked 1:1 (libthr): working TLS for statically linked M:N (libpthread): bugger! TLS for dynamically linked M:N (libpthread: bugger! The bugger for libpthread is that register r2 (the TLS pointer) is off by 8 bytes. I have no idea where that happens and I've been going over the code a hundred times. It's obvious that I either developed a blind spot, or I'm not looking in the right place. I need your help before I can have malloc(3) use TLS safely! To demon strate the problem, assume the following program: \begin{verbatim} #include #include int __thread i = -1; static void * thread(void *arg) { int j; j = (int)arg; return (arg); } int main(int argc, char *argv[]) { pthread_t pt; int err; err = pthread_create(&pt, NULL, thread, i); pthread_join(pt, NULL); return (0); } \end{verbatim} If I link it with libthr, run it in the debugger with breakpoints on main() and thread(), I can inspect register r2: : : (gdb) run Starting program: /nfs/home/marcel/t Breakpoint 1, main (argc=1, argv=0x7fffdc04) at t.c:21 21 err = pthread_create(&pt, NULL, thread, i); (gdb) p $r2 $1 = 27308344 (gdb) p ((int *)($r2 - 0x7008))[0] $2 = 27279680 (gdb) p ((int *)($r2 - 0x7008))[2] $3 = -1 The magic above means the following: r2 holds the address of the thread pointer of the main thread $2 holds the address of the DTV. The DTV is at TLS[0] $3 holds the value of the thread local variable i. It is -1. Now, to see how this pans out for the first thread: (gdb) c Continuing. Breakpoint 2, thread (arg=0xffffffff) at t.c:11 11 j = (int)arg; (gdb) p $r2 $4 = 27308376 (gdb) p ((int *)($r2 - 0x7008))[0] $5 = 27279712 (gdb) p ((int *)($r2 - 0x7008))[2] $6 = -1 Expected results. Now, if I link against libpthread I get the following: : : (gdb) run Starting program: /nfs/home/marcel/t Breakpoint 1, main (argc=1, argv=0x7fffdc04) at t.c:21 21 err = pthread_create(&pt, NULL, thread, i); (gdb) p $r2 $1 = 27493528 (gdb) p ((int *)($r2 - 0x7008))[0] $2 = 0 (gdb) p ((int *)($r2 - 0x7008))[2] $3 = 27279680 This is wrong. But... (gdb) p ((int *)($r2 - 0x7008))[4] $4 = -1 It appears that register r2 is off by 8 bytes. Let me double check. DTV entry 2 should point to the thread local variable i (lucky us): (gdb) p /x ((int *)$3)[2] $5 = 0x1a314a0 (gdb) p &((int *)($r2 - 0x7008))[4] $6 = (int *) 0x1a314a0 Yup. Now how this happens, I don't know. If anyone has any suggestions why for libpthread we end up with r2 off by 8 bytes, I'm happy to hear it... -- Marcel Moolenaar xcllnt@mac.com