X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=include%2Furcu%2Fannotate.h;fp=include%2Furcu%2Fannotate.h;h=37e7f0353fa77425bc3364de1ce396d8281eca90;hp=0000000000000000000000000000000000000000;hb=601922a81d884e16ff404cee7534ede56fb87d0a;hpb=fcab075f67cf3e29e8556b4af1bbbfb210977ac2 diff --git a/include/urcu/annotate.h b/include/urcu/annotate.h new file mode 100644 index 0000000..37e7f03 --- /dev/null +++ b/include/urcu/annotate.h @@ -0,0 +1,174 @@ +/* + * urcu/annotate.h + * + * Userspace RCU - annotation header. + * + * Copyright 2023 - Olivier Dion + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * WARNING! + * + * This API is highly experimental. There is zero guarantees of stability + * between releases. + * + * You have been warned. + */ +#ifndef _URCU_ANNOTATE_H +#define _URCU_ANNOTATE_H + +#include +#include + +#include + +enum cmm_annotate { + CMM_ANNOTATE_VOID, + CMM_ANNOTATE_LOAD, + CMM_ANNOTATE_STORE, + CMM_ANNOTATE_MB, +}; + +typedef enum cmm_annotate cmm_annotate_t __attribute__((unused)); + +#define cmm_annotate_define(name) \ + cmm_annotate_t name = CMM_ANNOTATE_VOID + +#ifdef CMM_SANITIZE_THREAD + +# ifdef __cplusplus +extern "C" { +# endif +extern void __tsan_acquire(void *); +extern void __tsan_release(void *); +# ifdef __cplusplus +} +# endif + +# define cmm_annotate_die(msg) \ + do { \ + fprintf(stderr, \ + "(" __FILE__ ":%s@%u) Annotation ERROR: %s\n", \ + __func__, __LINE__, msg); \ + abort(); \ + } while (0) + +/* Only used for typechecking in macros. */ +static inline cmm_annotate_t cmm_annotate_dereference(cmm_annotate_t *group) +{ + return *group; +} + +# define cmm_annotate_group_mb_acquire(group) \ + do { \ + switch (cmm_annotate_dereference(group)) { \ + case CMM_ANNOTATE_VOID: \ + break; \ + case CMM_ANNOTATE_LOAD: \ + break; \ + case CMM_ANNOTATE_STORE: \ + cmm_annotate_die("store for acquire group"); \ + break; \ + case CMM_ANNOTATE_MB: \ + cmm_annotate_die( \ + "redundant mb for acquire group" \ + ); \ + break; \ + } \ + *(group) = CMM_ANNOTATE_MB; \ + } while (0) + +# define cmm_annotate_group_mb_release(group) \ + do { \ + switch (cmm_annotate_dereference(group)) { \ + case CMM_ANNOTATE_VOID: \ + break; \ + case CMM_ANNOTATE_LOAD: \ + cmm_annotate_die("load before release group"); \ + break; \ + case CMM_ANNOTATE_STORE: \ + cmm_annotate_die( \ + "store before release group" \ + ); \ + break; \ + case CMM_ANNOTATE_MB: \ + cmm_annotate_die( \ + "redundant mb of release group" \ + ); \ + break; \ + } \ + *(group) = CMM_ANNOTATE_MB; \ + } while (0) + +# define cmm_annotate_group_mem_acquire(group, mem) \ + do { \ + __tsan_acquire((void*)(mem)); \ + switch (cmm_annotate_dereference(group)) { \ + case CMM_ANNOTATE_VOID: \ + *(group) = CMM_ANNOTATE_LOAD; \ + break; \ + case CMM_ANNOTATE_MB: \ + cmm_annotate_die( \ + "load after mb for acquire group" \ + ); \ + break; \ + default: \ + break; \ + } \ + } while (0) + +# define cmm_annotate_group_mem_release(group, mem) \ + do { \ + __tsan_release((void*)(mem)); \ + switch (cmm_annotate_dereference(group)) { \ + case CMM_ANNOTATE_MB: \ + break; \ + default: \ + cmm_annotate_die( \ + "missing mb for release group" \ + ); \ + } \ + } while (0) + +# define cmm_annotate_mem_acquire(mem) \ + __tsan_acquire((void*)(mem)) + +# define cmm_annotate_mem_release(mem) \ + __tsan_release((void*)(mem)) +#else + +# define cmm_annotate_group_mb_acquire(group) \ + (void) (group) + +# define cmm_annotate_group_mb_release(group) \ + (void) (group) + +# define cmm_annotate_group_mem_acquire(group, mem) \ + (void) (group) + +# define cmm_annotate_group_mem_release(group, mem) \ + (void) (group) + +# define cmm_annotate_mem_acquire(mem) \ + do { } while (0) + +# define cmm_annotate_mem_release(mem) \ + do { } while (0) + +#endif /* CMM_SANITIZE_THREAD */ + +#endif /* _URCU_ANNOTATE_H */