This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PCH support on Solaris
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: Ulrich Weigand <weigand at immd1 dot informatik dot uni-erlangen dot de>
- Cc: bonzini at gnu dot org,geoffk at geoffk dot org,gcc-patches at gcc dot gnu dot org
- Date: Sat, 5 Apr 2003 10:14:32 +0200
- Subject: Re: PCH support on Solaris
- References: <200304042214.AAA22353@faui11.informatik.uni-erlangen.de>
> I don't think this is a performance issue, but a correctness issue.
Don't forget that we're only talking about heuristics, so it's fine if it
just works.
> However, if you do not use MAP_FIXED, the OS will treat the address
> parameter as merely a hint, which it is free to ignore completely
> -- and in fact this is what in my experience (at least some versions)
> of Solaris tend to do.
I've attached a little test program that exercices Paolo's solution:
- we first ask mmap for the preferred location by passing NULL,
- then we pass it this preferred location with a zero offset.
We do so for sizes up to 1GB.
Tested on Solaris/Sparc 2.5.1, 2.6, 2.7, 2.8, 2.9, all clear.
> So it is easily possible that this mmap will always succeed, but never
> return guess == mmi.preferred_base. Using MAP_FIXED subsequently with the
> address guess doesn't then buy you anything ...
Note that, in the patch I posted, I explicitly check that we have the
equality guess == mmi.preferred_base. And, according to the little test
program, this seems to be true:
- if mmi.preferred_base is the preferred address returned by mmap(NULL, ...)
- and the offset is zero.
> This is why I don't quite see what the benefit of this mmap is
> supposed to be.
We work around the dependency upon the offset, which seems to be a feature of
Solaris.
--
Eric Botcazou
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#ifdef MAP_ANON
# define USING_MAP_ANON
#else
# define USING_DEV_ZERO
#endif
void *get_preferred_address(size_t size)
{
void *addr;
int dev_zero_fd;
dev_zero_fd = open ("/dev/zero", O_RDWR);
if (dev_zero_fd == -1)
return (void *)-1;
addr = mmap (NULL, size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_NORESERVE,
dev_zero_fd, 0);
if (addr == MAP_FAILED)
return (void *)-1;
munmap (addr, size);
close (dev_zero_fd);
return addr;
}
void *get_effective_address(void *preferred, size_t size)
{
void *addr;
#ifdef USING_MAP_ANON
addr = mmap (preferred, size,
PROT_NONE,
MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
-1, 0);
#endif
#ifdef USING_DEV_ZERO
int dev_zero_fd;
dev_zero_fd = open ("/dev/zero", O_RDWR);
if (dev_zero_fd == -1)
return (void *)-1;
addr = mmap (preferred, size,
PROT_NONE,
MAP_PRIVATE | MAP_NORESERVE,
dev_zero_fd, 0);
#endif
if (addr == MAP_FAILED)
return (void *)-1;
munmap (addr, size);
#ifdef USING_DEV_ZERO
close (dev_zero_fd);
#endif
return addr;
}
int main(int argc, char *argv[])
{
int i, not_matching = 0;
void *preferred;
size_t size;
#ifdef USING_MAP_ANON
printf("Using MAP_ANON...\n");
#endif
#ifdef USING_DEV_ZERO
printf("Using /dev/zero...\n");
#endif
for (i=0; i <= 30; i++) {
size = 1 << i;
preferred = get_preferred_address (size);
if (preferred == (void *)-1) {
printf(" failed for %d\n", size);
continue;
}
if (get_effective_address (preferred, size) != preferred) {
printf(" not matching for %d\n", size);
not_matching = 1;
}
}
if (! not_matching)
printf(" all clear.\n");
return 0;
}