bfd: Make bfd_cache_max_open depend on actual open file limit.
authorMark Wielaard <mjw@redhat.com>
Mon, 27 May 2013 07:55:17 +0000 (07:55 +0000)
committerMark Wielaard <mjw@redhat.com>
Mon, 27 May 2013 07:55:17 +0000 (07:55 +0000)
The current hard coded limit of open files in bfd/cache.c is 10. This
is pretty low these days. Binaries are often linked against much more
than 10 files (and sometimes against more than 100 shared libraries).
When debugging with GDB some files are opened and closed multiple
times because of this low limit. If possible make the BFD cache file
limit depend on the actual open file limit of the process so more BFD
files can be open at the same time.

    * cache.c (BFD_CACHE_MAX_OPEN): Remove define.
    (max_open_files): New static int initialized to zero.
    (bfd_cache_max_open): New static function to set and return
    max_open_files.
    (bfd_cache_init): Use bfd_cache_max_open.
    (bfd_open_file): Likewise.
    * configure.in (AC_CHECK_HEADERS): Add sys/resource.h.
    (AC_CHECK_FUNCS): Add getrlimit.
    * configure: Regenerated.
    * config.in: Likewise.
    * sysdep.h: Check and include sys/resource.h for getrlimit.

bfd/ChangeLog
bfd/cache.c
bfd/config.in
bfd/configure
bfd/configure.in
bfd/sysdep.h

index d01e6875e0b979a8729fed64f3bb153226baf1ec..a29227e52e81bde2971c9d9984e7a3be92dbcc30 100644 (file)
@@ -1,3 +1,17 @@
+2013-05-26  Mark Wielaard  <mjw@redhat.com>
+
+       * cache.c (BFD_CACHE_MAX_OPEN): Remove define.
+       (max_open_files): New static int initialized to zero.
+       (bfd_cache_max_open): New static function to set and return
+       max_open_files.
+       (bfd_cache_init): Use bfd_cache_max_open.
+       (bfd_open_file): Likewise.
+       * configure.in (AC_CHECK_HEADERS): Add sys/resource.h.
+       (AC_CHECK_FUNCS): Add getrlimit.
+       * configure: Regenerated.
+       * config.in: Likewise.
+       * sysdep.h: Check and include sys/resource.h for getrlimit.
+
 2013-05-23  Alan Modra  <amodra@gmail.com>
 
        * format.c (bfd_check_format_matches): Don't match a target in
index 52268162c268ebf01486208b49e0a1b223d5e065..4d46936bcfdb622281aa2ec568b899cbdfbc7254 100644 (file)
@@ -31,7 +31,7 @@ SECTION
        regard to the underlying operating system's file descriptor
        limit (often as low as 20 open files).  The module in
        <<cache.c>> maintains a least recently used list of
-       <<BFD_CACHE_MAX_OPEN>> files, and exports the name
+       <<bfd_cache_max_open>> files, and exports the name
        <<bfd_cache_lookup>>, which runs around and makes sure that
        the required BFD is open. If not, then it chooses a file to
        close, closes it and opens the one wanted, returning its file
@@ -67,9 +67,35 @@ enum cache_flag {
 };
 
 /* The maximum number of files which the cache will keep open at
-   one time.  */
+   one time.  When needed call bfd_cache_max_open to initialize.  */
 
-#define BFD_CACHE_MAX_OPEN 10
+static int max_open_files = 0;
+
+/* Set max_open_files, if not already set, to 12.5% of the allowed open
+   file descriptors, but at least 10, and return the value.  */
+static int
+bfd_cache_max_open (void)
+{
+  if (max_open_files == 0)
+    {
+      int max;
+#ifdef HAVE_GETRLIMIT
+      struct rlimit rlim;
+      if (getrlimit (RLIMIT_NOFILE, &rlim) == 0
+         && rlim.rlim_cur != RLIM_INFINITY)
+       max = rlim.rlim_cur / 8;
+      else
+#endif /* HAVE_GETRLIMIT */
+#ifdef _SC_OPEN_MAX
+       max = sysconf (_SC_OPEN_MAX) / 8;
+#else
+       max = 10;
+#endif /* _SC_OPEN_MAX */
+      max_open_files = max < 10 ? 10 : max;
+    }
+
+  return max_open_files;
+}
 
 /* The number of BFD files we have open.  */
 
@@ -187,7 +213,7 @@ close_one (void)
 /* Called when the macro <<bfd_cache_lookup>> fails to find a
    quick answer.  Find a file descriptor for @var{abfd}.  If
    necessary, it open it.  If there are already more than
-   <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
+   <<bfd_cache_max_open>> files open, it tries to close one first, to
    avoid running out of file descriptors.  It will return NULL
    if it is unable to (re)open the @var{abfd}.  */
 
@@ -466,7 +492,7 @@ bfd_boolean
 bfd_cache_init (bfd *abfd)
 {
   BFD_ASSERT (abfd->iostream != NULL);
-  if (open_files >= BFD_CACHE_MAX_OPEN)
+  if (open_files >= bfd_cache_max_open ())
     {
       if (! close_one ())
        return FALSE;
@@ -553,7 +579,7 @@ bfd_open_file (bfd *abfd)
 {
   abfd->cacheable = TRUE;      /* Allow it to be closed later.  */
 
-  if (open_files >= BFD_CACHE_MAX_OPEN)
+  if (open_files >= bfd_cache_max_open ())
     {
       if (! close_one ())
        return NULL;
index 2fc4897ea9d2c31b866807178ec92224d8e0596c..65fb0441e4ceec3655d6877cf562dd0359e353e9 100644 (file)
 /* Define to 1 if you have the `getpagesize' function. */
 #undef HAVE_GETPAGESIZE
 
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
+
 /* Define to 1 if you have the `getuid' function. */
 #undef HAVE_GETUID
 
 /* Define to 1 if you have the <sys/procfs.h> header file. */
 #undef HAVE_SYS_PROCFS_H
 
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H
 
index 5fc08e4febbe384961e0f64349a7953fffce6bf7..090f981d56eefaf0d1950c6795d0198e7a9a6813 100755 (executable)
@@ -12908,7 +12908,7 @@ fi
 
 done
 
-for ac_header in fcntl.h sys/file.h sys/time.h sys/stat.h
+for ac_header in fcntl.h sys/file.h sys/time.h sys/stat.h sys/resource.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -13583,12 +13583,14 @@ _ACEOF
 fi
 done
 
-for ac_func in strtoull
+for ac_func in strtoull getrlimit
 do :
-  ac_fn_c_check_func "$LINENO" "strtoull" "ac_cv_func_strtoull"
-if test "x$ac_cv_func_strtoull" = x""yes; then :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
   cat >>confdefs.h <<_ACEOF
-#define HAVE_STRTOULL 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
 fi
index befcf27094340b1426580f4cbc5b7cd4fad62ee4..ff14270fd57b5812a829e9e871c3f0e1160b400d 100644 (file)
@@ -211,7 +211,7 @@ AC_SUBST(BFD_HOSTPTR_T)
 BFD_CC_FOR_BUILD
 
 AC_CHECK_HEADERS(alloca.h stddef.h string.h strings.h stdlib.h time.h unistd.h)
-AC_CHECK_HEADERS(fcntl.h sys/file.h sys/time.h sys/stat.h)
+AC_CHECK_HEADERS(fcntl.h sys/file.h sys/time.h sys/stat.h sys/resource.h)
 GCC_HEADER_STDINT(bfd_stdint.h)
 AC_HEADER_TIME
 AC_HEADER_DIRENT
@@ -220,7 +220,7 @@ AC_CHECK_HEADERS(windows.h dlfcn.h)
 
 ACX_HEADER_STRING
 AC_CHECK_FUNCS(fcntl getpagesize setitimer sysconf fdopen getuid getgid fileno)
-AC_CHECK_FUNCS(strtoull)
+AC_CHECK_FUNCS(strtoull getrlimit)
 
 AC_CHECK_DECLS(basename)
 AC_CHECK_DECLS(ftello)
index b4fed10441118cb9faf6f519b2ec8b950d930b11..d560e7670b635c2d8b2f3b4f7fc8e4c4c5a6d524 100644 (file)
@@ -79,6 +79,10 @@ extern char *strrchr ();
 #include <unistd.h>
 #endif
 
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
 #ifdef USE_BINARY_FOPEN
 #include "fopen-bin.h"
 #else