使用 MMAP 读取时 OS X 上的页面错误

发布于 2024-09-24 12:57:50 字数 1601 浏览 9 评论 0原文

我正在尝试使用 mmap 在 Mac OS X 上对文件系统 I/O 进行基准测试。

#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <math.h>

char c;

int main(int argc, char ** argv)
{
        if (argc != 2)
        {
                printf("no files\n");
                exit(1);
        }
        int fd = open(argv[1], O_RDONLY);
        fcntl(fd, F_NOCACHE, 1);
        int offset=0;
        int size=0x100000;
        int pagesize = getpagesize();
        struct stat stats;
        fstat(fd, &stats);
        int filesize = stats.st_size;
        printf("%d byte pages\n", pagesize);
        printf("file %s @ %d bytes\n", argv[1], filesize);
        while(offset < filesize)
        {
                if(offset + size > filesize)
                {
                        int pages = ceil((filesize-offset)/(double)pagesize);
                        size = pages*pagesize;
                }
                printf("mapping offset %x with size %x\n", offset, size);
                void * mem = mmap(0, size, PROT_READ, 0, fd, offset);
                if(mem == -1)
                        return 0;
                offset+=size;
                int i=0;
                for(; i<size; i+=pagesize)
                {
                        c = *((char *)mem+i);
                }

                munmap(mem, size);
        }
        return 0;
}

我的想法是,我将映射一个文件或其中的一部分,然后通过取消引用它来导致页面错误。我正在慢慢失去理智,因为这根本不起作用,而且我以前在 Linux 上做过类似的事情。

I am trying to benchmark file system I/O on Mac OS X using mmap.

#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <math.h>

char c;

int main(int argc, char ** argv)
{
        if (argc != 2)
        {
                printf("no files\n");
                exit(1);
        }
        int fd = open(argv[1], O_RDONLY);
        fcntl(fd, F_NOCACHE, 1);
        int offset=0;
        int size=0x100000;
        int pagesize = getpagesize();
        struct stat stats;
        fstat(fd, &stats);
        int filesize = stats.st_size;
        printf("%d byte pages\n", pagesize);
        printf("file %s @ %d bytes\n", argv[1], filesize);
        while(offset < filesize)
        {
                if(offset + size > filesize)
                {
                        int pages = ceil((filesize-offset)/(double)pagesize);
                        size = pages*pagesize;
                }
                printf("mapping offset %x with size %x\n", offset, size);
                void * mem = mmap(0, size, PROT_READ, 0, fd, offset);
                if(mem == -1)
                        return 0;
                offset+=size;
                int i=0;
                for(; i<size; i+=pagesize)
                {
                        c = *((char *)mem+i);
                }

                munmap(mem, size);
        }
        return 0;
}

The idea is that I'll map a file or portion of it and then cause a page fault by dereferencing it. I am slowly losing my sanity since this doesn't at all work and I've done similar things on Linux before.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无妨# 2024-10-01 12:57:50

将此行更改

void * mem = mmap(0, size, PROT_READ, 0, fd, offset);

void * mem = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, offset);

And,不要将 mem-1 进行比较。改用这个:

if(mem == MAP_FAILED) { ... }

它更具可读性,也更便携。

一般建议:如果您使用的 UNIX 平台与您习惯的平台不同,最好打开手册页。对于 OS X 上的 mmap,可以在 此处。它说

符合要求的应用程序必须指定 MAP_PRIVATE 或 MAP_SHARED。

因此,在第四个指定 0
在 OS X 中,参数可以。我相信
对于 BSD 来说通常都是如此。

Change this line

void * mem = mmap(0, size, PROT_READ, 0, fd, offset);

to

void * mem = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, offset);

And, don't compare mem with -1. Use this instead:

if(mem == MAP_FAILED) { ... }

It's both more readable and more portable.

General advice: if you're on a different UNIX platform from what you're used to, it's a good idea to open the man page. For mmap on OS X, it can be found here. It says

Conforming applications must specify either MAP_PRIVATE or MAP_SHARED.

So, specifying 0 on the fourth
argument is not OK in OS X. I believe
this is true for BSD in general.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文