|
From: Jeremy F. <je...@go...> - 2003-11-17 01:19:19
|
On Fri, 2003-11-14 at 08:51, Tom Hughes wrote: > As valgrind has it's own libpthread we would have to work out how > setup the thread area for the new thread, which seems to be very > complicated as the GDT entry set in the kernel seems to point at a > thread descriptor structure which in turns points at the TLS data > and so on. OK, I looked at this in more detail. There are two parts of the puzzle: 1: There's the kernel mechanism for setting up a thread-local storage area, using the set_thread_area syscall. The argument to this is a segment descriptor, like the one used for set_ldt. This segment descriptor is assigned to one of the 3 TLS entries in the GDT. On thread context switch, the kernel reassigns the GDT entries to the thread's TLS segment. The thread itself assigns that descriptor to one of its segment registers, and uses %seg:0 as the pointer to its TLS area. This is easy for us to implement, since Julian has already done the hard work. We can store a per-thread "GDT" containing only these entries as part of each Thread structure. In VG_(do_useg)() we just look for the GDT (vs LDT) bit in the segment selector and do the appropriate thing. 2: All this is to support the new TLS extensions to the ABI. These are described in detail in http://people.redhat.com/drepper/tls.pdf. I've read this once, but I still don't understand the details. The essential point is that ELF files can now have a PT_TLS segment which is used as a prototype segment for thread-local variables. When a new thread is created, it effectively gets a new copy of the contents of the PT_TLS segment attached to its own thread area (pointed to via %gs). This is does lazily, so only the TLS segments which the thread actually uses are copied for it. This means that there's cooperation between the dynamic linker and libpthread. Since we control the one but not the other, we need to make our libpthread compatible with the dynamic linker's TLS implementation. The ABI documents some of this, but unfortunately it only documents the compiler interface to this goo, but not the internal interfaces between libpthread and the ld.so. The easy part of this is making sure that new threads get their own new TLS areas (which the glibc libpthread does by passing CLONE_SETTLS to clone(), which is the equivalent of doing set_thread_area() in the new thread). Trickier is getting the details of all the other structures right. And since they're internal to glibc, there's no certainty they won't change from release to release... BTW, this is completely independent of NPTL. The TLS stuff is an extension to the ABI which is also supported by the pre-NPTL threads library (though I'm not sure how they make do without the set_thread_area syscall). BTW(2): Nvidia will use set_thread_area and this tls mechanism when available. Otherwise they implement it themselves using a similar segment trick. In summary, I'm not sure what to do about this. J |