Hi Mark, On Thu, Sep 4, 2025 at 10:40 AM Mark Wielaard <m...@klomp.org> wrote: > > Hi Aaron, > > On Mon, 2025-09-01 at 20:31 -0400, Aaron Merey wrote: > > __libdw_dieabbrev uses the abbrev_lock rwlock to synchronize access to the > > Dwarf_Die abbrev field as well as its lazy loading. Calls to rwlock_wrlock > > and unlock incur significant performance overhead even in single-threaded > > cases. > > > > This patch implements thread safety in __libdw_dieabbrev with GCC __atomic > > builtins instead of an rwlock, improving performance. > > configure checks for C11 plus atomics support. So you should be able to > just use #include <stdatomic.h> and atomic_compare_exchange* functions.
My understanding is that stdatomic.h atomic_* functions are only compatible with values that are declared _Atomic, while the __atomic builtins can be used with non-atomic types. Since we can't change the declaration of Dwarf_Die.abbrev without breaking compatibility, we have to stick with __atomic builtins. > > > abbrev_lock has been > > changed to a mutex and now synchronizes access to the Dwarf_CU field > > last_abbrev_offset in __libdw_findabbrev. > > > > libdw/ > > * dwarf_begin_elf.c (valid_p): Change type of abbrev_lock from > > rwlock to mutex. > > * dwarf_end.c (cu_free): Ditto. > > * dwarf_tag.c (__libdw_findabbrev): Protect > > cu->last_abbrev_offset with mutex. > > * libdwP.h (struct Dwarf_CU): Change type of abbrev_lock from > > rwlock to mutex. > > (__libdw_dieabbrev): Use __atomic builtins instead of rwlock. > > * libdw_findcu.c (__libdw_intern_next_unit): Change type of > > abbrev_lock from rwlock to mutex. > > Apart from using stdatomic.h and the standard C11 functions I think > this is all correct. > > > One issue we need to address by the time we remove the "experimental" > > notice from --enable-thread-safety is communicating to the library > > caller that they should not attempt to read Dwarf_Die.abbrev before > > it is loaded. Since the Dwarf_Die struct is public and transparent to > > library callers, one thread attempting to read the abbrev field while > > another thread lazy loads the abbrev is undefined behavior. > > > > I don't think we can fully eliminate the possibility of UB under a lazy > > loading design given that we should not change the Dwarf_Die layout and > > its public accessibility. Lazy loading implementation cannot prevent > > library callers from reading partially written abbrev bytes no matter > > what internal synchronization methods are used. > > Maybe we just have to say that you cannot share Dwarf_Die references > between threads? So if you want to use a Dwarf_Die from another thread > you have to copy it instead by passing it by reference? It is a fairly > small struct so passing a copy instead of a reference shouldn't be a > very high overhead. Or maybe we should say that you should pass the > Dwarf and Dwarf_Die.addr to another thread and reconstruct it using > dwarf_die_addr_die? That would simplify things a bit on the > implementation side I think. But might make parallel algorithm using > libdw more awkward? Ok will add this to the relevant man pages before --enable-thread-safety is officially supported. Aaron