Hi, On Mon, 2019-10-21 at 20:00 +0200, Mark Wielaard wrote: > I think we cannot use the atomic_load () function, but have to use > atomic_load_explicit. So it would become: > > diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c > index fc573cb3..a2e94436 100644 > --- a/libdw/dwarf_end.c > +++ b/libdw/dwarf_end.c > @@ -95,7 +95,10 @@ dwarf_end (Dwarf *dwarf) > tdestroy (dwarf->split_tree, noop_free); > > /* Free the internally allocated memory. */ > - struct libdw_memblock *memp = (struct libdw_memblock *)dwarf->mem_tail; > + struct libdw_memblock *memp; > + memp = (struct libdw_memblock *) (atomic_load_explicit > + (&dwarf->mem_tail, > + memory_order_relaxed)); > while (memp != NULL) > { > struct libdw_memblock *prevp = memp->prev;
I made two more small changes to add error checking for pthread_key_create and pthread_setspecific, even though I couldn't trigger any of them to fail in this code, it seemed bad to just ignore if they would fail: diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index f865f69c..8d137414 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -418,7 +418,12 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) actual allocation. */ result->mem_default_size = mem_default_size; result->oom_handler = __libdw_oom; - pthread_key_create (&result->mem_key, NULL); + if (pthread_key_create (&result->mem_key, NULL) != 0) + { + free (result); + __libdw_seterrno (DWARF_E_NOMEM); /* no memory or max pthread keys. */ + return NULL; + } atomic_init (&result->mem_tail, (uintptr_t)NULL); if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR) diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c index 78977e54..f2e74d18 100644 --- a/libdw/libdw_alloc.c +++ b/libdw/libdw_alloc.c @@ -54,7 +54,8 @@ __libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) newp->prev = (struct libdw_memblock*)atomic_exchange_explicit( &dbg->mem_tail, (uintptr_t)newp, memory_order_relaxed); - pthread_setspecific(dbg->mem_key, newp); + if (pthread_setspecific (dbg->mem_key, newp) != 0) + dbg->oom_handler (); return (void *) result; } With that I pushed it to master. Thanks a lot for this code. To my surprise the code was actually slightly (although almost in the noise) faster in the single threaded cases I tested. Well done! Cheers, Mark