diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-05-11 18:27:20 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-05-11 18:27:20 +0000 |
commit | d65ef3dda3431ac8c5545de4305b9da0716bbb71 (patch) | |
tree | ee74f980236cb1e5a91cd587ad2bbd665723dcf0 /elf/dl-open.c | |
parent | 341c566f05fa6b19b88508f7ddd835bfd101731b (diff) | |
download | glibc-d65ef3dda3431ac8c5545de4305b9da0716bbb71.tar glibc-d65ef3dda3431ac8c5545de4305b9da0716bbb71.tar.gz glibc-d65ef3dda3431ac8c5545de4305b9da0716bbb71.tar.bz2 glibc-d65ef3dda3431ac8c5545de4305b9da0716bbb71.zip |
* elf/dl-open.c (add_to_global): Introduce variable ns to help gcc
optimize. Complerely extend global scope array before making the
new entries visible.
Diffstat (limited to 'elf/dl-open.c')
-rw-r--r-- | elf/dl-open.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/elf/dl-open.c b/elf/dl-open.c index 259372178b..0df62ff51e 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -1,5 +1,5 @@ /* Load a shared object at runtime, relocate it, and run its initializer. - Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1996-2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -97,17 +97,17 @@ add_to_global (struct link_map *new) in an realloc() call. Therefore we allocate a completely new array the first time we have to add something to the locale scope. */ - if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0) + struct link_namespaces *ns = &GL(dl_ns)[new->l_ns]; + if (ns->_ns_global_scope_alloc == 0) { /* This is the first dynamic object given global scope. */ - GL(dl_ns)[new->l_ns]._ns_global_scope_alloc - = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8; + ns->_ns_global_scope_alloc + = ns->_ns_main_searchlist->r_nlist + to_add + 8; new_global = (struct link_map **) - malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc - * sizeof (struct link_map *)); + malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *)); if (new_global == NULL) { - GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0; + ns->_ns_global_scope_alloc = 0; nomem: _dl_signal_error (ENOMEM, new->l_libname->name, NULL, N_("cannot extend global scope")); @@ -115,29 +115,29 @@ add_to_global (struct link_map *new) } /* Copy over the old entries. */ - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list - = memcpy (new_global, - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list, - (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + ns->_ns_main_searchlist->r_list + = memcpy (new_global, ns->_ns_main_searchlist->r_list, + (ns->_ns_main_searchlist->r_nlist * sizeof (struct link_map *))); } - else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add - > GL(dl_ns)[new->l_ns]._ns_global_scope_alloc) + else if (ns->_ns_main_searchlist->r_nlist + to_add + > ns->_ns_global_scope_alloc) { /* We have to extend the existing array of link maps in the main map. */ new_global = (struct link_map **) - realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list, - ((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8) + realloc (ns->_ns_main_searchlist->r_list, + ((ns->_ns_global_scope_alloc + to_add + 8) * sizeof (struct link_map *))); if (new_global == NULL) goto nomem; - GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8; - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global; + ns->_ns_global_scope_alloc += to_add + 8; + ns->_ns_main_searchlist->r_list = new_global; } /* Now add the new entries. */ + unsigned int added = 0; for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) { struct link_map *map = new->l_searchlist.r_list[cnt]; @@ -145,11 +145,14 @@ add_to_global (struct link_map *new) if (map->l_global == 0) { map->l_global = 1; - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist] + ns->_ns_main_searchlist->r_list[ns->_ns_main_searchlist->r_nlist + + added] = map; - ++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist; + ++added; } } + atomic_write_barrier (); + ns->_ns_main_searchlist->r_nlist += added; return 0; } |