|
Boost : |
From: Ken Hagan (K.Hagan_at_[hidden])
Date: 2003-02-20 05:00:22
Reading various replies, we appear to have a couple of things that
aren't completely pinned down: the type of "&k" and the implementation
of TLS.
1 If "&k" is a regular pointer to integer and TLS is implemented by
tweaking page tables for each thread, then "&k" has the same value
in each thread and C<&k> is the same type, but any member of C<&K>
that uses its template parameter will behave differently from one
thread to another.
Is this a problem. I don't think so. Consider...
__declspec(thread) k
int foo() { return k; }
We can easily write a template, C, and instantiate it "C<&k>" and
have its behaviour vary per-thread, although the value of the
template parameter is the same.
With this TLS implementation, we can't expose TLS data to another
thread except by copying it. The workaround is simply to store a
pointer to the actual data or object.
2 If "&k" is a regular pointer and TLS is implemented by allocating
separate blocks for each thread and storing the addresses in a
register, then "&k" has a different value in each thread and is no
longer a compile time constant so you can't write the template.
3 If "&k" is a special pointer, then we can implement TLS either way,
but we must define a conversion between special and regular pointers.
For ordinary functions expecting "int*" the compiler simply invokes
this conversion when passing the argument and no-one gets upset.
However, for the template case, that conversion is a run-time
operation so it clearly can't apply.
3a If we allow C<&k>, then "&k" is the offset into the TLS table, the
instantiated code includes the conversion, and C<&k> is the same
type in every thread because the offset is the same. It is then
possible to initialise static variables with the converted value
of "&k" and the results depend on the thread that ran first. Again,
we have the same "problem" passing a pointer to a function, so I'm
not bothered by this.
Alternatively, we could insist that template authors explicitly
declare their template parameter to be "int __thread*", but I don't
see that this buys us anything. On the contrary, it makes explicit
a whole new kind of pointer.
Alternatively, we could just ban the template instantiation, forcing
users to write the helper function "foo()" and instantiate on that.
Again, I don't think this buys us anything.
I think 3a describes the "existing practice" of MSVC and is the solution
that offers the greatest flexibility, allowing templates to be written
naturally and TLS data to be shared between threads if that's really
what you want to do.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk