uatomic/x86: Remove redundant memory barriers
[urcu.git] / include / urcu / annotate.h
1 // SPDX-FileCopyrightText: 2023 Olivier Dion <odion@efficios.com>
2 //
3 // SPDX-License-Identifier: LGPL-2.1-or-later
4
5 #ifndef _URCU_ANNOTATE_H
6 #define _URCU_ANNOTATE_H
7
8 /*
9 * urcu/annotate.h
10 *
11 * Userspace RCU - annotation header.
12 */
13
14 /*
15 * WARNING!
16 *
17 * This API is highly experimental. There is zero guarantees of stability
18 * between releases.
19 *
20 * You have been warned.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #include <urcu/compiler.h>
27
28 enum cmm_annotate {
29 CMM_ANNOTATE_VOID,
30 CMM_ANNOTATE_LOAD,
31 CMM_ANNOTATE_STORE,
32 CMM_ANNOTATE_MB,
33 };
34
35 typedef enum cmm_annotate cmm_annotate_t __attribute__((unused));
36
37 #define cmm_annotate_define(name) \
38 cmm_annotate_t name = CMM_ANNOTATE_VOID
39
40 #ifdef CMM_SANITIZE_THREAD
41
42 # ifdef __cplusplus
43 extern "C" {
44 # endif
45 extern void __tsan_acquire(void *);
46 extern void __tsan_release(void *);
47 # ifdef __cplusplus
48 }
49 # endif
50
51 # define cmm_annotate_die(msg) \
52 do { \
53 fprintf(stderr, \
54 "(" __FILE__ ":%s@%u) Annotation ERROR: %s\n", \
55 __func__, __LINE__, msg); \
56 abort(); \
57 } while (0)
58
59 /* Only used for typechecking in macros. */
60 static inline cmm_annotate_t cmm_annotate_dereference(cmm_annotate_t *group)
61 {
62 return *group;
63 }
64
65 # define cmm_annotate_group_mb_acquire(group) \
66 do { \
67 switch (cmm_annotate_dereference(group)) { \
68 case CMM_ANNOTATE_VOID: \
69 break; \
70 case CMM_ANNOTATE_LOAD: \
71 break; \
72 case CMM_ANNOTATE_STORE: \
73 cmm_annotate_die("store for acquire group"); \
74 break; \
75 case CMM_ANNOTATE_MB: \
76 cmm_annotate_die( \
77 "redundant mb for acquire group" \
78 ); \
79 break; \
80 } \
81 *(group) = CMM_ANNOTATE_MB; \
82 } while (0)
83
84 # define cmm_annotate_group_mb_release(group) \
85 do { \
86 switch (cmm_annotate_dereference(group)) { \
87 case CMM_ANNOTATE_VOID: \
88 break; \
89 case CMM_ANNOTATE_LOAD: \
90 cmm_annotate_die("load before release group"); \
91 break; \
92 case CMM_ANNOTATE_STORE: \
93 cmm_annotate_die( \
94 "store before release group" \
95 ); \
96 break; \
97 case CMM_ANNOTATE_MB: \
98 cmm_annotate_die( \
99 "redundant mb of release group" \
100 ); \
101 break; \
102 } \
103 *(group) = CMM_ANNOTATE_MB; \
104 } while (0)
105
106 # define cmm_annotate_group_mem_acquire(group, mem) \
107 do { \
108 __tsan_acquire((void*)(mem)); \
109 switch (cmm_annotate_dereference(group)) { \
110 case CMM_ANNOTATE_VOID: \
111 *(group) = CMM_ANNOTATE_LOAD; \
112 break; \
113 case CMM_ANNOTATE_MB: \
114 cmm_annotate_die( \
115 "load after mb for acquire group" \
116 ); \
117 break; \
118 default: \
119 break; \
120 } \
121 } while (0)
122
123 # define cmm_annotate_group_mem_release(group, mem) \
124 do { \
125 __tsan_release((void*)(mem)); \
126 switch (cmm_annotate_dereference(group)) { \
127 case CMM_ANNOTATE_MB: \
128 break; \
129 default: \
130 cmm_annotate_die( \
131 "missing mb for release group" \
132 ); \
133 } \
134 } while (0)
135
136 # define cmm_annotate_mem_acquire(mem) \
137 __tsan_acquire((void*)(mem))
138
139 # define cmm_annotate_mem_release(mem) \
140 __tsan_release((void*)(mem))
141 #else
142
143 # define cmm_annotate_group_mb_acquire(group) \
144 (void) (group)
145
146 # define cmm_annotate_group_mb_release(group) \
147 (void) (group)
148
149 # define cmm_annotate_group_mem_acquire(group, mem) \
150 (void) (group)
151
152 # define cmm_annotate_group_mem_release(group, mem) \
153 (void) (group)
154
155 # define cmm_annotate_mem_acquire(mem) \
156 do { } while (0)
157
158 # define cmm_annotate_mem_release(mem) \
159 do { } while (0)
160
161 #endif /* CMM_SANITIZE_THREAD */
162
163 #endif /* _URCU_ANNOTATE_H */
This page took 0.031263 seconds and 4 git commands to generate.