1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

* elf/dl-close.c (free_mem): Free _dl_scope_free_list.

2007-06-13  Jakub Jelinek  <jakub@redhat.com>

	* include/link.h: Don't include rtld-lowlevel.h.
	(struct link_map): Remove l_scope_lock.
	* sysdeps/generic/ldsodefs.h: Don't include rtld-lowlevel.h.
	(_dl_scope_free_list): New field (variable) in _rtld_global.
	(DL_LOOKUP_SCOPE_LOCK): Remove.
	(_dl_scope_free): New prototype.
	* elf/dl-runtime.c (_dl_fixup): Don't use __rtld_mrlock_*lock.
	Don't pass DL_LOOKUP_SCOPE_LOCK to _dl_lookup_symbol_x.
	(_dl_profile_fixup): Likewise.
	* elf/dl-sym.c (do_sym): Likewise.  Use wrapped _dl_lookup_symbol_x
	whenever !RTLD_SINGLE_THREAD_P, use THREAD_GSCOPE_SET_FLAG and
	THREAD_GSCOPE_RESET_FLAG around it.
	* elf/dl-close.c (_dl_close_worker): Don't use
	__rtld_mrlock_{change,done}.  Call _dl_scope_free on the old
	scope.  Make sure THREAD_GSCOPE_WAIT () happens if any old
	scopes were queued or if l_scope_mem has been abandoned.
	* elf/dl-open.c (_dl_scope_free): New function.
	(dl_open_worker): Use it.  Don't use __rtld_mrlock_{change,done}.
	* elf/dl-support.c (_dl_scope_free_list): New variable.
	* elf/dl-lookup.c (add_dependency): Remove flags argument.
	Remove DL_LOOKUP_SCOPE_LOCK handling.
	(_dl_lookup_symbol_x): Adjust caller.  Remove DL_LOOKUP_SCOPE_LOCK
	handling.
	* elf/dl-object.c (_dl_new_object): Don't use
	__rtld_mrlock_initialize.

2007-06-19  Ulrich Drepper  <drepper@redhat.com>
This commit is contained in:
Ulrich Drepper
2007-06-20 03:19:13 +00:00
parent 9be09e060f
commit e4eb675d0c
12 changed files with 132 additions and 193 deletions

View File

@ -1,3 +1,35 @@
2007-06-19 Ulrich Drepper <drepper@redhat.com>
* elf/dl-close.c (free_mem): Free _dl_scope_free_list.
2007-06-13 Jakub Jelinek <jakub@redhat.com>
* include/link.h: Don't include rtld-lowlevel.h.
(struct link_map): Remove l_scope_lock.
* sysdeps/generic/ldsodefs.h: Don't include rtld-lowlevel.h.
(_dl_scope_free_list): New field (variable) in _rtld_global.
(DL_LOOKUP_SCOPE_LOCK): Remove.
(_dl_scope_free): New prototype.
* elf/dl-runtime.c (_dl_fixup): Don't use __rtld_mrlock_*lock.
Don't pass DL_LOOKUP_SCOPE_LOCK to _dl_lookup_symbol_x.
(_dl_profile_fixup): Likewise.
* elf/dl-sym.c (do_sym): Likewise. Use wrapped _dl_lookup_symbol_x
whenever !RTLD_SINGLE_THREAD_P, use THREAD_GSCOPE_SET_FLAG and
THREAD_GSCOPE_RESET_FLAG around it.
* elf/dl-close.c (_dl_close_worker): Don't use
__rtld_mrlock_{change,done}. Call _dl_scope_free on the old
scope. Make sure THREAD_GSCOPE_WAIT () happens if any old
scopes were queued or if l_scope_mem has been abandoned.
* elf/dl-open.c (_dl_scope_free): New function.
(dl_open_worker): Use it. Don't use __rtld_mrlock_{change,done}.
* elf/dl-support.c (_dl_scope_free_list): New variable.
* elf/dl-lookup.c (add_dependency): Remove flags argument.
Remove DL_LOOKUP_SCOPE_LOCK handling.
(_dl_lookup_symbol_x): Adjust caller. Remove DL_LOOKUP_SCOPE_LOCK
handling.
* elf/dl-object.c (_dl_new_object): Don't use
__rtld_mrlock_initialize.
2007-06-19 Ulrich Drepper <drepper@redhat.com> 2007-06-19 Ulrich Drepper <drepper@redhat.com>
* sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements * sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements

View File

@ -229,6 +229,7 @@ _dl_close_worker (struct link_map *map)
bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing; bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
#endif #endif
bool unload_any = false; bool unload_any = false;
bool scope_mem_left = false;
unsigned int unload_global = 0; unsigned int unload_global = 0;
unsigned int first_loaded = ~0; unsigned int first_loaded = ~0;
for (unsigned int i = 0; i < nloaded; ++i) for (unsigned int i = 0; i < nloaded; ++i)
@ -405,18 +406,18 @@ _dl_close_worker (struct link_map *map)
struct r_scope_elem **old = imap->l_scope; struct r_scope_elem **old = imap->l_scope;
if (RTLD_SINGLE_THREAD_P) imap->l_scope = newp;
imap->l_scope = newp;
else
{
__rtld_mrlock_change (imap->l_scope_lock);
imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scope_lock);
}
/* No user anymore, we can free it now. */ /* No user anymore, we can free it now. */
if (old != imap->l_scope_mem) if (old != imap->l_scope_mem)
free (old); {
if (_dl_scope_free (old))
/* If _dl_scope_free used THREAD_GSCOPE_WAIT (),
no need to repeat it. */
scope_mem_left = false;
}
else
scope_mem_left = true;
imap->l_scope_max = new_size; imap->l_scope_max = new_size;
} }
@ -485,9 +486,21 @@ _dl_close_worker (struct link_map *map)
j++; j++;
} }
ns_msl->r_nlist = j; ns_msl->r_nlist = j;
}
if (!RTLD_SINGLE_THREAD_P) if (!RTLD_SINGLE_THREAD_P
THREAD_GSCOPE_WAIT (); && (unload_global
|| scope_mem_left
|| (GL(dl_scope_free_list) != NULL
&& GL(dl_scope_free_list)->count)))
{
THREAD_GSCOPE_WAIT ();
/* Now we can free any queued old scopes. */
struct dl_scope_free_list *fsl = GL(dl_scope_free_list);
if (fsl != NULL)
while (fsl->count > 0)
free (fsl->list[--fsl->count]);
} }
size_t tls_free_start; size_t tls_free_start;
@ -786,4 +799,8 @@ libc_freeres_fn (free_mem)
malloc), and in the static library it's in .bss space. */ malloc), and in the static library it's in .bss space. */
free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next); free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next);
} }
void *scope_free_list = GL(dl_scope_free_list);
GL(dl_scope_free_list) = NULL;
free (scope_free_list);
} }

View File

@ -86,7 +86,7 @@ dl_new_hash (const char *s)
/* Add extra dependency on MAP to UNDEF_MAP. */ /* Add extra dependency on MAP to UNDEF_MAP. */
static int static int
internal_function internal_function
add_dependency (struct link_map *undef_map, struct link_map *map, int flags) add_dependency (struct link_map *undef_map, struct link_map *map)
{ {
struct link_map **list; struct link_map **list;
struct link_map *runp; struct link_map *runp;
@ -99,18 +99,8 @@ add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
if (undef_map == map) if (undef_map == map)
return 0; return 0;
/* Make sure nobody can unload the object while we are at it. /* Make sure nobody can unload the object while we are at it. */
If we hold a scope lock drop it now to avoid ABBA locking problems. */ __rtld_lock_lock_recursive (GL(dl_load_lock));
if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0 && !RTLD_SINGLE_THREAD_P)
{
__rtld_mrlock_unlock (undef_map->l_scope_lock);
__rtld_lock_lock_recursive (GL(dl_load_lock));
__rtld_mrlock_lock (undef_map->l_scope_lock);
}
else
__rtld_lock_lock_recursive (GL(dl_load_lock));
/* Avoid references to objects which cannot be unloaded anyway. */ /* Avoid references to objects which cannot be unloaded anyway. */
if (map->l_type != lt_loaded if (map->l_type != lt_loaded
@ -237,10 +227,9 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
bump_num_relocations (); bump_num_relocations ();
/* No other flag than DL_LOOKUP_ADD_DEPENDENCY and DL_LOOKUP_SCOPE_LOCK /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look
is allowed if we look up a versioned symbol. */ up a versioned symbol. */
assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY)) == 0);
| DL_LOOKUP_SCOPE_LOCK)) == 0);
size_t i = 0; size_t i = 0;
if (__builtin_expect (skip_map != NULL, 0)) if (__builtin_expect (skip_map != NULL, 0))
@ -346,13 +335,11 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
runtime lookups. */ runtime lookups. */
&& (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
/* Add UNDEF_MAP to the dependencies. */ /* Add UNDEF_MAP to the dependencies. */
&& add_dependency (undef_map, current_value.m, flags) < 0) && add_dependency (undef_map, current_value.m) < 0)
/* Something went wrong. Perhaps the object we tried to reference /* Something went wrong. Perhaps the object we tried to reference
was just removed. Try finding another definition. */ was just removed. Try finding another definition. */
return _dl_lookup_symbol_x (undef_name, undef_map, ref, return _dl_lookup_symbol_x (undef_name, undef_map, ref, symbol_scope,
(flags & DL_LOOKUP_SCOPE_LOCK) == 0 version, type_class, flags, skip_map);
? symbol_scope : undef_map->l_scope, version,
type_class, flags, skip_map);
/* The object is used. */ /* The object is used. */
current_value.m->l_used = 1; current_value.m->l_used = 1;

View File

@ -1,5 +1,5 @@
/* Storage management for the chain of loaded shared objects. /* Storage management for the chain of loaded shared objects.
Copyright (C) 1995-2002, 2004, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2002, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -85,11 +85,6 @@ _dl_new_object (char *realname, const char *libname, int type,
new->l_scope = new->l_scope_mem; new->l_scope = new->l_scope_mem;
new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]); new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
/* No need to initialize the scope lock if the initializer is zero. */
#if _RTLD_MRLOCK_INITIALIZER != 0
__rtld_mrlock_initialize (new->l_scope_lock);
#endif
/* Counter for the scopes we have to handle. */ /* Counter for the scopes we have to handle. */
idx = 0; idx = 0;

View File

@ -165,6 +165,40 @@ add_to_global (struct link_map *new)
return 0; return 0;
} }
int
_dl_scope_free (struct r_scope_elem **old)
{
struct dl_scope_free_list *fsl;
#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
if (RTLD_SINGLE_THREAD_P)
free (old);
else if ((fsl = GL(dl_scope_free_list)) == NULL)
{
GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
if (fsl == NULL)
{
THREAD_GSCOPE_WAIT ();
free (old);
return 1;
}
else
{
fsl->list[0] = old;
fsl->count = 1;
}
}
else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
fsl->list[fsl->count++] = old;
else
{
THREAD_GSCOPE_WAIT ();
while (fsl->count > 0)
free (fsl->list[--fsl->count]);
return 1;
}
return 0;
}
static void static void
dl_open_worker (void *a) dl_open_worker (void *a)
@ -429,17 +463,10 @@ dl_open_worker (void *a)
memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0])); memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
struct r_scope_elem **old = imap->l_scope; struct r_scope_elem **old = imap->l_scope;
if (RTLD_SINGLE_THREAD_P) imap->l_scope = newp;
imap->l_scope = newp;
else
{
__rtld_mrlock_change (imap->l_scope_lock);
imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scope_lock);
}
if (old != imap->l_scope_mem) if (old != imap->l_scope_mem)
free (old); _dl_scope_free (old);
imap->l_scope_max = new_size; imap->l_scope_max = new_size;
} }

View File

@ -100,22 +100,11 @@ _dl_fixup (
we are not using any threads (yet). */ we are not using any threads (yet). */
int flags = DL_LOOKUP_ADD_DEPENDENCY; int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (!RTLD_SINGLE_THREAD_P) if (!RTLD_SINGLE_THREAD_P)
{ THREAD_GSCOPE_SET_FLAG ();
THREAD_GSCOPE_SET_FLAG ();
if (l->l_type == lt_loaded)
{
__rtld_mrlock_lock (l->l_scope_lock);
flags |= DL_LOOKUP_SCOPE_LOCK;
}
}
result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope, result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
version, ELF_RTYPE_CLASS_PLT, flags, NULL); version, ELF_RTYPE_CLASS_PLT, flags, NULL);
if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0)
__rtld_mrlock_unlock (l->l_scope_lock);
/* We are done with the global scope. */ /* We are done with the global scope. */
if (!RTLD_SINGLE_THREAD_P) if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_RESET_FLAG (); THREAD_GSCOPE_RESET_FLAG ();
@ -203,23 +192,12 @@ _dl_profile_fixup (
we are not using any threads (yet). */ we are not using any threads (yet). */
int flags = DL_LOOKUP_ADD_DEPENDENCY; int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (!RTLD_SINGLE_THREAD_P) if (!RTLD_SINGLE_THREAD_P)
{ THREAD_GSCOPE_SET_FLAG ();
THREAD_GSCOPE_SET_FLAG ();
if (l->l_type == lt_loaded)
{
__rtld_mrlock_lock (l->l_scope_lock);
flags |= DL_LOOKUP_SCOPE_LOCK;
}
}
result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, result = _dl_lookup_symbol_x (strtab + refsym->st_name, l,
&defsym, l->l_scope, version, &defsym, l->l_scope, version,
ELF_RTYPE_CLASS_PLT, flags, NULL); ELF_RTYPE_CLASS_PLT, flags, NULL);
if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0)
__rtld_mrlock_unlock (l->l_scope_lock);
/* We are done with the global scope. */ /* We are done with the global scope. */
if (!RTLD_SINGLE_THREAD_P) if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_RESET_FLAG (); THREAD_GSCOPE_RESET_FLAG ();

View File

@ -135,6 +135,8 @@ int (*_dl_make_stack_executable_hook) (void **) internal_function
/* Function in libpthread to wait for termination of lookups. */ /* Function in libpthread to wait for termination of lookups. */
void (*_dl_wait_lookup_done) (void); void (*_dl_wait_lookup_done) (void);
struct dl_scope_free_list *_dl_scope_free_list;
#ifdef NEED_DL_SYSINFO #ifdef NEED_DL_SYSINFO
/* Needed for improved syscall handling on at least x86/Linux. */ /* Needed for improved syscall handling on at least x86/Linux. */
uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT; uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;

View File

@ -112,29 +112,29 @@ do_sym (void *handle, const char *name, void *who,
the initial binary. And then the more complex part the initial binary. And then the more complex part
where the object is dynamically loaded and the scope where the object is dynamically loaded and the scope
array can change. */ array can change. */
if (match->l_type != lt_loaded || RTLD_SINGLE_THREAD_P) if (RTLD_SINGLE_THREAD_P)
result = GLRO(dl_lookup_symbol_x) (name, match, &ref, result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
match->l_scope, vers, 0, match->l_scope, vers, 0,
flags | DL_LOOKUP_ADD_DEPENDENCY, flags | DL_LOOKUP_ADD_DEPENDENCY,
NULL); NULL);
else else
{ {
__rtld_mrlock_lock (match->l_scope_lock);
struct call_dl_lookup_args args; struct call_dl_lookup_args args;
args.name = name; args.name = name;
args.map = match; args.map = match;
args.vers = vers; args.vers = vers;
args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_SCOPE_LOCK; args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
args.refp = &ref; args.refp = &ref;
THREAD_GSCOPE_SET_FLAG ();
const char *objname; const char *objname;
const char *errstring = NULL; const char *errstring = NULL;
bool malloced; bool malloced;
int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced, int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
call_dl_lookup, &args); call_dl_lookup, &args);
__rtld_mrlock_unlock (match->l_scope_lock); THREAD_GSCOPE_RESET_FLAG ();
if (__builtin_expect (errstring != NULL, 0)) if (__builtin_expect (errstring != NULL, 0))
{ {

View File

@ -44,7 +44,6 @@ extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid,
#include <dl-lookupcfg.h> #include <dl-lookupcfg.h>
#include <tls.h> #include <tls.h>
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
#include <rtld-lowlevel.h>
/* Some internal data structures of the dynamic linker used in the /* Some internal data structures of the dynamic linker used in the
@ -223,8 +222,6 @@ struct link_map
/* This is an array defining the lookup scope for this link map. /* This is an array defining the lookup scope for this link map.
There are initially at most three different scope lists. */ There are initially at most three different scope lists. */
struct r_scope_elem **l_scope; struct r_scope_elem **l_scope;
/* We need to protect using the SCOPEREC. */
__rtld_mrlock_define (, l_scope_lock)
/* A similar array, this time only with the local scope. This is /* A similar array, this time only with the local scope. This is
used occasionally. */ used occasionally. */

View File

@ -1,3 +1,8 @@
2007-06-19 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/rtld-lowlevel.h: Remove mrlock
implementation.
2007-06-18 Ulrich Drepper <drepper@redhat.com> 2007-06-18 Ulrich Drepper <drepper@redhat.com>
* pthreadP.h: Define PTHREAD_MUTEX_TYPE. * pthreadP.h: Define PTHREAD_MUTEX_TYPE.

View File

@ -24,115 +24,6 @@
#include <lowlevellock.h> #include <lowlevellock.h>
/* Special multi-reader lock used in ld.so. */
#define __RTLD_MRLOCK_WRITER 1
#define __RTLD_MRLOCK_RWAIT 2
#define __RTLD_MRLOCK_WWAIT 4
#define __RTLD_MRLOCK_RBITS \
~(__RTLD_MRLOCK_WRITER | __RTLD_MRLOCK_RWAIT | __RTLD_MRLOCK_WWAIT)
#define __RTLD_MRLOCK_INC 8
#define __RTLD_MRLOCK_TRIES 5
typedef int __rtld_mrlock_t;
#define __rtld_mrlock_define(CLASS,NAME) \
CLASS __rtld_mrlock_t NAME;
#define _RTLD_MRLOCK_INITIALIZER 0
#define __rtld_mrlock_initialize(NAME) \
(void) ((NAME) = 0)
#define __rtld_mrlock_lock(lock) \
do { \
__label__ out; \
while (1) \
{ \
int oldval; \
for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries) \
{ \
oldval = lock; \
while (__builtin_expect ((oldval \
& (__RTLD_MRLOCK_WRITER \
| __RTLD_MRLOCK_WWAIT)) \
== 0, 1)) \
{ \
int newval = ((oldval & __RTLD_MRLOCK_RBITS) \
+ __RTLD_MRLOCK_INC); \
int ret = atomic_compare_and_exchange_val_acq (&(lock), \
newval, \
oldval); \
if (__builtin_expect (ret == oldval, 1)) \
goto out; \
oldval = ret; \
} \
atomic_delay (); \
} \
if ((oldval & __RTLD_MRLOCK_RWAIT) == 0) \
{ \
atomic_or (&(lock), __RTLD_MRLOCK_RWAIT); \
oldval |= __RTLD_MRLOCK_RWAIT; \
} \
lll_private_futex_wait (lock, oldval); \
} \
out:; \
} while (0)
#define __rtld_mrlock_unlock(lock) \
do { \
int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_INC); \
if (__builtin_expect ((oldval \
& (__RTLD_MRLOCK_RBITS | __RTLD_MRLOCK_WWAIT)) \
== (__RTLD_MRLOCK_INC | __RTLD_MRLOCK_WWAIT), 0)) \
/* We have to wake all threads since there might be some queued \
readers already. */ \
lll_private_futex_wake (&(lock), 0x7fffffff); \
} while (0)
/* There can only ever be one thread trying to get the exclusive lock. */
#define __rtld_mrlock_change(lock) \
do { \
__label__ out; \
while (1) \
{ \
int oldval; \
for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries) \
{ \
oldval = lock; \
while (__builtin_expect ((oldval & __RTLD_MRLOCK_RBITS) == 0, 1)) \
{ \
int newval = ((oldval & __RTLD_MRLOCK_RWAIT) \
+ __RTLD_MRLOCK_WRITER); \
int ret = atomic_compare_and_exchange_val_acq (&(lock), \
newval, \
oldval); \
if (__builtin_expect (ret == oldval, 1)) \
goto out; \
oldval = ret; \
} \
atomic_delay (); \
} \
atomic_or (&(lock), __RTLD_MRLOCK_WWAIT); \
oldval |= __RTLD_MRLOCK_WWAIT; \
lll_private_futex_wait (lock, oldval); \
} \
out:; \
} while (0)
#define __rtld_mrlock_done(lock) \
do { \
int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_WRITER); \
if (__builtin_expect ((oldval & __RTLD_MRLOCK_RWAIT) != 0, 0)) \
lll_private_futex_wake (&(lock), 0x7fffffff); \
} while (0)
/* Function to wait for variable become zero. Used in ld.so for /* Function to wait for variable become zero. Used in ld.so for
reference counters. */ reference counters. */
#define __rtld_waitzero(word) \ #define __rtld_waitzero(word) \

View File

@ -38,7 +38,6 @@
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
#include <hp-timing.h> #include <hp-timing.h>
#include <tls.h> #include <tls.h>
#include <rtld-lowlevel.h>
__BEGIN_DECLS __BEGIN_DECLS
@ -488,6 +487,12 @@ struct rtld_global
EXTERN void (*_dl_wait_lookup_done) (void); EXTERN void (*_dl_wait_lookup_done) (void);
/* Scopes to free after next THREAD_GSCOPE_WAIT (). */
EXTERN struct dl_scope_free_list
{
size_t count;
struct r_scope_elem **list[50];
} *_dl_scope_free_list;
#ifdef SHARED #ifdef SHARED
}; };
# define __rtld_global_attribute__ # define __rtld_global_attribute__
@ -840,9 +845,7 @@ enum
DL_LOOKUP_ADD_DEPENDENCY = 1, DL_LOOKUP_ADD_DEPENDENCY = 1,
/* Return most recent version instead of default version for /* Return most recent version instead of default version for
unversioned lookup. */ unversioned lookup. */
DL_LOOKUP_RETURN_NEWEST = 2, DL_LOOKUP_RETURN_NEWEST = 2
/* Set if the scopr lock in the UNDEF_MAP is taken. */
DL_LOOKUP_SCOPE_LOCK = 4
}; };
/* Lookup versioned symbol. */ /* Lookup versioned symbol. */
@ -1050,6 +1053,11 @@ extern void *_dl_open (const char *name, int mode, const void *caller,
Lmid_t nsid, int argc, char *argv[], char *env[]) Lmid_t nsid, int argc, char *argv[], char *env[])
attribute_hidden; attribute_hidden;
/* Free or queue for freeing scope OLD. If other threads might be
in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the
old scope, OLD can't be freed until no thread is using it. */
extern int _dl_scope_free (struct r_scope_elem **old) attribute_hidden;
/* Add module to slot information data. */ /* Add module to slot information data. */
extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden; extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden;