1.7.0 CVS mmap failure

Brian Ford Brian.Ford@FlightSafety.com
Wed Jan 17 19:43:00 GMT 2007


On Wed, 17 Jan 2007, Corinna Vinschen wrote:

> On Jan 16 17:28, Brian Ford wrote:
>
> > PS: In an strace of this, I see three fstat64s called from within a
> > single mmap64.  Do you know where they all are, and if two should be
> > optimized away?
>
> There's only one such call in list::set.

which is called from map::add_list, yes.  I also see one in
map::get_list_by_fd.

> Your observation is strange.  The first mapping, which really maps the
> file, calls fstat.  The second (valid remainder) and third (sigbus area)
> mapping are anonymous mappings, which don't call fstat.

I don't think my three fstat64s correspond to your three mappings.

> In my tests, fstat64 is called only once for a file mapping.

Really?  I think I see them as follows:

mmap.cc:1203 mmap64():
  map_list = mmapped_areas.get_list_by_fd (fd);
mmap.cc:982 mmap_worker():
  if (!(map_list = mmapped_areas.get_list_by_fd (fd))
mmap.cc:983 mmap_worker():
  && !(map_list = mmapped_areas.add_list (fd)))

Also:

mmap.cc:1134 mmap64():
  DWORD low = GetFileSize (fh->get_handle (), &high);

> STC?

It looks like your statement is true for the first mmap in a process, but
subsequent mmaps have significant overhead.  In the attached STC, I count
5 fstat64s of the same fd via strace, plus the GetFileSize mentioned
above.

PS. Since this isn't a bug, I don't expect you to do any more than
consider putting it in your long term low priority que or reply with a PTC
Thanks for the evaluation tuits ;-).

-- 
Brian Ford
Lead Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
the best safety device in any aircraft is a well-trained crew...

-------------- next part --------------
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>


int
main(int argc, const char *argv[])
{
    char         fname[PATH_MAX];
    int          cnt;
    int          fd;
    struct stat  sb;
    void        *addr;

    cnt        = readlink("/proc/self/exe", fname, sizeof(fname));
    fname[cnt] = '\0';

#define EXE_SUFFIX ".exe"
#define STRLEN_EXE_SUFFIX (sizeof(EXE_SUFFIX)-1)
    if (cnt <= STRLEN_EXE_SUFFIX
        || strcasecmp(&fname[cnt-STRLEN_EXE_SUFFIX], EXE_SUFFIX))
        strcpy(fname+cnt, EXE_SUFFIX);

    fd = open(fname, O_RDONLY);
    if (fd < 0)
    {
	perror("open self");
	return -1;
    }

    if (fstat(fd, &sb) < 0)
    {
	perror("stat");
	return -1;
    }

    addr = mmap(NULL, sb.st_size, (PROT_READ|PROT_WRITE),
		(MAP_NORESERVE|MAP_PRIVATE), fd, 0);
    if (addr == MAP_FAILED)
    {
	perror("mmap1");
	return -1;
    }

    addr = mmap(NULL, sb.st_size, (PROT_READ|PROT_WRITE),
		(MAP_NORESERVE|MAP_PRIVATE), fd, 0);
    if (addr == MAP_FAILED)
    {
	perror("mmap2");
	return -1;
    }

    close(fd);

    puts("test passed");
    return 0;
}
-------------- next part --------------
--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


More information about the Cygwin mailing list