urcu/annotate: Add CMM annotation
[urcu.git] / include / urcu / annotate.h
CommitLineData
601922a8
OD
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
39enum cmm_annotate {
40 CMM_ANNOTATE_VOID,
41 CMM_ANNOTATE_LOAD,
42 CMM_ANNOTATE_STORE,
43 CMM_ANNOTATE_MB,
44};
45
46typedef 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
54extern "C" {
55# endif
56extern void __tsan_acquire(void *);
57extern 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. */
71static 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.028997 seconds and 4 git commands to generate.