37e7f0353fa77425bc3364de1ce396d8281eca90
[urcu.git] / include / urcu / annotate.h
1 /*
2 * urcu/annotate.h
3 *
4 * Userspace RCU - annotation header.
5 *
6 * Copyright 2023 - Olivier Dion <odion@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /*
24 * WARNING!
25 *
26 * This API is highly experimental. There is zero guarantees of stability
27 * between releases.
28 *
29 * You have been warned.
30 */
31 #ifndef _URCU_ANNOTATE_H
32 #define _URCU_ANNOTATE_H
33
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #include <urcu/compiler.h>
38
39 enum cmm_annotate {
40 CMM_ANNOTATE_VOID,
41 CMM_ANNOTATE_LOAD,
42 CMM_ANNOTATE_STORE,
43 CMM_ANNOTATE_MB,
44 };
45
46 typedef enum cmm_annotate cmm_annotate_t __attribute__((unused));
47
48 #define cmm_annotate_define(name) \
49 cmm_annotate_t name = CMM_ANNOTATE_VOID
50
51 #ifdef CMM_SANITIZE_THREAD
52
53 # ifdef __cplusplus
54 extern "C" {
55 # endif
56 extern void __tsan_acquire(void *);
57 extern void __tsan_release(void *);
58 # ifdef __cplusplus
59 }
60 # endif
61
62 # define cmm_annotate_die(msg) \
63 do { \
64 fprintf(stderr, \
65 "(" __FILE__ ":%s@%u) Annotation ERROR: %s\n", \
66 __func__, __LINE__, msg); \
67 abort(); \
68 } while (0)
69
70 /* Only used for typechecking in macros. */
71 static inline cmm_annotate_t cmm_annotate_dereference(cmm_annotate_t *group)
72 {
73 return *group;
74 }
75
76 # define cmm_annotate_group_mb_acquire(group) \
77 do { \
78 switch (cmm_annotate_dereference(group)) { \
79 case CMM_ANNOTATE_VOID: \
80 break; \
81 case CMM_ANNOTATE_LOAD: \
82 break; \
83 case CMM_ANNOTATE_STORE: \
84 cmm_annotate_die("store for acquire group"); \
85 break; \
86 case CMM_ANNOTATE_MB: \
87 cmm_annotate_die( \
88 "redundant mb for acquire group" \
89 ); \
90 break; \
91 } \
92 *(group) = CMM_ANNOTATE_MB; \
93 } while (0)
94
95 # define cmm_annotate_group_mb_release(group) \
96 do { \
97 switch (cmm_annotate_dereference(group)) { \
98 case CMM_ANNOTATE_VOID: \
99 break; \
100 case CMM_ANNOTATE_LOAD: \
101 cmm_annotate_die("load before release group"); \
102 break; \
103 case CMM_ANNOTATE_STORE: \
104 cmm_annotate_die( \
105 "store before release group" \
106 ); \
107 break; \
108 case CMM_ANNOTATE_MB: \
109 cmm_annotate_die( \
110 "redundant mb of release group" \
111 ); \
112 break; \
113 } \
114 *(group) = CMM_ANNOTATE_MB; \
115 } while (0)
116
117 # define cmm_annotate_group_mem_acquire(group, mem) \
118 do { \
119 __tsan_acquire((void*)(mem)); \
120 switch (cmm_annotate_dereference(group)) { \
121 case CMM_ANNOTATE_VOID: \
122 *(group) = CMM_ANNOTATE_LOAD; \
123 break; \
124 case CMM_ANNOTATE_MB: \
125 cmm_annotate_die( \
126 "load after mb for acquire group" \
127 ); \
128 break; \
129 default: \
130 break; \
131 } \
132 } while (0)
133
134 # define cmm_annotate_group_mem_release(group, mem) \
135 do { \
136 __tsan_release((void*)(mem)); \
137 switch (cmm_annotate_dereference(group)) { \
138 case CMM_ANNOTATE_MB: \
139 break; \
140 default: \
141 cmm_annotate_die( \
142 "missing mb for release group" \
143 ); \
144 } \
145 } while (0)
146
147 # define cmm_annotate_mem_acquire(mem) \
148 __tsan_acquire((void*)(mem))
149
150 # define cmm_annotate_mem_release(mem) \
151 __tsan_release((void*)(mem))
152 #else
153
154 # define cmm_annotate_group_mb_acquire(group) \
155 (void) (group)
156
157 # define cmm_annotate_group_mb_release(group) \
158 (void) (group)
159
160 # define cmm_annotate_group_mem_acquire(group, mem) \
161 (void) (group)
162
163 # define cmm_annotate_group_mem_release(group, mem) \
164 (void) (group)
165
166 # define cmm_annotate_mem_acquire(mem) \
167 do { } while (0)
168
169 # define cmm_annotate_mem_release(mem) \
170 do { } while (0)
171
172 #endif /* CMM_SANITIZE_THREAD */
173
174 #endif /* _URCU_ANNOTATE_H */
This page took 0.0316689999999999 seconds and 4 git commands to generate.