in pthread_getattr_np, use mremap rather than madvise to measure stack
authorRich Felker <dalias@aerifal.cx>
Wed, 31 Jul 2013 19:19:39 +0000 (15:19 -0400)
committerRich Felker <dalias@aerifal.cx>
Wed, 31 Jul 2013 19:19:39 +0000 (15:19 -0400)
the original motivation for this patch was that qemu (and possibly
other syscall emulators) nop out madvise, resulting in an infinite
loop. however, there is another benefit to this change: madvise may
actually undo an explicit madvise the application intended for its
stack, whereas the mremap operation is a true nop. the logic here is
that mremap must fail if it cannot resize the mapping in-place, and
the caller knows that it cannot resize in-place because it knows the
next page of virtual memory is already occupied.

src/thread/pthread_getattr_np.c

index 945242b7dd5bd37e1335dc27f0e2b3dd0fc5c77c..86df1defed80bb70780df4bda1fa920e8a7d09c3 100644 (file)
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE
 #include "pthread_impl.h"
 #include <sys/mman.h>
 
@@ -13,7 +14,7 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
                size_t l = PAGE_SIZE;
                p += -(uintptr_t)p & PAGE_SIZE-1;
                a->_a_stackaddr = (uintptr_t)p;
-               while (!posix_madvise(p-l-PAGE_SIZE, PAGE_SIZE, POSIX_MADV_NORMAL))
+               while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
                        l += PAGE_SIZE;
                a->_a_stacksize = l - DEFAULT_STACK_SIZE;
        }