This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PCH support on Solaris


> 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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]