This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Fwd: local equivalent for pthread_once() in glibc?
- From: Florian Weimer <fweimer at redhat dot com>
- To: Chris Aoki <christopher dot aoki at oracle dot com>, libc-alpha at sourceware dot org
- Date: Wed, 26 Apr 2017 10:35:35 +0200
- Subject: Re: Fwd: local equivalent for pthread_once() in glibc?
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=fweimer at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 97811D400A
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 97811D400A
- References: <9EBFE06E-AF1D-48E9-85AB-B74C048438B1@oracle.com> <F050C948-50BF-4305-84AC-9003F97D9F59@oracle.com>
On 04/25/2017 11:19 PM, Chris Aoki wrote:
p.s. The secondary question, which is specific to glibc malloc, is
whether ptmalloc_init() can be called concurrently by multiple threads.
No, but the reason is really subtle: pthread_create calls calloc before
creating the new thread. :)
#0 ptmalloc_init () at arena.c:255
#1 0x00007ffff787a7ad in ptmalloc_init () at malloc.c:2935
#2 malloc_hook_ini (sz=272, caller=<optimized out>) at hooks.c:31
#3 0x00007ffff7879d8a in __libc_calloc (n=<optimized out>,
elem_size=<optimized out>) at malloc.c:3234
#4 0x00007ffff7deac2b in allocate_dtv (result=0x7ffff77f2700) at
dl-tls.c:322
#5 __GI__dl_allocate_tls (mem=mem@entry=0x7ffff77f2700) at dl-tls.c:539
#6 0x00007ffff7bc128a in allocate_stack (stack=<synthetic pointer>,
pdp=<synthetic pointer>, attr=0x7fffffffe520) at allocatestack.c:586
#7 __pthread_create_2_1 (newthread=0x7fffffffe5a8, attr=0x0,
start_routine=0x4005c6 <f>, arg=0x0) at pthread_create.c:539
I have a structure that is frequently accessed after initialization
so putting a lock around initialization and a check for initialization
would add considerable overhead. Normally one would use pthread_once()
in this situation, but my colleagues tell me that adding a reference to an
external function is prohibited within libc.so. I see a macro __libc_once()
but it does not appear to synchronize:
/* Define once control variable. */
#define __libc_once_define(CLASS, NAME) CLASS int NAME = 0
/* Call handler iff the first call. */
#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
do { \
if ((ONCE_CONTROL) == 0) { \
INIT_FUNCTION (); \
(ONCE_CONTROL) = 1; \
} \
} while (0)
Any clues appreciated. Thanks
There is an override for the generic definition in
sysdeps/nptl/libc-lockP.h, which is used on Linux. In general, you have
to examine the source tree carefully to discover such overrides.
Thanks,
Florian