qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC 1/2] tls: add macros for coroutine-safe TLS variables


From: Richard Henderson
Subject: Re: [RFC 1/2] tls: add macros for coroutine-safe TLS variables
Date: Mon, 25 Oct 2021 10:19:04 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0

On 10/25/21 7:07 AM, Stefan Hajnoczi wrote:
Compiler optimizations can cache TLS values across coroutine yield
points, resulting in stale values from the previous thread when a
coroutine is re-entered by a new thread.
...
  include/qemu/tls.h | 142 +++++++++++++++++++++++++++++++++++++++++++++

Better as qemu/coroutine-tls.h, since it is needed for no other purpose.

+#define QEMU_DEFINE_TLS(type, var) \
+    __thread type qemu_tls_##var; \
+    type get_##var(void) { return qemu_tls_##var; } \
+    void set_##var(type v) { qemu_tls_##var = v; }

You might as well make the variable static, since it may only be referenced by these two functions.

+#define QEMU_DEFINE_STATIC_TLS(type, var) \
+    static __thread type qemu_tls_##var; \
+    static __attribute__((noinline)) type get_##var(void); \
+    static type get_##var(void) { return qemu_tls_##var; } \
+    static __attribute__((noinline)) void set_##var(type v); \
+    static void set_##var(type v) { qemu_tls_##var = v; }

You don't need separate function declarations; you can fold them together.

If would be nice to inline this when possible,

#if defined(__aarch64__)
#define QEMU_COROUTINE_TLS_ADDR(RET, VAR)                       \
    asm volatile("mrs %0, tpidr_el0\n\t"                        \
                 "add %0, %0, #:tprel_hi12:"#VAR", lsl #12\n\t" \
                 "add %0, %0, #:tprel_lo12_nc:"#VAR             \
                 : "=r"(RET))
#elif defined(__powerpc64__)
#define QEMU_COROUTINE_TLS_ADDR(RET, VAR)                       \
    asm volatile("addis %0,13,"#VAR"@tprel@ha\n\t"              \
                 "add   %0,%0,"#VAR"@tprel@l"                   \
                 : "=r"(RET))
#elif defined(__riscv)
#define QEMU_COROUTINE_TLS_ADDR(RET, VAR)                       \
    asm volatile("lui  %0,%%tprel_hi("#VAR")\n\t"               \
                 "add  %0,%0,%%tprel_add("#VAR")\n\t"           \
                 "addi %0,%0,%%tprel_lo("#VAR")"                \
                 : "=r"(RET))
#elif defined(__x86_64__)
#define QEMU_COROUTINE_TLS_ADDR(RET, VAR)                       \
    asm volatile("mov %%fs:"#VAR"@tpoff, %0" : "=r"(RET))
#endif

#ifdef QEMU_COROUTINE_TLS_ADDR
#define QEMU_COROUTINE_TLS_DECLARE(TYPE, VAR)                   \
    extern __thread TYPE co_tls_##VAR;                          \
    static inline TYPE get_##VAR(void)                          \
    { TYPE *p; QEMU_COROUTINE_TLS_ADDR(p, co_tls_##VAR); return *p; } \
    static inline void set_##VAR(TYPE v)                        \
    { TYPE *p; QEMU_COROUTINE_TLS_ADDR(p, co_tls_##VAR); *p = v; }
#else
    etc
#endif


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]