How to understand the macro, get_tls, and identifier,TLS, when I read function, runtime·rt0_go?

Viewed 106

Recently, I want to learn detail process about start of Go program.However, when I read some code about thread local storage, I get confused. The following snippet is from lines 183 to 198 of source file named runtime/asm_amd64.s:

    LEAQ    runtime·m0+m_tls(SB), DI
    CALL    runtime·settls(SB)

    // store through it, to make sure it works
    get_tls(BX)
    MOVQ    $0x123, g(BX)
    MOVQ    runtime·m0+m_tls(SB), AX
    CMPQ    AX, $0x123
    JEQ 2(PC)
    CALL    runtime·abort(SB)
    ok:
    // set the per-goroutine and per-mach "registers"
    get_tls(BX)
    LEAQ    runtime·g0(SB), CX
    MOVQ    CX, g(BX)
    LEAQ    runtime·m0(SB), AX

To place g0 into TLS, three line codes following label "ok" need to be executed:

get_tls(BX)
LEAQ runtime·g0(SB),CX
MOVQ CX,g(BX)

But when I find the defination of "get_tls",which comes from lines 9 to 12 of runtime/go_tls.h,I can't understand macro get_tls:

#ifdef GOARCH_amd64
#define get_tls(r)  MOVQ TLS, r
#define g(r)    0(r)(TLS*1)
#endif

What is the "TLS"? Is it a register of amd64 archtecture,which I don't know?How does the program get thread local storage through it?

Thank you for your answers.

2 Answers

I believe that on architectures that have a sufficient number of registers (e.g. amd64 but not i386), one CPU register is permanently holding a pointer to the thread-local storage area.

For other architectures, there is a different (slower) path to avoid the permanent use of a register.

Related