bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCHv2 1/4] utimecmp: drop dependency on xmalloc


From: Eric Blake
Subject: [PATCHv2 1/4] utimecmp: drop dependency on xmalloc
Date: Wed, 27 Apr 2011 17:03:51 -0600

utimecmp's only use of malloc was for a cache; we can always bypass
the cache in low memory, and thus avoid dragging in xalloc-die.

* lib/utimecmp.c (utimecmp): Work even if hash table cache fails
due to memory pressure.
* modules/utimecmp (Depends-on): Drop xalloc.

Signed-off-by: Eric Blake <address@hidden>
---

It's always a bit trickier proceeding after a failed malloc, but
I think I got it all.  A close review would be appreciated.

 ChangeLog        |    7 ++++++
 lib/utimecmp.c   |   58 ++++++++++++++++++++++++++++++++++++++---------------
 modules/utimecmp |    1 -
 3 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f20299f..138c169 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-04-27  Eric Blake  <address@hidden>
+
+       utimecmp: drop dependency on xmalloc
+       * lib/utimecmp.c (utimecmp): Work even if hash table cache fails
+       due to memory pressure.
+       * modules/utimecmp (Depends-on): Drop xalloc.
+
 2011-04-27  Bruno Haible  <address@hidden>

        mkstemps: Ensure declaration on MacOS X 10.5.
diff --git a/lib/utimecmp.c b/lib/utimecmp.c
index 356763f..c0f6713 100644
--- a/lib/utimecmp.c
+++ b/lib/utimecmp.c
@@ -33,7 +33,6 @@
 #include "stat-time.h"
 #include "utimens.h"
 #include "verify.h"
-#include "xalloc.h"

 #ifndef MAX
 # define MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -122,7 +121,9 @@ utimecmp (char const *dst_name,
   /* Things to watch out for:

      The code uses a static hash table internally and is not safe in the
-     presence of signals, multiple threads, etc.
+     presence of signals, multiple threads, etc.  However, memory pressure
+     that prevents use of the hash table is not fatal - we just fall back
+     to redoing the computations on every call in that case.

      int and long int might be 32 bits.  Many of the calculations store
      numbers up to 2 billion, and multiply by 10; they have to avoid
@@ -143,12 +144,13 @@ utimecmp (char const *dst_name,
     {
       /* Look up the time stamp resolution for the destination device.  */

-      /* Hash table for devices.  */
+      /* Hash table for caching information learned about devices.  */
       static Hash_table *ht;

       /* Information about the destination file system.  */
       static struct fs_res *new_dst_res;
-      struct fs_res *dst_res;
+      struct fs_res *dst_res = NULL;
+      struct fs_res tmp_dst_res;

       /* Time stamp resolution in nanoseconds.  */
       int res;
@@ -163,24 +165,46 @@ utimecmp (char const *dst_name,
       if (src_s <= dst_s - 2)
         return 1;

+      /* Try to do a hash lookup, but fall back to stack variables and
+         recomputation on low memory situations.  */
       if (! ht)
         ht = hash_initialize (16, NULL, dev_info_hash, dev_info_compare, free);
-      if (! new_dst_res)
+      if (ht)
         {
-          new_dst_res = xmalloc (sizeof *new_dst_res);
-          new_dst_res->resolution = 2 * BILLION;
-          new_dst_res->exact = false;
-        }
-      new_dst_res->dev = dst_stat->st_dev;
-      dst_res = hash_insert (ht, new_dst_res);
-      if (! dst_res)
-        xalloc_die ();
+          if (! new_dst_res)
+            {
+              new_dst_res = malloc (sizeof *new_dst_res);
+              if (!new_dst_res)
+                goto low_memory;
+              new_dst_res->resolution = 2 * BILLION;
+              new_dst_res->exact = false;
+            }
+          new_dst_res->dev = dst_stat->st_dev;
+          dst_res = hash_insert (ht, new_dst_res);
+          if (! dst_res)
+            goto low_memory;

-      if (dst_res == new_dst_res)
+          if (dst_res == new_dst_res)
+            {
+              /* NEW_DST_RES is now in use in the hash table, so allocate a
+                 new entry next time.  */
+              new_dst_res = NULL;
+            }
+        }
+      else
         {
-          /* NEW_DST_RES is now in use in the hash table, so allocate a
-             new entry next time.  */
-          new_dst_res = NULL;
+        low_memory:
+          if (ht)
+            {
+              tmp_dst_res.dev = dst_stat->st_dev;
+              dst_res = hash_lookup (ht, &tmp_dst_res);
+            }
+          if (!dst_res)
+            {
+              dst_res = &tmp_dst_res;
+              dst_res->resolution = 2 * BILLION;
+              dst_res->exact = false;
+            }
         }

       res = dst_res->resolution;
diff --git a/modules/utimecmp b/modules/utimecmp
index 7be906b..a3160c8 100644
--- a/modules/utimecmp
+++ b/modules/utimecmp
@@ -11,7 +11,6 @@ hash
 stat-time
 time
 utimens
-xalloc
 intprops
 lstat
 stdbool
-- 
1.7.4.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]