]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Overshoot size for large memory chunks in solv_extend
authorMichael Schroeder <mls@suse.de>
Tue, 17 Nov 2015 14:33:52 +0000 (15:33 +0100)
committerMichael Schroeder <mls@suse.de>
Tue, 17 Nov 2015 14:33:52 +0000 (15:33 +0100)
We now dynamically round up the size to some ppower of two. This
brings down the number of mremap calls fro 96163 to 675 when
converting Fedora22's Everything repo, which makes no real difference
on my system but seems to help a lot if this is done in a Xen
guest. See libsolv issue#111 on github.

src/libsolv.ver
src/util.c
src/util.h

index 9e47117d1b9ab884e1c19a1fd9dddbb5f39d1486..5d372aab80597ca2e0827c862daebae6a14ff80d 100644 (file)
@@ -262,6 +262,7 @@ SOLV_1.0 {
                solv_depmarker;
                solv_dupappend;
                solv_dupjoin;
+               solv_extend_realloc;
                solv_free;
                solv_hex2bin;
                solv_latin1toutf8;
index d8ae7cab7b4f3776862baf1d751591609565b3a9..8be293519c66d056344e5d4e0434aa5882da0bb8 100644 (file)
@@ -76,6 +76,29 @@ solv_calloc(size_t num, size_t len)
   return r;
 }
 
+/* this was solv_realloc2(old, len, size), but we now overshoot
+ * for huge len sizes */
+void *
+solv_extend_realloc(void *old, size_t len, size_t size, size_t block)
+{
+  size_t xblock = (block + 1) << 5;
+  if (len >= xblock && xblock)
+    {
+      xblock <<= 1;
+      while (len >= xblock && xblock)
+       xblock <<= 1;
+      if (xblock)
+       {
+         size_t nlen;
+          xblock = (xblock >> 5) - 1;
+         nlen = (len + xblock) & ~xblock;
+         if (nlen > len)
+           len = nlen;
+       }
+    }
+  return solv_realloc2(old, len, size);
+}
+
 void *
 solv_free(void *mem)
 {
index d8a136d62bc4c1239d6c961c930be1f3fb97e96f..60dd49cc74b80e7bda3095b4dbe3ee20d6895f09 100644 (file)
@@ -29,6 +29,7 @@ extern void *solv_malloc2(size_t, size_t);
 extern void *solv_calloc(size_t, size_t);
 extern void *solv_realloc(void *, size_t);
 extern void *solv_realloc2(void *, size_t, size_t);
+extern void *solv_extend_realloc(void *, size_t, size_t, size_t);
 extern void *solv_free(void *);
 extern char *solv_strdup(const char *);
 extern void solv_oom(size_t, size_t);
@@ -48,12 +49,12 @@ static inline void *solv_extend(void *buf, size_t len, size_t nmemb, size_t size
   if (nmemb == 1)
     {
       if ((len & block) == 0)
-       buf = solv_realloc2(buf, len + (1 + block), size);
+       buf = solv_extend_realloc(buf, len + (1 + block), size, block);
     }
   else
     {
       if (((len - 1) | block) != ((len + nmemb - 1) | block))
-       buf = solv_realloc2(buf, (len + (nmemb + block)) & ~block, size);
+       buf = solv_extend_realloc(buf, (len + (nmemb + block)) & ~block, size, block);
     }
   return buf;
 }
@@ -76,7 +77,7 @@ static inline void *solv_zextend(void *buf, size_t len, size_t nmemb, size_t siz
 static inline void *solv_extend_resize(void *buf, size_t len, size_t size, size_t block)
 {
   if (len)
-    buf = solv_realloc2(buf, (len + block) & ~block, size);
+    buf = solv_extend_realloc(buf, (len + block) & ~block, size, block);
   return buf;
 }
 
@@ -85,7 +86,7 @@ static inline void *solv_calloc_block(size_t len, size_t size, size_t block)
   void *buf;
   if (!len)
     return 0;
-  buf = solv_malloc2((len + block) & ~block, size);
+  buf = solv_extend_realloc((void *)0, (len + block) & ~block, size, block);
   memset(buf, 0, ((len + block) & ~block) * size);
   return buf;
 }