Thread Local Storage

Julian Elischer julian at elischer.org
Mon Mar 29 11:27:03 PST 2004


Doug Rabson wrote:
> I've been spending a bit of time recently familiarising myself with this 
> TLS stuff and trying out a few things. I've been playing with rtld and 
> I have a prototype patch which implements enough TLS support to let a 
> non-threaded program which uses static TLS work. With a tiny bit more 
> work I can have limited support for dynamic TLS as well (not for 
> dlopen'ed modules yet though). Is there a p4 tree for this stuff yet? 
> I'd like to check in what I have sometime.

there is a KSE  p4 tree that is curently unused as we have everything
in CVS at the moment..

> 
> I've also been looking at libpthread and I can see some potential 
> problems with it. Currently libpthread on i386 uses %gs to point at a 
> struct kcb which seems to be a per-kse structure. This structure 
> contains a pointer to a per-thread struct tcb and this pointer is 
> managed by the userland context switch code. Other arches are similar, 
> e.g. ia64 uses $tp to point at struct kcb.

We're ahead of you there :-)
In fact the spec requires that %gs:0 is the address of a POINTER to the
per thread stuff.. The kse mailbox that %gs points to has reserved a field at 
this location to be that pointer.


> 
> The problem with TLS is that the i386 ABI needs %gs to point at the TLS 
> storage for the current thread (its a tiny bit more involved than that 
> but that doesn't matter much for the purposed of this discussion). This 
> leads to trouble since it looks like we will end up needing to allocate 
> an LDT segment per thread, leading to an arbitrary limit on the number 
> of threads (~8192).


No, you missed a level of indirection :-) (I did too originally).
The x86 version of the spec (SUN variant) expects there to be a double indirection.
ths allows the UTS to keep the pointer up to date as to which thread
is running on that KSE.



> 
> I can think of a couple of possible ways to get around this. One easy 
> way would be to allocate a segment per KSE and call i386_set_ldt from 
> the thread switch. Pretty ugly really and takes a syscall. Another 
> slightly better way would be to lazy-allocate segments when we switch 
> threads and reclaim segments from threads which haven't run recently. 
> This technique would be able to get away with a smaller number of 
> segments which tend to be owned by the threads which run most often.
> 
> There is a similar issue with libthr but since it already allocates an 
> LDT entry per thread there are no new limitations. Linux has an 
> interesting wrinkle on the libthr solution - they have a GDT per cpu 
> and they pre-allocate three GDT slots for TLS pointers (one for glibc, 
> one for Wine and one spare). The kernel thread switching code fills in 
> these GDT slots on the current cpu with values stored in the 
> pcb-equivalent.


Yes in fact we are looking at switching to something similar..
a GDT entry per CPU that the UTS plugs with "what I am running now" info
for that CPU.


> _______________________________________________
> freebsd-threads at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-threads
> To unsubscribe, send any mail to "freebsd-threads-unsubscribe at freebsd.org"
> 


-- 
+------------------------------------+       ______ _  __
|   __--_|\  Julian Elischer         |       \     U \/ / hard at work in
|  /       \ julian at elischer.org     +------>x   USA    \ a very strange
| (   OZ    )                                \___   ___ | country !
+- X_.---._/    presently in San Francisco       \_/   \\
           v



More information about the freebsd-threads mailing list