diff options
author | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-12 04:54:42 +0000 |
---|---|---|
committer | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-12 04:54:42 +0000 |
commit | 901dfcc7f6e0550e46d865befe0f4da4ccc60988 (patch) | |
tree | 9381534d80452c32494066d2511c5ca33135ba29 /gcc/aclocal.m4 | |
parent | 3b853ab87d4a626bf5229082903fd2bb891f1ecf (diff) | |
download | gcc-901dfcc7f6e0550e46d865befe0f4da4ccc60988.tar.gz |
2001-01-11 Zack Weinberg <zack@wolery.stanford.edu>
* aclocal.m4 (AC_FUNC_MMAP_ANYWHERE): Completely rewritten.
Now defines HAVE_MMAP_DEV_ZERO and/or HAVE_MMAP_ANON depending
which you have.
(AC_FUNC_MMAP_FILE): Don't AC_REQUIRE AC_FUNC_MMAP_ANYWHERE.
* configure.in: Set GGC to ggc-page if any of mmap_dev_zero,
mmap_anon, and valloc is available.
* ggc-page.c: Restructure ifdef logic to match new autoconf
spec. Don't throw away the test page in init_ggc.
* configure, config.in: Regenerate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38934 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/aclocal.m4')
-rw-r--r-- | gcc/aclocal.m4 | 266 |
1 files changed, 234 insertions, 32 deletions
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 index c3e1d576be8..4544c778503 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -737,16 +737,17 @@ AC_SUBST($1)dnl # Check whether mmap can map an arbitrary page from /dev/zero or with # MAP_ANONYMOUS, without MAP_FIXED. AC_DEFUN([AC_FUNC_MMAP_ANYWHERE], -[AC_CHECK_HEADERS(unistd.h) -AC_CHECK_FUNCS(getpagesize) -AC_CACHE_CHECK(for working mmap which provides zeroed pages anywhere, - ac_cv_func_mmap_anywhere, -[AC_TRY_RUN([ -/* Test by Richard Henderson and Alexandre Oliva. - Check whether mmap MAP_ANONYMOUS or mmap from /dev/zero works. */ +[AC_CHECK_FUNCS(getpagesize) +# The test program for the next two tests is the same except for one +# set of ifdefs. +changequote({{{,}}})dnl +{{{cat >ct-mmap.inc <<'EOF' #include <sys/types.h> -#include <fcntl.h> #include <sys/mman.h> +#include <fcntl.h> +#include <signal.h> +#include <setjmp.h> +#include <stdio.h> #if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) # define MAP_ANONYMOUS MAP_ANON @@ -793,45 +794,246 @@ AC_CACHE_CHECK(for working mmap which provides zeroed pages anywhere, #endif /* no HAVE_GETPAGESIZE */ -int main() -{ - char *x; - int fd, pg; - -#ifndef MAP_ANONYMOUS - fd = open("/dev/zero", O_RDWR); - if (fd < 0) - exit(1); +#ifndef MAP_FAILED +# define MAP_FAILED -1 #endif - pg = getpagesize(); -#ifdef MAP_ANONYMOUS - x = (char*)mmap(0, pg, PROT_READ|PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +#undef perror_exit +#define perror_exit(str, val) \ + do { perror(str); exit(val); } while (0) + +/* Some versions of cygwin mmap require that munmap is called with the + same parameters as mmap. GCC expects that this is not the case. + Test for various forms of this problem. Warning - icky signal games. */ + +static sigset_t unblock_sigsegv; +static jmp_buf r; +static size_t pg; +static int devzero; + +static char * +anonmap (size) + size_t size; +{ +#ifdef USE_MAP_ANON + return (char *) mmap (0, size, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); #else - x = (char*)mmap(0, pg, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + return (char *) mmap (0, size, PROT_READ|PROT_WRITE, + MAP_PRIVATE, devzero, 0); #endif - if (x == (char *) -1) - exit(2); +} + +static void +sigsegv (unused) + int unused; +{ + sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0); + longjmp (r, 1); +} + +/* Basic functionality test. */ +void +test_0 () +{ + char *x = anonmap (pg); + if (x == (char *) MAP_FAILED) + perror_exit("test 0 mmap", 2); *(int *)x += 1; if (munmap(x, pg) < 0) - exit(3); + perror_exit("test 0 munmap", 3); +} + +/* 1. If we map a 2-page region and unmap its second page, the first page + must remain. */ +static void +test_1 () +{ + char *x = anonmap (pg * 2); + if (x == (char *)MAP_FAILED) + perror_exit ("test 1 mmap", 4); + + signal (SIGSEGV, sigsegv); + if (setjmp (r)) + perror_exit ("test 1 fault", 5); + + x[0] = 1; + x[pg] = 1; + + if (munmap (x + pg, pg) < 0) + perror_exit ("test 1 munmap 1", 6); + x[0] = 2; + + if (setjmp (r) == 0) + { + x[pg] = 1; + perror_exit ("test 1 no fault", 7); + } + if (munmap (x, pg) < 0) + perror_exit ("test 1 munmap 2", 8); +} + +/* 2. If we map a 2-page region and unmap its first page, the second + page must remain. */ +static void +test_2 () +{ + char *x = anonmap (pg * 2); + if (x == (char *)MAP_FAILED) + perror_exit ("test 2 mmap", 9); + + signal (SIGSEGV, sigsegv); + if (setjmp (r)) + perror_exit ("test 2 fault", 10); + + x[0] = 1; + x[pg] = 1; + + if (munmap (x, pg) < 0) + perror_exit ("test 2 munmap 1", 11); + + x[pg] = 2; + + if (setjmp (r) == 0) + { + x[0] = 1; + perror_exit ("test 2 no fault", 12); + } + + if (munmap (x+pg, pg) < 0) + perror_exit ("test 2 munmap 2", 13); +} + +/* 3. If we map two adjacent 1-page regions and unmap them both with + one munmap, both must go away. + + Getting two adjacent 1-page regions with two mmap calls is slightly + tricky. All OS's tested skip over already-allocated blocks; therefore + we have been careful to unmap all allocated regions in previous tests. + HP/UX allocates pages backward in memory. No OS has yet been observed + to be so perverse as to leave unmapped space between consecutive calls + to mmap. */ + +static void +test_3 () +{ + char *x, *y, *z; + + x = anonmap (pg); + if (x == (char *)MAP_FAILED) + perror_exit ("test 3 mmap 1", 14); + y = anonmap (pg); + if (y == (char *)MAP_FAILED) + perror_exit ("test 3 mmap 2", 15); + + if (y != x + pg) + { + if (y == x - pg) + z = y, y = x, x = z; + else + { + fprintf (stderr, "test 3 nonconsecutive pages - %lx, %lx\n", + (unsigned long)x, (unsigned long)y); + exit (16); + } + } + + signal (SIGSEGV, sigsegv); + if (setjmp (r)) + perror_exit ("test 3 fault", 17); + + x[0] = 1; + y[0] = 1; + + if (munmap (x, pg*2) < 0) + perror_exit ("test 3 munmap", 18); + + if (setjmp (r) == 0) + { + x[0] = 1; + perror_exit ("test 3 no fault 1", 19); + } + + signal (SIGSEGV, sigsegv); + if (setjmp (r) == 0) + { + y[0] = 1; + perror_exit ("test 3 no fault 2", 20); + } +} + +int +main () +{ + sigemptyset (&unblock_sigsegv); + sigaddset (&unblock_sigsegv, SIGSEGV); + pg = getpagesize (); +#ifndef USE_MAP_ANON + devzero = open ("/dev/zero", O_RDWR); + if (devzero < 0) + perror_exit ("open /dev/zero", 1); +#endif + + test_0(); + test_1(); + test_2(); + test_3(); exit(0); -}], ac_cv_func_mmap_anywhere=yes, ac_cv_func_mmap_anywhere=no, -ac_cv_func_mmap_anywhere=no)]) -if test $ac_cv_func_mmap_anywhere = yes; then - AC_DEFINE(HAVE_MMAP_ANYWHERE, 1, - [Define if mmap can get us zeroed pages without MAP_FIXED.]) +} +EOF}}} +changequote([,])dnl + +AC_CACHE_CHECK(for working mmap from /dev/zero, + ac_cv_func_mmap_dev_zero, +[AC_TRY_RUN( + [#include "ct-mmap.inc"], + ac_cv_func_mmap_dev_zero=yes, + [if test $? -lt 4 + then ac_cv_func_mmap_dev_zero=no + else ac_cv_func_mmap_dev_zero=buggy + fi], + # If this is not cygwin, and /dev/zero is a character device, it's probably + # safe to assume it works. + [case "$host_os" in + cygwin* | win32 | pe | mingw* ) ac_cv_func_mmap_dev_zero=buggy ;; + * ) if test -c /dev/zero + then ac_cv_func_mmap_dev_zero=yes + else ac_cv_func_mmap_dev_zero=no + fi ;; + esac]) +]) +if test $ac_cv_func_mmap_dev_zero = yes; then + AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1, + [Define if mmap can get us zeroed pages from /dev/zero.]) +fi + +AC_CACHE_CHECK([for working mmap with MAP_ANON(YMOUS)], + ac_cv_func_mmap_anon, +[AC_TRY_RUN( + [#define USE_MAP_ANON +#include "ct-mmap.inc"], + ac_cv_func_mmap_anon=yes, + [if test $? -lt 4 + then ac_cv_func_mmap_anon=no + else ac_cv_func_mmap_anon=buggy + fi], + # Unlike /dev/zero, it is not safe to assume MAP_ANON(YMOUS) works + # just because it's there. Some SCO Un*xen define it but don't implement it. + ac_cv_func_mmap_anon=no) +]) +if test $ac_cv_func_mmap_anon = yes; then + AC_DEFINE(HAVE_MMAP_ANON, 1, + [Define if mmap can get us zeroed pages using MAP_ANON(YMOUS).]) fi +rm -f ct-mmap.inc ]) # Check whether mmap can map a plain file, without MAP_FIXED. AC_DEFUN([AC_FUNC_MMAP_FILE], -[AC_REQUIRE([AC_FUNC_MMAP_ANYWHERE])dnl -AC_CACHE_CHECK(for working mmap of a file, ac_cv_func_mmap_file, +[AC_CACHE_CHECK(for working mmap of a file, ac_cv_func_mmap_file, [# Create a file one thousand bytes long. for i in 1 2 3 4 5 6 7 8 9 0 do for j in 1 2 3 4 5 6 7 8 9 0 |