Speeding up wineserver syncronization objects with shared memory

David Howells dhowells at cambridge.redhat.com
Thu Mar 8 02:15:24 CST 2001


> Page alignment is needed for the address in memory, not for the offset
> inside the file on disk; since section virtual addresses in PE files
> are always page-aligned the memory address is never a problem. The
> only problem comes from the alignment of the data inside the PE file,
> and this is where we only need block-size alignment to make mmap
> possible.

Not so... The file offset must also be page aligned!

Try the following program:

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/mman.h>

    int main(int argc, char **argv)
    {
    	void *addr;
    	int fd;

    	fd = open("/bin/sh",O_RDONLY);
    	if (fd<0) { perror("mmap"); return 1; }

    	addr = mmap(NULL,512,PROT_READ,MAP_PRIVATE,fd,argc==1?512:4096);
    	if (addr==MAP_FAILED) { perror("mmap"); return 1; }

    	return 0;
    }

If you don't run it with an argument, it fails (Invalid Argument), and if you
do give it an argument, it works.

If you look at the kernel:

    [arch/i386/kernel/sys_i386.c]
    asmlinkage int old_mmap(struct mmap_arg_struct *arg)
    {
    	struct mmap_arg_struct a;
    	int err = -EFAULT;

    	if (copy_from_user(&a, arg, sizeof(a)))
    		goto out;

    	err = -EINVAL;
    	if (a.offset & ~PAGE_MASK)
    		goto out;

    	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
    out:
    	return err;
    }

Note that "a.offset" (the file offset) is checked for page alignment. Note
also that the internal kernel routine do_mmap2() deals with the offset in
terms of pages, not bytes.

David




More information about the wine-devel mailing list