Thread Local Storage
Julian Elischer
julian at elischer.org
Mon Mar 29 14:27:58 PST 2004
On Mon, 29 Mar 2004, Doug Rabson wrote:
> On Monday 29 March 2004 22:50, Julian Elischer wrote:
> > On Mon, 29 Mar 2004, Doug Rabson wrote:
> > > How do you do that without an expensive syscall?
> >
> > Each cpu has a GDT entry pointing to a slightly different location
> > and the kernel and the UTS co-operate as to making the contents of
> > that location keep track of the thread currently running. The kernel
> > always makes sure that %gs points to the correct place when it goes
> > back to userland and teh contents of that location is saved whenever
> > a thread sleeps and is restored whenever it wakes up again.
> >
> > it can even be in kernel memory space as long as teh segment
> > is defined as r/w to the user and the segment size is limitted to
> > just that region it is allowed to read from.
> > This actualy gives us a 'per thread' pointer rather than a per-kse
> > pointer which might allow us to go to the GNU version of TLS but we
> > haven't worked out the details..
> > David and peter have both looked at this but we haven't actually
> > tried to do it yet..
>
> Yes, I understand about the per-cpu GDT thing. I've been reading linux
> kernel code and glibc all afternoon and my brain is melting :-). It
> would work great for libthr.
>
> For the GNU TLS ABI, the %gs segment can't be in kernel space because of
> the negative offset thing which is generated by the local exec TLS
> model. That idiom requires the %gs segment to have a 4G limit so that
> the negative addresses can wrap round properly. If it wasn't for that
> single 'optimisation', we could just go with the GNU model right now.
and how do they stop the user from accessing kernel space then?
>
> My question is, given that we are switching threads in userland, how can
> we get the right contents for the GDT without a syscall?
>
as you note,
The thread library and the dynamic linker know ahead of time the size of
the static area needed for each thread.. i.e. the size of
the area addresed -vely.
Unfortunatly you an only make use of this for N:N threads
(I dislike teh term 1:1, which in my mind is a single threaded program)
If you compile libpthread in 1:1 mode (define FORCE_SCOPE_SYSTEM when
you compile it) then this would work for us but for M:N threads it woudl
require a syscall for every context switch
(which removes the whole point of M:N threads. The reason for M:N
threads is the ability to hop between threads in userspace without doing
a kernel entry.
I tend to believe that going with the solaris model is good enough
for now and that we can try optimise later if we think its worth while.
We can use a 'simple per-CPU GDT %gs' and the solaris model and
get enough for our purposes...
lets just go with that..
amd64 and ia64 have their own challenges.
More information about the freebsd-threads
mailing list