aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2021-01-30 17:14:20 -0500
committerRich Felker <dalias@aerifal.cx>2021-01-30 17:14:20 -0500
commit2010df0d64570db4ce29cc7df0e31f81aa26ae4a (patch)
tree6eeebcbc7f665b45936d10b2d62e0c19e6765567
parent9afed99c224ab33578623744f40d31bee84ec6ba (diff)
downloadmusl-2010df0d64570db4ce29cc7df0e31f81aa26ae4a.zip
musl-2010df0d64570db4ce29cc7df0e31f81aa26ae4a.tar.gz
musl-2010df0d64570db4ce29cc7df0e31f81aa26ae4a.tar.bz2
preserve errno across free
as an outcome of Austin Group issue #385, future versions of the standard will require free not to alter the value of errno. save and restore it individually around the calls to madvise and munmap so that the cost is not imposed on calls to free that do not result in any syscall.
-rw-r--r--src/malloc/mallocng/free.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/malloc/mallocng/free.c b/src/malloc/mallocng/free.c
index 40745f9..418a085 100644
--- a/src/malloc/mallocng/free.c
+++ b/src/malloc/mallocng/free.c
@@ -119,7 +119,11 @@ void free(void *p)
if (((uintptr_t)(start-1) ^ (uintptr_t)end) >= 2*PGSZ && g->last_idx) {
unsigned char *base = start + (-(uintptr_t)start & (PGSZ-1));
size_t len = (end-base) & -PGSZ;
- if (len) madvise(base, len, MADV_FREE);
+ if (len) {
+ int e = errno;
+ madvise(base, len, MADV_FREE);
+ errno = e;
+ }
}
// atomic free without locking if this is neither first or last slot
@@ -139,5 +143,9 @@ void free(void *p)
wrlock();
struct mapinfo mi = nontrivial_free(g, idx);
unlock();
- if (mi.len) munmap(mi.base, mi.len);
+ if (mi.len) {
+ int e = errno;
+ munmap(mi.base, mi.len);
+ errno = e;
+ }
}