diff options
author | Rich Felker <dalias@aerifal.cx> | 2021-01-30 17:14:20 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2021-01-30 17:14:20 -0500 |
commit | 2010df0d64570db4ce29cc7df0e31f81aa26ae4a (patch) | |
tree | 6eeebcbc7f665b45936d10b2d62e0c19e6765567 | |
parent | 9afed99c224ab33578623744f40d31bee84ec6ba (diff) | |
download | musl-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.c | 12 |
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; + } } |