hw/i2c: add asynchronous send
[qemu.git] / include / qemu / coroutine-tls.h
blob1558a826aa0dcb9ede1b3328d21a1358db1ccb73
1 /*
2 * QEMU Thread Local Storage for coroutines
4 * Copyright Red Hat
6 * SPDX-License-Identifier: LGPL-2.1-or-later
8 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
9 * See the COPYING.LIB file in the top-level directory.
11 * It is forbidden to access Thread Local Storage in coroutines because
12 * compiler optimizations may cause values to be cached across coroutine
13 * re-entry. Coroutines can run in more than one thread through the course of
14 * their life, leading bugs when stale TLS values from the wrong thread are
15 * used as a result of compiler optimization.
17 * An example is:
19 * ..code-block:: c
20 * :caption: A coroutine that may see the wrong TLS value
22 * static __thread AioContext *current_aio_context;
23 * ...
24 * static void coroutine_fn foo(void)
25 * {
26 * aio_notify(current_aio_context);
27 * qemu_coroutine_yield();
28 * aio_notify(current_aio_context); // <-- may be stale after yielding!
29 * }
31 * This header provides macros for safely defining variables in Thread Local
32 * Storage:
34 * ..code-block:: c
35 * :caption: A coroutine that safely uses TLS
37 * QEMU_DEFINE_STATIC_CO_TLS(AioContext *, current_aio_context)
38 * ...
39 * static void coroutine_fn foo(void)
40 * {
41 * aio_notify(get_current_aio_context());
42 * qemu_coroutine_yield();
43 * aio_notify(get_current_aio_context()); // <-- safe
44 * }
47 #ifndef QEMU_COROUTINE_TLS_H
48 #define QEMU_COROUTINE_TLS_H
51 * To stop the compiler from caching TLS values we define accessor functions
52 * with __attribute__((noinline)) plus asm volatile("") to prevent
53 * optimizations that override noinline.
55 * The compiler can still analyze noinline code and make optimizations based on
56 * that knowledge, so an inline asm output operand is used to prevent
57 * optimizations that make assumptions about the address of the TLS variable.
59 * This is fragile and ultimately needs to be solved by a mechanism that is
60 * guaranteed to work by the compiler (e.g. stackless coroutines), but for now
61 * we use this approach to prevent issues.
64 /**
65 * QEMU_DECLARE_CO_TLS:
66 * @type: the variable's C type
67 * @var: the variable name
69 * Declare an extern variable in Thread Local Storage from a header file:
71 * .. code-block:: c
72 * :caption: Declaring an extern variable in Thread Local Storage
74 * QEMU_DECLARE_CO_TLS(int, my_count)
75 * ...
76 * int c = get_my_count();
77 * set_my_count(c + 1);
78 * *get_ptr_my_count() = 0;
80 * This is a coroutine-safe replacement for the __thread keyword and is
81 * equivalent to the following code:
83 * .. code-block:: c
84 * :caption: Declaring a TLS variable using __thread
86 * extern __thread int my_count;
87 * ...
88 * int c = my_count;
89 * my_count = c + 1;
90 * *(&my_count) = 0;
92 #define QEMU_DECLARE_CO_TLS(type, var) \
93 __attribute__((noinline)) type get_##var(void); \
94 __attribute__((noinline)) void set_##var(type v); \
95 __attribute__((noinline)) type *get_ptr_##var(void);
97 /**
98 * QEMU_DEFINE_CO_TLS:
99 * @type: the variable's C type
100 * @var: the variable name
102 * Define a variable in Thread Local Storage that was previously declared from
103 * a header file with QEMU_DECLARE_CO_TLS():
105 * .. code-block:: c
106 * :caption: Defining a variable in Thread Local Storage
108 * QEMU_DEFINE_CO_TLS(int, my_count)
110 * This is a coroutine-safe replacement for the __thread keyword and is
111 * equivalent to the following code:
113 * .. code-block:: c
114 * :caption: Defining a TLS variable using __thread
116 * __thread int my_count;
118 #define QEMU_DEFINE_CO_TLS(type, var) \
119 static __thread type co_tls_##var; \
120 type get_##var(void) { asm volatile(""); return co_tls_##var; } \
121 void set_##var(type v) { asm volatile(""); co_tls_##var = v; } \
122 type *get_ptr_##var(void) \
123 { type *ptr = &co_tls_##var; asm volatile("" : "+rm" (ptr)); return ptr; }
126 * QEMU_DEFINE_STATIC_CO_TLS:
127 * @type: the variable's C type
128 * @var: the variable name
130 * Define a static variable in Thread Local Storage:
132 * .. code-block:: c
133 * :caption: Defining a static variable in Thread Local Storage
135 * QEMU_DEFINE_STATIC_CO_TLS(int, my_count)
136 * ...
137 * int c = get_my_count();
138 * set_my_count(c + 1);
139 * *get_ptr_my_count() = 0;
141 * This is a coroutine-safe replacement for the __thread keyword and is
142 * equivalent to the following code:
144 * .. code-block:: c
145 * :caption: Defining a static TLS variable using __thread
147 * static __thread int my_count;
148 * ...
149 * int c = my_count;
150 * my_count = c + 1;
151 * *(&my_count) = 0;
153 #define QEMU_DEFINE_STATIC_CO_TLS(type, var) \
154 static __thread type co_tls_##var; \
155 static __attribute__((noinline, unused)) \
156 type get_##var(void) \
157 { asm volatile(""); return co_tls_##var; } \
158 static __attribute__((noinline, unused)) \
159 void set_##var(type v) \
160 { asm volatile(""); co_tls_##var = v; } \
161 static __attribute__((noinline, unused)) \
162 type *get_ptr_##var(void) \
163 { type *ptr = &co_tls_##var; asm volatile("" : "+rm" (ptr)); return ptr; }
165 #endif /* QEMU_COROUTINE_TLS_H */