Changeset 14827

Jun 15, 2011, 8:09:24 AM (8 years ago)

Until a few years ago, when HAVE_TLS was defined we had:

#ifdef HAVE_TLS
__thread TCR current_tcr;

and things like get_tcr(true) did:

#ifdef HAVE_TLS
current = &current_tcr;

On x8632/64 (which were the only platforms where HAVE_TLS might have
been defined), the TCR always existed (as long as the thread did) and
could be assumed to be initialized if tcr.linear was non-zero. On x8664
when HAVE_TLS was defined, _SPcallback could avoid having to call
get_tcr(true) if this was the case, and the magic

	 __(movq %fs:current_tcr@TPOFF+tcr.linear,%rax)

was a reliable way of testing for that.

Despite the fact that some versions of the TCR structure were defined
to have vector-typed fields, the toolchains on some platforms didn't
guarantee that the thread-local TCR structure was properly aligned, so
things changed to:

#ifdef HAVE_TLS
__thread char tcrbuf[sizeof(TCR)+16];
__thread TCR *current_tcr;

and new_tcr() initialized the thread-local variable current_tcr to
a properly-aligned pointer within tcrbuf. The test in _SPcallback wasn't
updated, and the magic incantation was testing random some memory location
tcr.linear bytes away from the address of the variable current_tcr in
thread-local storage. If this happened to be NULL, we'd call get_tcr(true)
and it'd notice that current_tcr was NULL and set things up; if the random
location's contents was non-null, we'd assume that %gs/%gsbase pointed to
this thread's TCR (and they generally didn't.)

With that explanation out of the way:

in _SPcallback on x8664, if HAVE_TLS is true, just check to see if
current_tcr is non-NULL to avoid having to call get_tcr(true).

I don't think that any other platforms tried to perform this check,
and it's harmless (just wastes a few cycles) to call get_tcr(true)
if we aren't sure whether or not the current thread has a TCR.

1 edited


  • trunk/source/lisp-kernel/x86-spentry64.s

    r14805 r14827  
    46364636         /* TCR initialized for lisp ?   */
    46374637         __ifndef(`TCR_IN_GPR') /* FIXME */
    4638          __(movq %fs:current_tcr@TPOFF+tcr.linear,%rax)
     4638         __(movq %fs:current_tcr@TPOFF,%rax)
    46394639         __(testq %rax,%rax)
    46404640         __(jne 1f)
Note: See TracChangeset for help on using the changeset viewer.