mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 10:22:41 +08:00
* elf/dl-close.c (_dl_close_worker): Remove all to be removed
libraries from the global scope at once and call THREAD_GSCOPE_WAIT at most once per _dl_close_worker.
This commit is contained in:
parent
755db8c5bd
commit
e8b6b64d3c
@ -1,3 +1,9 @@
|
|||||||
|
2007-06-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* elf/dl-close.c (_dl_close_worker): Remove all to be removed
|
||||||
|
libraries from the global scope at once and call THREAD_GSCOPE_WAIT
|
||||||
|
at most once per _dl_close_worker.
|
||||||
|
|
||||||
2007-06-08 Ulrich Drepper <drepper@redhat.com>
|
2007-06-08 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/bits/sched.h: Make second parameter of
|
* sysdeps/unix/sysv/linux/bits/sched.h: Make second parameter of
|
||||||
|
@ -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;
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@ -293,6 +294,9 @@ _dl_close_worker (struct link_map *map)
|
|||||||
/* We indeed have an object to remove. */
|
/* We indeed have an object to remove. */
|
||||||
unload_any = true;
|
unload_any = true;
|
||||||
|
|
||||||
|
if (imap->l_global)
|
||||||
|
++unload_global;
|
||||||
|
|
||||||
/* Remember where the first dynamically loaded object is. */
|
/* Remember where the first dynamically loaded object is. */
|
||||||
if (i < first_loaded)
|
if (i < first_loaded)
|
||||||
first_loaded = i;
|
first_loaded = i;
|
||||||
@ -458,6 +462,34 @@ _dl_close_worker (struct link_map *map)
|
|||||||
r->r_state = RT_DELETE;
|
r->r_state = RT_DELETE;
|
||||||
_dl_debug_state ();
|
_dl_debug_state ();
|
||||||
|
|
||||||
|
if (unload_global)
|
||||||
|
{
|
||||||
|
/* Some objects are in the global scope list. Remove them. */
|
||||||
|
struct r_scope_elem *ns_msl = ns->_ns_main_searchlist;
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int j = 0;
|
||||||
|
unsigned int cnt = ns_msl->r_nlist;
|
||||||
|
|
||||||
|
while (cnt > 0 && ns_msl->r_list[cnt - 1]->l_removed)
|
||||||
|
--cnt;
|
||||||
|
|
||||||
|
if (cnt + unload_global == ns_msl->r_nlist)
|
||||||
|
/* Speed up removing most recently added objects. */
|
||||||
|
j = cnt;
|
||||||
|
else
|
||||||
|
for (i = 0; i < cnt; i++)
|
||||||
|
if (ns_msl->r_list[i]->l_removed == 0)
|
||||||
|
{
|
||||||
|
if (i != j)
|
||||||
|
ns_msl->r_list[j] = ns_msl->r_list[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
ns_msl->r_nlist = j;
|
||||||
|
|
||||||
|
if (!RTLD_SINGLE_THREAD_P)
|
||||||
|
THREAD_GSCOPE_WAIT ();
|
||||||
|
}
|
||||||
|
|
||||||
size_t tls_free_start;
|
size_t tls_free_start;
|
||||||
size_t tls_free_end;
|
size_t tls_free_end;
|
||||||
tls_free_start = tls_free_end = NO_TLS_OFFSET;
|
tls_free_start = tls_free_end = NO_TLS_OFFSET;
|
||||||
@ -473,25 +505,6 @@ _dl_close_worker (struct link_map *map)
|
|||||||
|
|
||||||
/* That was the last reference, and this was a dlopen-loaded
|
/* That was the last reference, and this was a dlopen-loaded
|
||||||
object. We can unmap it. */
|
object. We can unmap it. */
|
||||||
if (__builtin_expect (imap->l_global, 0))
|
|
||||||
{
|
|
||||||
/* This object is in the global scope list. Remove it. */
|
|
||||||
struct r_scope_elem *ns_msl = ns->_ns_main_searchlist;
|
|
||||||
unsigned int cnt = ns_msl->r_nlist;
|
|
||||||
|
|
||||||
do
|
|
||||||
--cnt;
|
|
||||||
while (ns_msl->r_list[cnt] != imap);
|
|
||||||
|
|
||||||
/* The object was already correctly registered. */
|
|
||||||
while (++cnt < ns_msl->r_nlist)
|
|
||||||
ns_msl->r_list[cnt - 1] = ns_msl->r_list[cnt];
|
|
||||||
|
|
||||||
--ns_msl->r_nlist;
|
|
||||||
|
|
||||||
if (!RTLD_SINGLE_THREAD_P)
|
|
||||||
THREAD_GSCOPE_WAIT ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the object from the dtv slotinfo array if it uses TLS. */
|
/* Remove the object from the dtv slotinfo array if it uses TLS. */
|
||||||
if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
|
if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
|
||||||
|
Loading…
Reference in New Issue
Block a user