From: Michael Schroeder Date: Tue, 17 Nov 2015 14:33:52 +0000 (+0100) Subject: Overshoot size for large memory chunks in solv_extend X-Git-Tag: 0.6.15~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8220fe1d69f96825a912df96d1a2212f5c61b85;p=thirdparty%2Flibsolv.git Overshoot size for large memory chunks in solv_extend 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. --- diff --git a/src/libsolv.ver b/src/libsolv.ver index 9e47117d..5d372aab 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -262,6 +262,7 @@ SOLV_1.0 { solv_depmarker; solv_dupappend; solv_dupjoin; + solv_extend_realloc; solv_free; solv_hex2bin; solv_latin1toutf8; diff --git a/src/util.c b/src/util.c index d8ae7cab..8be29351 100644 --- a/src/util.c +++ b/src/util.c @@ -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) { diff --git a/src/util.h b/src/util.h index d8a136d6..60dd49cc 100644 --- a/src/util.h +++ b/src/util.h @@ -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; }