<div dir="ltr">>Since 0.15.0, we've introduce an annotation layer (not part of the<br>>public API), making TSAN compatible with URCU.  See<br>>`include/urcu/annotate.h' and the `CMM_SANITIZE_THREAD' macro.<br>><br>>However, IIRC, you also need to compile URCU with the configuration<br>>option `--enable-compiler-atomic-builtins' so that atomic operations are<br>>implemented with the configured toolchain's builtin atomics.  I don't<br>>recall if this was strictly necessary.<br>><br>>If you encounter false positives with TSAN, please send me a minimal<br>>reproducible example together with:<br>><br>> - the toolchain you’re using<br>><br>> - the version of URCU<br>><br>> - the configuration flags you used<br>><br>>I will be happy to have a look.<div><br></div><div>Sorry for the late answer. I had to find the time to fix some bugs to get it all running before switching to urcu v0.15.0 and setting the flags and macros for thread sanitizer support. Creating a minimum reproducible example would take some time as I don't have any good idea of the exact place where the thread sanitizer issues arise because they are scattered all over tsm.c and test_tsm.c. If you have linux debian family then you can clone my repo and run it: <a href="https://github.com/ThobiasKnudsen/Logos">https://github.com/ThobiasKnudsen/Logos</a>. ./scripts/build.sh --debug --tsan && ./build/bin/test_tsm. I tried running with and without thread sanitizer support and got the same issues. In the test_tsm when only one thread is running, the thread sanitizer produces warnings still. I did find a place where the thread sanitizer said there was a race and the write was within a node not yet inserted into the cds_lfht. That seems like a false positive. The read for the same case should be inside rcu_read_lock as everything within lines 263 to 904 inside test_tsm.c is within a read section.</div><div><br></div><div>  Read of size 1 at 0x7b1400085ea1 by thread T6:<br>    #0 tsm_base_node_is_valid /Logos/src/tsm.c:721 (test_tsm+0xa548)<br>    #1 _tsm_tsm_type_is_valid /Logos/src/tsm.c:364 (test_tsm+0xb1bf)<br>    #2 tsm_node_is_valid /Logos/src/tsm.c:1553 (test_tsm+0x9984)<br>    #3 tsm_node_defer_free /Logos/src/tsm.c:1888 (test_tsm+0xb2fc)<br>    #4 stress_thread /Logos/src/tests/test_tsm.c:549 (test_tsm+0x46a6)<br><br>  Previous write of size 1 at 0x7b1400085ea1 by thread T9:<br>    #0 tsm_base_node_create /Logos/src/tsm.c:683 (test_tsm+0x6f2a)<br>    #1 stress_thread /Logos/src/tests/test_tsm.c:843 (test_tsm+0x5ce0)<br></div><div><br></div><div>>I don’t see why that would be a problem for the static-check algorithm I<br>>described above.  If a pointer needs to be protected by a mutex for<br>>mutation, that falls outside the scope of RCU, as far as I know.</div><div><br></div><div>If I understand correctly the __rcu checks that reads are not done outside read sections and unsafe writes are not done at all. If this is correct then if you are using custom concurrency for __rcu protected data outside the read section or unsafe writes is that allowed? Because if it's not that would be a limitation for __rcu. </div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">man. 8. sep. 2025 kl. 02:10 skrev Olivier Dion <<a href="mailto:odion@efficios.com">odion@efficios.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sun, 07 Sep 2025, Thobias Knudsen <<a href="mailto:thobknu@gmail.com" target="_blank">thobknu@gmail.com</a>> wrote:<br>
>> It looks like you want runtime verification for the usage of the API.<br>
>> Did you know that URCU can now be compiled against ThreadSanitizer<br>
>> (TSAN)?  If a user misuses the API or makes incorrect assumptions about<br>
>> the guarantees offered by RCU, TSAN will most likely detect those<br>
>> issues.  Coupled with the other debug features we already have, this<br>
>> makes it very hard to not trigger an error path when the API is used<br>
>> incorrectly.<br>
><br>
> Really?! I've used TSAN and got a bunch of false positives, I believe, but<br>
> maybe they're not false positives? How do you remove the false positives,<br>
> or know that they're not false positives?<br>
<br>
Since 0.15.0, we've introduce an annotation layer (not part of the<br>
public API), making TSAN compatible with URCU.  See<br>
`include/urcu/annotate.h' and the `CMM_SANITIZE_THREAD' macro.<br>
<br>
However, IIRC, you also need to compile URCU with the configuration<br>
option `--enable-compiler-atomic-builtins' so that atomic operations are<br>
implemented with the configured toolchain's builtin atomics.  I don't<br>
recall if this was stricly necessary.<br>
<br>
If you encounter false positives with TSAN, please send me a minimal<br>
reproducible example together with:<br>
<br>
 - the toolchain you’re using<br>
<br>
 - the version of URCU<br>
<br>
 - the configuration flags you used<br>
<br>
I will be happy to have a look.<br>
<br>
>> Note that certain kind of errors could actually be flag at compile time<br>
>> with the proper tooling.  For example, the Linux kernel uses a `__rcu'<br>
>> attribute that Sparse can understand to flag improper use of<br>
>> RCU‑protected pointers.  I’d be very open to exposing something similar<br>
>> (an attribute) for static checkers.<br>
><br>
> wow thanks for the info! I knew compile time checks would be possible but<br>
> requiring compiler operability which is a higher hanging fruit for me. <br>
<br>
I don’t know the details of `__rcu' from the Linux kernel. I think it’s<br>
just a macro that expands to nothing by default, but Sparse treats it as<br>
an attribute.  I’m not sure exactly what checks Sparse performs with it,<br>
but I suspect it involves traversing the program’s control-flow graph<br>
(CFG), ensuring that pointers marked with the `__rcu' qualifier are:<br>
<br>
  - obtained via rcu_dereference<br>
<br>
  - only dereferenced under RCU lock protection<br>
<br>
> Is '__rcu' compatible with custom concurrency? For example<br>
> rcu_dereference a pointer then locking a mutex inside the pointer then<br>
> unlock read then continue using the pointer?<br>
<br>
I don’t see why that would be a problem for the static-check algorithm I<br>
described above.  If a pointer needs to be protected by a mutex for<br>
mutation, that falls outside the scope of RCU, as far as I know.<br>
<br>
> I cant come up with something usefull other than a language rework. Is<br>
> it much work making the __urcu attribute?<br>
<br>
I suppose not.  On top of my head, it would involve adding some pointer<br>
qualifier and function attributes to the primitives exposed by URCU.<br>
Users would also need to use the pointer qualifier when working with<br>
RCU-protected pointers.  The qualifier and the attributes would expand<br>
to nothing by default, letting static checkers defining them to internal<br>
values.  I suggest you read `Documentation/RCU/rcu_dereference.rst' in<br>
the Linux kernel tree if you are interested.<br>
<br>
In its current state, this would not be very useful because none of the<br>
major compilers provide static analysis for RCU.  However, implementing<br>
such analysis, as a plugin, wouldn’t be overly difficult for someone<br>
familiar with Clang or GCC, I suppose.<br>
<br>
[...]<br>
<br>
Thanks,<br>
Olivier<br>
-- <br>
Olivier Dion<br>
EfficiOS Inc.<br>
<a href="https://www.efficios.com" rel="noreferrer" target="_blank">https://www.efficios.com</a><br>
</blockquote></div>