mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
* elf/dl-tls.c (__tls_get_addr): Optimize by moving slow path in
its own function. This reduces the frame setup costs and more.
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
2008-05-11 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-tls.c (__tls_get_addr): Optimize by moving slow path in
|
||||||
|
its own function. This reduces the frame setup costs and more.
|
||||||
|
|
||||||
2008-02-11 Joseph Myers <joseph@codesourcery.com>
|
2008-02-11 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
[BZ #3406]
|
[BZ #3406]
|
||||||
|
61
elf/dl-tls.c
61
elf/dl-tls.c
@ -691,28 +691,15 @@ _dl_update_slotinfo (unsigned long int req_modid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The generic dynamic and local dynamic model cannot be used in
|
static void *
|
||||||
statically linked applications. */
|
__attribute_noinline__
|
||||||
void *
|
tls_get_addr_tail (dtv_t *dtv, struct link_map *the_map, size_t module)
|
||||||
__tls_get_addr (GET_ADDR_ARGS)
|
|
||||||
{
|
{
|
||||||
dtv_t *dtv = THREAD_DTV ();
|
|
||||||
struct link_map *the_map = NULL;
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
if (__builtin_expect (dtv[0].counter != GL(dl_tls_generation), 0))
|
|
||||||
the_map = _dl_update_slotinfo (GET_ADDR_MODULE);
|
|
||||||
|
|
||||||
retry:
|
|
||||||
p = dtv[GET_ADDR_MODULE].pointer.val;
|
|
||||||
|
|
||||||
if (__builtin_expect (p == TLS_DTV_UNALLOCATED, 0))
|
|
||||||
{
|
|
||||||
/* The allocation was deferred. Do it now. */
|
/* The allocation was deferred. Do it now. */
|
||||||
if (the_map == NULL)
|
if (the_map == NULL)
|
||||||
{
|
{
|
||||||
/* Find the link map for this module. */
|
/* Find the link map for this module. */
|
||||||
size_t idx = GET_ADDR_MODULE;
|
size_t idx = module;
|
||||||
struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
|
struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
|
||||||
|
|
||||||
while (idx >= listp->len)
|
while (idx >= listp->len)
|
||||||
@ -724,11 +711,11 @@ __tls_get_addr (GET_ADDR_ARGS)
|
|||||||
the_map = listp->slotinfo[idx].map;
|
the_map = listp->slotinfo[idx].map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
/* Make sure that, if a dlopen running in parallel forces the
|
/* Make sure that, if a dlopen running in parallel forces the
|
||||||
variable into static storage, we'll wait until the address in
|
variable into static storage, we'll wait until the address in the
|
||||||
the static TLS block is set up, and use that. If we're
|
static TLS block is set up, and use that. If we're undecided
|
||||||
undecided yet, make sure we make the decision holding the
|
yet, make sure we make the decision holding the lock as well. */
|
||||||
lock as well. */
|
|
||||||
if (__builtin_expect (the_map->l_tls_offset
|
if (__builtin_expect (the_map->l_tls_offset
|
||||||
!= FORCED_DYNAMIC_TLS_OFFSET, 0))
|
!= FORCED_DYNAMIC_TLS_OFFSET, 0))
|
||||||
{
|
{
|
||||||
@ -743,12 +730,38 @@ __tls_get_addr (GET_ADDR_ARGS)
|
|||||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
if (__builtin_expect (the_map->l_tls_offset
|
if (__builtin_expect (the_map->l_tls_offset
|
||||||
!= FORCED_DYNAMIC_TLS_OFFSET, 1))
|
!= FORCED_DYNAMIC_TLS_OFFSET, 1))
|
||||||
goto retry;
|
{
|
||||||
|
void *p = dtv[module].pointer.val;
|
||||||
|
if (__builtin_expect (p == TLS_DTV_UNALLOCATED, 0))
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p = dtv[GET_ADDR_MODULE].pointer.val = allocate_and_init (the_map);
|
|
||||||
dtv[GET_ADDR_MODULE].pointer.is_static = false;
|
|
||||||
}
|
}
|
||||||
|
void *p = dtv[module].pointer.val = allocate_and_init (the_map);
|
||||||
|
dtv[module].pointer.is_static = false;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The generic dynamic and local dynamic model cannot be used in
|
||||||
|
statically linked applications. */
|
||||||
|
void *
|
||||||
|
__tls_get_addr (GET_ADDR_ARGS)
|
||||||
|
{
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
struct link_map *the_map = NULL;
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (__builtin_expect (dtv[0].counter != GL(dl_tls_generation), 0))
|
||||||
|
the_map = _dl_update_slotinfo (GET_ADDR_MODULE);
|
||||||
|
|
||||||
|
p = dtv[GET_ADDR_MODULE].pointer.val;
|
||||||
|
|
||||||
|
if (__builtin_expect (p == TLS_DTV_UNALLOCATED, 0))
|
||||||
|
p = tls_get_addr_tail (dtv, the_map, GET_ADDR_MODULE);
|
||||||
|
|
||||||
return (char *) p + GET_ADDR_OFFSET;
|
return (char *) p + GET_ADDR_OFFSET;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user