"Ken Hagan" <[EMAIL PROTECTED]> writes:

> 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.

I think you may be missing the point that in some sense &k doesn't
have to have a single type.  At compile-time it can be manipulated as
though it's a different type of thing from other (non-TLS)
pointers-to-objects, while at runtime it will of course always be an
ordinary pointer.

>  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.

The behavior you describe above is IMO the only reasonable one, but
IMO we don't need the implementation details (tweaking page tables) in
order to achieve it.

>    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.

I disagree with your conclusion.  As I've said elsewhere, &k can be a
compile-time constant in the same way that &X::k is a compile-time
constant.  This is simple to accomplish from a conceptual POV, though
existing compilers may need some modification to support it.
Conceptually, the compile-time representation of addresses would have
to be something like this:

   struct address
   {
        type t;                    // the type of object being pointed at
        bool thread_local;        // whether it's thread-local
        unsigned logical_address;
   };

logical addresses would be assigned for TLS entities in the same way
as other "globals."  Typically physical addresses are not determined
until link-time.

>  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.

I don't know what you mean by "special pointer", and I don't see what
argument-passing has to do with it.  It's simply a matter of what code
gets generated to retrieve &k at the compile-time/runtime boundary.
Having different ways to get the address is no different conceptually
from having near and far variables, or variables which are local or in
some other DLL.

> 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.

I don't understand how this is different from the other options above.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to