2002-10-30 Jakub Jelinek <jakub@redhat.com>
authorroland <roland>
Fri, 1 Nov 2002 20:43:53 +0000 (20:43 +0000)
committerroland <roland>
Fri, 1 Nov 2002 20:43:53 +0000 (20:43 +0000)
* include/libc-symbols.h (__libc_freeres_fn_section, libc_freeres_fn):
New macros.
* elf/dl-close.c (free_mem): Use libc_freeres_fn macro, remove
text_set_element.
* elf/dl-libc.c (free_mem): Likewise.
* iconv/gconv_conf.c (free_mem): Likewise.
* iconv/gconv_db.c (free_mem): Likewise.
* iconv/gconv_dl.c (free_mem): Likewise.
* iconv/gconv_cache.c (free_mem): Likewise.
* intl/finddomain.c (free_mem): Likewise.
* intl/dcigettext.c (free_mem): Likewise.
* locale/setlocale.c (free_mem): Likewise.
* misc/fstab.c (fstab_free): Likewise.
* nss/nsswitch.c (free_mem): Likewise.
* posix/regcomp.c (free_mem): Likewise.
* resolv/gai_misc.c (free_res): Likewise.
* stdlib/fmtmsg.c (free_mem): Likewise.
* sunrpc/clnt_perr.c (free_mem): Likewise.
* sysdeps/generic/setenv.c (free_mem): Likewise.
* sysdeps/unix/sysv/linux/shm_open.c (freeit): Likewise.
* sysdeps/pthread/aio_misc.c (free_res): Likewise.
* time/tzset.c (free_mem): Likewise.
* malloc/mtrace.c (release_libc_mem): Add __libc_freeres_fn_section.
* locale/loadarchive.c (_nl_archive_subfreeres): Likewise.
* malloc/set-freeres.c (__libc_freeres): Likewise.

20 files changed:
elf/dl-close.c
elf/dl-libc.c
iconv/gconv_cache.c
iconv/gconv_conf.c
iconv/gconv_db.c
iconv/gconv_dl.c
intl/dcigettext.c
intl/finddomain.c
locale/loadarchive.c
locale/setlocale.c
misc/fstab.c
nss/nsswitch.c
posix/regcomp.c
resolv/gai_misc.c
stdlib/fmtmsg.c
sunrpc/clnt_perr.c
sysdeps/generic/setenv.c
sysdeps/pthread/aio_misc.c
sysdeps/unix/sysv/linux/shm_open.c
time/tzset.c

index 094db53..632f8ba 100644 (file)
@@ -247,6 +247,11 @@ _dl_close (void *_map)
   _r_debug.r_state = RT_DELETE;
   _dl_debug_state ();
 
+#ifdef USE_TLS
+  size_t tls_free_start, tls_free_end;
+  tls_free_start = tls_free_end = GL(dl_tls_static_used);
+#endif
+
   /* Check each element of the search list to see if all references to
      it are gone.  */
   for (i = 0; list[i] != NULL; ++i)
@@ -286,6 +291,30 @@ _dl_close (void *_map)
                                     imap->l_init_called))
                /* All dynamically loaded modules with TLS are unloaded.  */
                GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
+
+             if (imap->l_tls_offset != 0)
+               {
+                 /* Collect a contiguous chunk built from the objects in
+                    this search list, going in either direction.  When the
+                    whole chunk is at the end of the used area then we can
+                    reclaim it.  */
+                 if (imap->l_tls_offset == tls_free_end)
+                   /* Extend the contiguous chunk being reclaimed.  */
+                   tls_free_end += imap->l_tls_blocksize;
+                 else if (imap->l_tls_offset + imap->l_tls_blocksize
+                          == tls_free_start)
+                   /* Extend the chunk backwards.  */
+                   tls_free_start = imap->l_tls_offset;
+                 else
+                   {
+                     /* This isn't contiguous with the last chunk freed.
+                        One of them will be leaked.  */
+                     if (tls_free_end == GL(dl_tls_static_used))
+                       GL(dl_tls_static_used) = tls_free_start;
+                     tls_free_start = imap->l_tls_offset;
+                     tls_free_end = tls_free_start + imap->l_tls_blocksize;
+                   }
+               }
            }
 #endif
 
@@ -363,11 +392,15 @@ _dl_close (void *_map)
     }
 
 #ifdef USE_TLS
-  /* If we removed any object which uses TLS bumnp the generation
-     counter.  */
+  /* If we removed any object which uses TLS bump the generation counter.  */
   if (any_tls)
-    if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
-      __libc_fatal (_("TLS generation counter wrapped!  Please send report with the 'glibcbug' script."));
+    {
+      if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
+       __libc_fatal (_("TLS generation counter wrapped!  Please send report with the 'glibcbug' script."));
+
+      if (tls_free_end == GL(dl_tls_static_used))
+       GL(dl_tls_static_used) = tls_free_start;
+    }
 #endif
 
   /* Notify the debugger those objects are finalized and gone.  */
@@ -424,8 +457,7 @@ free_slotinfo (struct dtv_slotinfo_list *elemp)
 #endif
 
 
-static void
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0
       && GL(dl_main_searchlist)->r_nlist == GL(dl_initial_searchlist).r_nlist)
@@ -453,4 +485,3 @@ free_mem (void)
     GL(dl_tls_dtv_slotinfo_list)->next = NULL;
 #endif
 }
-text_set_element (__libc_subfreeres, free_mem);
index 938b5d7..d69e49f 100644 (file)
@@ -123,8 +123,7 @@ __libc_dlclose (void *__map)
 }
 
 
-static void
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   struct link_map *l;
   struct r_search_path_elem *d;
@@ -154,4 +153,3 @@ free_mem (void)
        }
     }
 }
-text_set_element (__libc_subfreeres, free_mem);
index f7dca02..8f92cba 100644 (file)
@@ -445,8 +445,7 @@ __gconv_release_cache (struct __gconv_step *steps, size_t nsteps)
 
 
 /* Free all resources if necessary.  */
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   if (cache_malloced)
     free (gconv_cache);
@@ -455,5 +454,3 @@ free_mem (void)
     __munmap (gconv_cache, cache_size);
 #endif
 }
-
-text_set_element (__libc_subfreeres, free_mem);
index 8c2f4b0..cd5055c 100644 (file)
@@ -597,11 +597,8 @@ __gconv_read_conf (void)
 
 
 /* Free all resources if necessary.  */
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   if (__gconv_path_elem != NULL && __gconv_path_elem != &empty_path_elem)
     free ((void *) __gconv_path_elem);
 }
-
-text_set_element (__libc_subfreeres, free_mem);
index 25b06d0..70c33df 100644 (file)
@@ -778,8 +778,7 @@ free_modules_db (struct gconv_module *node)
 
 
 /* Free all resources if necessary.  */
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   if (__gconv_alias_db != NULL)
     __tdestroy (__gconv_alias_db, free);
@@ -790,5 +789,3 @@ free_mem (void)
   if (known_derivations != NULL)
     __tdestroy (known_derivations, free_derivation);
 }
-
-text_set_element (__libc_subfreeres, free_mem);
index 990338f..ff90a54 100644 (file)
@@ -203,12 +203,10 @@ do_release_all (void *nodep)
   free (obj);
 }
 
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   __tdestroy (loaded, do_release_all);
 }
-text_set_element (__libc_subfreeres, free_mem);
 
 
 #ifdef DEBUG
index 42d39a1..80c71ef 100644 (file)
@@ -1124,8 +1124,7 @@ mempcpy (dest, src, n)
 #ifdef _LIBC
 /* If we want to free all resources we have to do some work at
    program's end.  */
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   void *old;
 
@@ -1155,6 +1154,4 @@ free_mem (void)
       free (old);
     }
 }
-
-text_set_element (__libc_subfreeres, free_mem);
 #endif
index e0e11f0..1031e4d 100644 (file)
@@ -168,8 +168,7 @@ _nl_find_domain (dirname, locale, domainname, domainbinding)
 
 
 #ifdef _LIBC
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   struct loaded_l10nfile *runp = _nl_loaded_domains;
 
@@ -183,6 +182,4 @@ free_mem (void)
       free (here);
     }
 }
-
-text_set_element (__libc_subfreeres, free_mem);
 #endif
index aa19dbd..dbb4d7a 100644 (file)
@@ -493,7 +493,7 @@ _nl_load_locale_from_archive (int category, const char **namep)
   return lia->data[category];
 }
 
-void
+void __libc_freeres_fn_section
 _nl_archive_subfreeres (void)
 {
   struct locale_in_archive *lia;
index 56a875e..50c7528 100644 (file)
@@ -463,8 +463,7 @@ free_category (int category,
     }
 }
 
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
 #ifdef NL_CURRENT_INDIRECT
   /* We don't use the loop because we want to have individual weak
@@ -494,4 +493,3 @@ free_mem (void)
      not called _nl_unload_locale on them above.  */
   _nl_archive_subfreeres ();
 }
-text_set_element (__libc_subfreeres, free_mem);
index 754ea13..b434203 100644 (file)
@@ -180,9 +180,7 @@ fstab_convert (struct fstab_state *state)
 
 /* Make sure the memory is freed if the programs ends while in
    memory-debugging mode and something actually was allocated.  */
-static void
-__attribute__ ((unused))
-fstab_free (void)
+libc_freeres_fn (fstab_free)
 {
   char *buffer;
 
@@ -190,5 +188,3 @@ fstab_free (void)
   if (buffer != NULL)
     free ((void *) buffer);
 }
-
-text_set_element (__libc_subfreeres, fstab_free);
index ca411b2..1b3bb23 100644 (file)
@@ -697,8 +697,7 @@ nss_new_service (name_database *database, const char *name)
 
 
 /* Free all resources if necessary.  */
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   name_database *top = service_table;
   name_database_entry *entry;
@@ -745,5 +744,3 @@ free_mem (void)
 
   free (top);
 }
-
-text_set_element (__libc_subfreeres, free_mem);
index 9bb06aa..1414780 100644 (file)
@@ -696,12 +696,10 @@ re_comp (s)
 }
 
 #ifdef _LIBC
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   __regfree (&re_comp_buf);
 }
-text_set_element (__libc_subfreeres, free_mem);
 #endif
 
 #endif /* _REGEX_RE_COMP */
index b89abf9..b3334f3 100644 (file)
@@ -410,9 +410,7 @@ handle_requests (void *arg)
 
 
 /* Free allocated resources.  */
-static void
-__attribute__ ((unused))
-free_res (void)
+libc_freeres_fn (free_res)
 {
   size_t row;
 
@@ -421,4 +419,3 @@ free_res (void)
 
   free (pool);
 }
-text_set_element (__libc_subfreeres, free_res);
index 660df1f..37c641c 100644 (file)
@@ -390,8 +390,7 @@ addseverity (int severity, const char *string)
 }
 
 
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   struct severity_info *runp = severity_list;
 
@@ -407,4 +406,3 @@ free_mem (void)
     else
       runp = runp->next;
 }
-text_set_element (__libc_subfreeres, free_mem);
index ad96e4a..4b34289 100644 (file)
@@ -413,9 +413,8 @@ auth_errmsg (enum auth_stat stat)
 }
 
 
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
+  /* Not libc_freeres_ptr, since buf is a macro.  */
   free (buf);
 }
-text_set_element (__libc_subfreeres, free_mem);
index e5799e5..e7fd492 100644 (file)
@@ -323,8 +323,7 @@ clearenv ()
   return 0;
 }
 #ifdef _LIBC
-static void
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   /* Remove all traces.  */
   clearenv ();
@@ -333,8 +332,6 @@ free_mem (void)
   __tdestroy (known_values, free);
   known_values = NULL;
 }
-text_set_element (__libc_subfreeres, free_mem);
-
 
 # undef setenv
 # undef unsetenv
index b0432e6..78cf764 100644 (file)
@@ -530,7 +530,7 @@ handle_fildes_io (void *arg)
                                                  aiocbp->aiocb64.aio_offset));
              else
                aiocbp->aiocb.__return_value =
-                 TEMP_FAILURE_RETRY (pwrite (fildes, (const void *)
+                 TEMP_FAILURE_RETRY (__libc_pwrite (fildes, (const void *)
                                              aiocbp->aiocb.aio_buf,
                                              aiocbp->aiocb.aio_nbytes,
                                              aiocbp->aiocb.aio_offset));
@@ -665,9 +665,7 @@ handle_fildes_io (void *arg)
 
 
 /* Free allocated resources.  */
-static void
-__attribute__ ((unused))
-free_res (void)
+libc_freeres_fn (free_res)
 {
   size_t row;
 
@@ -676,7 +674,6 @@ free_res (void)
 
   free (pool);
 }
-text_set_element (__libc_subfreeres, free_res);
 
 
 /* Add newrequest to the runlist. The __abs_prio flag of newrequest must
index a96df24..b118533 100644 (file)
@@ -226,14 +226,10 @@ shm_unlink (const char *name)
 }
 
 
-static void  __attribute__ ((unused))
-freeit (void)
+/* Make sure the table is freed if we want to free everything before
+   exiting.  */
+libc_freeres_fn (freeit)
 {
   if (mountpoint.dir != defaultdir)
     free (mountpoint.dir);
 }
-
-
-/* Make sure the table is freed if we want to free everything before
-   exiting.  */
-text_set_element (__libc_subfreeres, freeit);
index c9a9783..0294058 100644 (file)
@@ -624,8 +624,7 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
 }
 
 
-static void
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   while (tzstring_list != NULL)
     {
@@ -637,4 +636,3 @@ free_mem (void)
   free (old_tz);
   old_tz = NULL;
 }
-text_set_element (__libc_subfreeres, free_mem);